diff options
| -rw-r--r-- | challenge-123/cheok-yin-fung/perl/ch-2.pl | 86 | ||||
| -rw-r--r-- | challenge-123/cheok-yin-fung/perl/ch-2a.pl | 59 | ||||
| -rw-r--r-- | challenge-123/cheok-yin-fung/perl/ch-2ax.pl | 86 |
3 files changed, 154 insertions, 77 deletions
diff --git a/challenge-123/cheok-yin-fung/perl/ch-2.pl b/challenge-123/cheok-yin-fung/perl/ch-2.pl index ed7142b2b9..7421f86fc7 100644 --- a/challenge-123/cheok-yin-fung/perl/ch-2.pl +++ b/challenge-123/cheok-yin-fung/perl/ch-2.pl @@ -8,7 +8,7 @@ use strict; use warnings; use v5.10.0; -use Test::More tests => 11; +use Test::More tests => 13; my $D = $ARGV[0] || 2; @@ -25,19 +25,24 @@ sub is_square { my $v0 = vec_subtract($p0, $p1); my $v1 = vec_subtract($p0, $p2); my $v2 = vec_subtract($p0, $p3); - # "cross product test"; - return 0 unless (vec_prod($v1, $v2) == 0) xor - (vec_prod($v0, $v2) == 0) xor - (vec_prod($v0, $v1) == 0); + # "dot product test"; + # return 0 unless (vec_prod_f($v1, $v2) == 0) xor + # (vec_prod_f($v0, $v2) == 0) xor + # (vec_prod_f($v0, $v1) == 0); my @n_vector = map { norm($_) } ($v0, $v1, $v2); @n_vector = sort {$a<=>$b} @n_vector; # "norm test" #if ( $n_vector[0] == $n_vector[1] ) { # the above conditional is fit for integter coordinates -# the below is special arrangement starting from the 7th test case +# the below is special arrangement starting from the 5th test case # or floating point number in general if ( sprintf("%f",$n_vector[0]) == sprintf("%f", $n_vector[1]) - && 2*sprintf("%f", $n_vector[0]) == sprintf("%f", $n_vector[2]) + && 2*sprintf("%f", $n_vector[0]) == sprintf("%f", $n_vector[2]) +# the above line concerning length of diagonal is sqrt(2) +# times the edge length would not be a necessary check +# if we preserve the dot product test, because in +# Euclidean space, if two vectors are orthogonal and in equal length, +# we can apply the Pythagorean theorem. ) { return 1; } @@ -53,6 +58,10 @@ sub vec_prod { return $sum; } +sub vec_prod_f { + return sprintf("%f", vec_prod($_[0], $_[1])); +} + sub norm { my $p = $_[0]; my $sum = 0; @@ -108,33 +117,66 @@ ok is_square( [5/sqrt(26), 1/sqrt(26)], "inclined by arctan(1/5), centre at origin"; ok is_square( - [cos(atan2(1,5)), sin(atan2(1,5))], [-sin(atan2(1,5)), cos(atan2(1,5))], - [-cos(atan2(1,5)), -sin(atan2(1,5))],[sin(atan2(1,5)), -cos(atan2(1,5))] + [cos(atan2(1,5)), sin(atan2(1,5))], + [-sin(atan2(1,5)), cos(atan2(1,5))], + [-cos(atan2(1,5)), -sin(atan2(1,5))], + [sin(atan2(1,5)), -cos(atan2(1,5))] ) == 1, "arctan(1/5) by atan2(), caught by the equalities"; ok is_square( - [2.7*cos(atan2(1,5)), 2.7*sin(atan2(1,5))], [-2.7*sin(atan2(1,5)), 2.7*cos(atan2(1,5))], - [-2.7*cos(atan2(1,5)), -2.7*sin(atan2(1,5))],[2.7*sin(atan2(1,5)), -2.7*cos(atan2(1,5))] + [2.7*cos(atan2(1,5)), 2.7*sin(atan2(1,5))], + [-2.7*sin(atan2(1,5)), 2.7*cos(atan2(1,5))], + [-2.7*cos(atan2(1,5)), -2.7*sin(atan2(1,5))], + [2.7*sin(atan2(1,5)), -2.7*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 2.7), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 2.7), " + ."caught by the equalities"; ok is_square( - [2.8*cos(atan2(1,5)), 2.8*sin(atan2(1,5))], [-2.8*sin(atan2(1,5)), 2.8*cos(atan2(1,5))], - [-2.8*cos(atan2(1,5)), -2.8*sin(atan2(1,5))],[2.8*sin(atan2(1,5)), -2.8*cos(atan2(1,5))] + [2.8*cos(atan2(1,5)), 2.8*sin(atan2(1,5))], + [-2.8*sin(atan2(1,5)), 2.8*cos(atan2(1,5))], + [-2.8*cos(atan2(1,5)), -2.8*sin(atan2(1,5))], + [2.8*sin(atan2(1,5)), -2.8*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 2.8), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 2.8), " + ."caught by the equalities"; ok is_square( - [4.0*cos(atan2(1,5)), 4.0*sin(atan2(1,5))], [-4.0*sin(atan2(1,5)), 4.0*cos(atan2(1,5))], - [-4.0*cos(atan2(1,5)), -4.0*sin(atan2(1,5))],[4.0*sin(atan2(1,5)), -4.0*cos(atan2(1,5))] + [4.0*cos(atan2(1,5)), 4.0*sin(atan2(1,5))], + [-4.0*sin(atan2(1,5)), 4.0*cos(atan2(1,5))], + [-4.0*cos(atan2(1,5)), -4.0*sin(atan2(1,5))], + [4.0*sin(atan2(1,5)), -4.0*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 4.0), caught by the equalities"; - + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 4.0)" + .", caught by the equalities"; ok is_square( - [0.0009*cos(atan2(1,5)), 0.0009*sin(atan2(1,5))], [-0.0009*sin(atan2(1,5)), 0.0009*cos(atan2(1,5))], - [-0.0009*cos(atan2(1,5)), -0.0009*sin(atan2(1,5))],[0.0009*sin(atan2(1,5)), -0.0009*cos(atan2(1,5))] + [0.0009*cos(atan2(1,5)), 0.0009*sin(atan2(1,5))], + [-0.0009*sin(atan2(1,5)), 0.0009*cos(atan2(1,5))], + [-0.0009*cos(atan2(1,5)), -0.0009*sin(atan2(1,5))], + [0.0009*sin(atan2(1,5)), -0.0009*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of a much smaller size (multiple by 0.0009), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of a much smaller size" + ." (multiple by 0.0009), caught by the equalities" + ." (expected fail)"; +; + +ok is_square( + [-2, 2*sqrt(3), -2*sqrt(3)-1 ], + [-2, 4+2*sqrt(3), -1+2*sqrt(3) ], + [ 6, 2*sqrt(3), -2*sqrt(3)-1], + [ 6, 4+2*sqrt(3), -1+2*sqrt(3)] + ); + +ok is_square( + [ 6, -2*sqrt(3), 3-2*sqrt(3)], + [-2, -2*sqrt(3), 3-2*sqrt(3)], + [-2, 4-2*sqrt(3), 3+2*sqrt(3)], + [ 6, 4-2*sqrt(3), 3+2*sqrt(3)], + ); done_testing(); diff --git a/challenge-123/cheok-yin-fung/perl/ch-2a.pl b/challenge-123/cheok-yin-fung/perl/ch-2a.pl index 533bebf029..a7ea05eea8 100644 --- a/challenge-123/cheok-yin-fung/perl/ch-2a.pl +++ b/challenge-123/cheok-yin-fung/perl/ch-2a.pl @@ -1,10 +1,12 @@ #!/usr/bin/perl # The Weekly Challenge 123 # Task 2 extension: Square/Cube/Hypercube Points -# Usage: ch-2a.pl (optional $k) (optional)$D +# Usage: $ ch-2a.pl (optional) $k (optional)$D # $k: 2 or 3 or 4, stands for square or cube or hypercube, default is 3 # $D: 2 or above, cannot be smaller than $k, default is same as $k +# Note: check out $ diff ch-2a.pl ch-2ax.pl + use strict; use warnings; use v5.10.0; @@ -26,12 +28,18 @@ sub is_square { my $v0 = vec_subtract($p0, $p1); my $v1 = vec_subtract($p0, $p2); my $v2 = vec_subtract($p0, $p3); - return 0 unless (vec_prod($v1, $v2) == 0) xor - (vec_prod($v0, $v2) == 0) xor - (vec_prod($v0, $v1) == 0); + return 0 unless (vec_prod_f($v1, $v2) == 0) xor + (vec_prod_f($v0, $v2) == 0) xor + (vec_prod_f($v0, $v1) == 0); +#========== BEGIN: diff of ch-2a.pl and ch-2ax.pl ========= return 0 unless vec_same($v0, vec_sum($v1, $v2) ) xor vec_same($v1, vec_sum($v2, $v0) ) xor vec_same($v2, vec_sum($v0, $v1) ); +#=========== END: diff of ch-2a.pl and ch-2ax.pl ========== +# COMMENT: +# this test is mathematically NOT necessary, +# and if you check it against ch-2ax.pl, +# you will find this section is the source of failed tests! my @n_vector = map { norm_f($_) } ($v0, $v1, $v2); @n_vector = sort {$a<=>$b} @n_vector; if ( $n_vector[0] == $n_vector[1] ) { @@ -46,11 +54,11 @@ sub is_cube { my @p = @_; my %v; $v{$_} = vec_subtract($p[0], $p[$_]) for (1..7); - my @ind = sort { norm($v{$a}) <=> norm($v{$b}) } keys %v; + my @ind = sort { norm_f($v{$a}) <=> norm_f($v{$b}) } keys %v; my ($N, $W, $U) = ($v{$ind[0]} , $v{$ind[1]} , $v{$ind[2]}) ; return 0 unless norm_f($N) == norm_f($W) && norm_f($N) == norm_f($U); - return 0 unless vec_prod($N,$W) == 0 && vec_prod($W,$U) == 0 - && vec_prod($U,$N) == 0; + return 0 unless vec_prod_f($N,$W) == 0 && vec_prod_f($W,$U) == 0 + && vec_prod_f($U,$N) == 0; my $NW = vec_sum($N, $W); my $WU = vec_sum($W, $U); my $UN = vec_sum($U, $N); @@ -93,19 +101,19 @@ sub is_hypercube { my @p = @_; my %v; $v{$_} = vec_subtract($p[0], $p[$_]) for (1..15); - my @ind = sort { norm($v{$a}) <=> norm($v{$b}) } keys %v; + my @ind = sort { norm_f($v{$a}) <=> norm_f($v{$b}) } keys %v; my ($N, $W, $U, $A) = ( $v{$ind[0]}, $v{$ind[1]} , $v{$ind[2]}, $v{$ind[3]} ); return 0 unless norm_f($N) == norm_f($W) && norm_f($W) == norm_f($U) && norm_f($U) == norm_f($A); return 0 unless - vec_prod($N, $W) == 0 && - vec_prod($N, $U) == 0 && - vec_prod($N, $A) == 0 && - vec_prod($A, $W) == 0 && - vec_prod($A, $U) == 0 && - vec_prod($W, $U) == 0 ; + vec_prod_f($N, $W) == 0 && + vec_prod_f($N, $U) == 0 && + vec_prod_f($N, $A) == 0 && + vec_prod_f($A, $W) == 0 && + vec_prod_f($A, $U) == 0 && + vec_prod_f($W, $U) == 0 ; my $AU = vec_sum($A, $U); my $AW = vec_sum($A, $W); @@ -159,6 +167,10 @@ sub vec_prod { return $sum; } +sub vec_prod_f { + return sprintf("%f", vec_prod($_[0], $_[1])); +} + sub norm { my $p = $_[0]; my $sum = 0; @@ -204,7 +216,7 @@ sub vec_subtract { -# 4 tests +# 9 tests ok is_square( [1,0], [0,1], [-1,0],[0,-1]) == 1, "on x-axis and y-axis"; ok is_square( [5/sqrt(26), 1/sqrt(26)], @@ -227,7 +239,9 @@ ok is_square( [-2.7*cos(atan2(1,5)), -2.7*sin(atan2(1,5))], [2.7*sin(atan2(1,5)), -2.7*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 2.7), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 2.7)," + ."caught by the equalities"; ok is_square( [2.8*cos(atan2(1,5)), 2.8*sin(atan2(1,5))], @@ -235,7 +249,9 @@ ok is_square( [-2.8*cos(atan2(1,5)), -2.8*sin(atan2(1,5))], [2.8*sin(atan2(1,5)), -2.8*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 2.8), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 2.8)," + ."caught by the equalities"; ok is_square( [4.0*cos(atan2(1,5)), 4.0*sin(atan2(1,5))], @@ -243,7 +259,9 @@ ok is_square( [-4.0*cos(atan2(1,5)), -4.0*sin(atan2(1,5))], [4.0*sin(atan2(1,5)), -4.0*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 4.0), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 4.0)," + ." caught by the equalities"; ok is_square( [0.0009*cos(atan2(1,5)), 0.0009*sin(atan2(1,5))], @@ -251,7 +269,10 @@ ok is_square( [-0.0009*cos(atan2(1,5)), -0.0009*sin(atan2(1,5))], [0.0009*sin(atan2(1,5)), -0.0009*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of a much smaller size (multiple by 0.0009), caught by the equalities (_\"not ok\" is normal_)"; + == 1, + "arctan(1/5) by atan2() of a much smaller size" + ."(multiple by 0.0009), caught by the equalities" + ."(_\"not ok\" is normal_)"; ok is_square( [1, 2] , [4,3], [3,1], [2,4] ) == 1, "Knight's square"; ok is_square( [1, 1] , [-1, 1], [1,-1], [-1,-1] ) == 1, "centre at origin"; diff --git a/challenge-123/cheok-yin-fung/perl/ch-2ax.pl b/challenge-123/cheok-yin-fung/perl/ch-2ax.pl index ac3ba42cce..cc5521e311 100644 --- a/challenge-123/cheok-yin-fung/perl/ch-2ax.pl +++ b/challenge-123/cheok-yin-fung/perl/ch-2ax.pl @@ -1,16 +1,17 @@ #!/usr/bin/perl # The Weekly Challenge 123 # Task 2 extension: Square/Cube/Hypercube Points -# Usage: ch-2a.pl (optional $k) (optional)$D +# Usage: ch-2ax.pl (optional) $k (optional)$D # $k: 2 or 3 or 4, stands for square or cube or hypercube, default is 3 # $D: 2 or above, cannot be smaller than $k, default is same as $k +# Note: check out $ diff ch-2a.pl ch-2ax.pl use strict; use warnings; use v5.10.0; use Test::More tests => 14; -use Algorithm::Combinatorics qw(permutations); #use for cube and hypercube +use Algorithm::Combinatorics qw(permutations); #use for hypercube my $k = $ARGV[0] || 3; @@ -26,12 +27,12 @@ sub is_square { my $v0 = vec_subtract($p0, $p1); my $v1 = vec_subtract($p0, $p2); my $v2 = vec_subtract($p0, $p3); - return 0 unless (vec_prod($v1, $v2) == 0) xor - (vec_prod($v0, $v2) == 0) xor - (vec_prod($v0, $v1) == 0); + return 0 unless (vec_prod_f($v1, $v2) == 0) xor + (vec_prod_f($v0, $v2) == 0) xor + (vec_prod_f($v0, $v1) == 0); my @n_vector = map { norm_f($_) } ($v0, $v1, $v2); @n_vector = sort {$a<=>$b} @n_vector; - if ( $n_vector[0] == $n_vector[1] && 2*$n_vector[0] == $n_vector[2] ) { + if ( $n_vector[0] == $n_vector[1] ) { return 1; } else { @@ -43,11 +44,11 @@ sub is_cube { my @p = @_; my %v; $v{$_} = vec_subtract($p[0], $p[$_]) for (1..7); - my @ind = sort { norm($v{$a}) <=> norm($v{$b}) } keys %v; + my @ind = sort { norm_f($v{$a}) <=> norm_f($v{$b}) } keys %v; my ($N, $W, $U) = ($v{$ind[0]} , $v{$ind[1]} , $v{$ind[2]}) ; return 0 unless norm_f($N) == norm_f($W) && norm_f($N) == norm_f($U); - return 0 unless vec_prod($N,$W) == 0 && vec_prod($W,$U) == 0 - && vec_prod($U,$N) == 0; + return 0 unless vec_prod_f($N,$W) == 0 && vec_prod_f($W,$U) == 0 + && vec_prod_f($U,$N) == 0; my $NW = vec_sum($N, $W); my $WU = vec_sum($W, $U); my $UN = vec_sum($U, $N); @@ -81,10 +82,10 @@ sub is_cube { if ( vec_same( $v{$ind[6]} , $NWU ) ) { =pod return 0 unless - 2*norm($N) == norm($NW) && - norm($NW) == norm($WU) && - norm($WU) == norm($UN) && - 3*norm($N) == norm($NWU); + 2*norm_f($N) == norm_f($NW) && + norm_f($NW) == norm_f($WU) && + norm_f($WU) == norm_f($UN) && + 3*norm_f($N) == norm_f($NWU); =cut return 1; } @@ -97,19 +98,19 @@ sub is_hypercube { my @p = @_; my %v; $v{$_} = vec_subtract($p[0], $p[$_]) for (1..15); - my @ind = sort { norm($v{$a}) <=> norm($v{$b}) } keys %v; + my @ind = sort { norm_f($v{$a}) <=> norm_f($v{$b}) } keys %v; my ($N, $W, $U, $A) = ( $v{$ind[0]}, $v{$ind[1]} , $v{$ind[2]}, $v{$ind[3]} ); return 0 unless norm_f($N) == norm_f($W) && norm_f($W) == norm_f($U) && norm_f($U) == norm_f($A); return 0 unless - vec_prod($N, $W) == 0 && - vec_prod($N, $U) == 0 && - vec_prod($N, $A) == 0 && - vec_prod($A, $W) == 0 && - vec_prod($A, $U) == 0 && - vec_prod($W, $U) == 0 ; + vec_prod_f($N, $W) == 0 && + vec_prod_f($N, $U) == 0 && + vec_prod_f($N, $A) == 0 && + vec_prod_f($A, $W) == 0 && + vec_prod_f($A, $U) == 0 && + vec_prod_f($W, $U) == 0 ; my $AU = vec_sum($A, $U); my $AW = vec_sum($A, $W); @@ -149,17 +150,17 @@ sub is_hypercube { if ( vec_same($v{$ind[14]}, $AUNW) ) { =pod return 0 unless - 2*norm($N) == norm($NW) && - norm($NW) == norm($AU) && - norm($NW) == norm($UN) && - norm($NW) == norm($WU) && - norm($NW) == norm($AW) && - norm($NW) == norm($AN) && - 3*norm($N) == norm($UNW) && - 3*norm($N) == norm($ANW) && - 3*norm($N) == norm($AWU) && - 3*norm($N) == norm($AUN) && - 4*norm($N) == norm($AUNW); + 2*norm_f($N) == norm_f($NW) && + norm_f($NW) == norm_f($AU) && + norm_f($NW) == norm_f($UN) && + norm_f($NW) == norm_f($WU) && + norm_f($NW) == norm_f($AW) && + norm_f($NW) == norm_f($AN) && + 3*norm_f($N) == norm_f($UNW) && + 3*norm_f($N) == norm_f($ANW) && + 3*norm_f($N) == norm_f($AWU) && + 3*norm_f($N) == norm_f($AUN) && + 4*norm_f($N) == norm_f($AUNW); =cut return 1; } @@ -177,6 +178,10 @@ sub vec_prod { return $sum; } +sub vec_prod_f { + return sprintf("%f", vec_prod($_[0], $_[1])); +} + sub norm { my $p = $_[0]; my $sum = 0; @@ -222,7 +227,7 @@ sub vec_subtract { -# 4 tests +# 9 tests ok is_square( [1,0], [0,1], [-1,0],[0,-1]) == 1, "on x-axis and y-axis"; ok is_square( [5/sqrt(26), 1/sqrt(26)], @@ -245,7 +250,9 @@ ok is_square( [-2.7*cos(atan2(1,5)), -2.7*sin(atan2(1,5))], [2.7*sin(atan2(1,5)), -2.7*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 2.7), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 2.7)," + ."caught by the equalities"; ok is_square( [2.8*cos(atan2(1,5)), 2.8*sin(atan2(1,5))], @@ -253,7 +260,9 @@ ok is_square( [-2.8*cos(atan2(1,5)), -2.8*sin(atan2(1,5))], [2.8*sin(atan2(1,5)), -2.8*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 2.8), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 2.8)," + ."caught by the equalities"; ok is_square( [4.0*cos(atan2(1,5)), 4.0*sin(atan2(1,5))], @@ -261,7 +270,9 @@ ok is_square( [-4.0*cos(atan2(1,5)), -4.0*sin(atan2(1,5))], [4.0*sin(atan2(1,5)), -4.0*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of larger size (multipled by 4.0), caught by the equalities"; + == 1, + "arctan(1/5) by atan2() of larger size (multipled by 4.0)," + ." caught by the equalities"; ok is_square( [0.0009*cos(atan2(1,5)), 0.0009*sin(atan2(1,5))], @@ -269,7 +280,10 @@ ok is_square( [-0.0009*cos(atan2(1,5)), -0.0009*sin(atan2(1,5))], [0.0009*sin(atan2(1,5)), -0.0009*cos(atan2(1,5))] ) - == 1, "arctan(1/5) by atan2() of a much smaller size (multiple by 0.0009), caught by the equalities (_\"not ok\" is normal_)"; + == 1, + "arctan(1/5) by atan2() of a much smaller size" + ."(multiple by 0.0009), caught by the equalities" + ."(_\"not ok\" is normal_)"; ok is_square( [1, 2] , [4,3], [3,1], [2,4] ) == 1, "Knight's square"; ok is_square( [1, 1] , [-1, 1], [1,-1], [-1,-1] ) == 1, "centre at origin"; |
