diff options
| -rw-r--r-- | challenge-101/simon-proctor/raku/ch-1.raku | 49 | ||||
| -rw-r--r-- | challenge-101/simon-proctor/raku/ch-2.raku | 77 |
2 files changed, 126 insertions, 0 deletions
diff --git a/challenge-101/simon-proctor/raku/ch-1.raku b/challenge-101/simon-proctor/raku/ch-1.raku new file mode 100644 index 0000000000..d98113719f --- /dev/null +++ b/challenge-101/simon-proctor/raku/ch-1.raku @@ -0,0 +1,49 @@ +#!/usr/bin/env raku + +use v6; + +#| Run the test suite +multi sub MAIN( "test" ) { + use Test; + is( tight-factors(4), (2,2), "4 factors to 2 and 2" ); + is( tight-factors(12), (3,4), "12 factors to 3 and 4" ); + is( spiralize( [1,2,3,4] ), [[4,3],[1,2]], "4 long list" ); + is( spiralize( [1,2,3,4,5,6] ), [[6,5,4],[1,2,3]], "6 Long list" ); + is( spiralize( (1..12) ), [[9,8,7,6],[10,11,12,5],[1,2,3,4]], "12 Long list" ); + done-testing; +} + +#| Given a list of items print them in a tight anti clockwise sprial +multi sub MAIN( *@items ) { + my $width = @items.map( *.chars ).max; + .say for spiralize( @items ).map( -> @l { @l.map( { sprintf("%{$width}s",$_ ) } ).join(" ") }); +} + +sub tight-factors(Int $len) { + (1..$len div 2).grep( { $len %% $_ } ).map( { ($_, $len / $_ ) } ).sort( -> ($a,$b) { abs($a-$b) } ).first; +} + +sub spiralize( @list ) { + my ( $height, $width ) = tight-factors( @list.elems ); + my @out = [[Any xx $width] xx $height]; + + my @current = [0,$height-1]; + my @direction = [1,0]; + + for @list -> $val { + @out[@current[1]][@current[0]] = $val; + my @next = [ @current[0]+@direction[0], @current[1]+@direction[1] ]; + if @next[0] < 0 || @next[1] < 0 || + (@out[@next[1]][@next[0]]:!exists) || (defined @out[@next[1]][@next[0]]) { + given @direction { + when [1,0] { @direction = [0,-1] } + when [0,-1] { @direction = [-1,0] } + when [-1,0] { @direction = [0,1] } + when [0,1] { @direction = [1,0] } + } + } + @current = [ @current[0]+@direction[0], @current[1]+@direction[1] ]; + } + return @out; +} + diff --git a/challenge-101/simon-proctor/raku/ch-2.raku b/challenge-101/simon-proctor/raku/ch-2.raku new file mode 100644 index 0000000000..7ab78e1c55 --- /dev/null +++ b/challenge-101/simon-proctor/raku/ch-2.raku @@ -0,0 +1,77 @@ +#!/usr/bin/env raku + +use v6; + +class Point {...} +class Vector {...} +class Triangle {...} + +sub p( *@ (Rat() $x, Rat() $y) ) { + Point.new( :$x, :$y ); +} + +sub v( *@ (Point $p1, Point $p2) ) { + Vector.new( :$p1, :$p2 ); +} + +sub t( *@ (Point $p1, Point $p2, Point $p3 ) ) { + Triangle.new( :$p1, :$p2, :$p3 ) +} + +class Point { + has Rat() $.x; + has Rat() $.y; +} + +class Vector { + has Point $.p1; + has Point $.p2; + + method len() { + ( ($.p1.x - $.p2.x)² + ($.p1.y - $.p2.y)² ).sqrt; + } +} + +class Triangle { + has Point $.p1; + has Point $.p2; + has Point $.p3; + + method area() { + my \a = v($.p1,$.p2).len; + my \b = v($.p1,$.p3).len; + my \c = v($.p2,$.p3).len; + my \s = (a + b + c) / 2; + return ( s * (s - a) * (s - b) * (s - c) ).sqrt; + } + + method point-inside( Point $pn ) { + my $*TOLERANCE = .0000001; + return self.area =~= + ( t($pn, $.p1, $.p2).area + + t($pn, $.p1, $.p3).area + + t($pn, $.p2, $.p3).area ); + } +} + +#| Run tests +multi sub MAIN("test") { + use Test; + isa-ok( p(2,3), Point, "Point Creation OK" ); + isa-ok( v(p(0,0), p(2,2)), Vector, "Vector Creation OK" ); + isa-ok( t(p(0,0), p(0,3), p(4,0)), Triangle, "Triangle Creation OK" ); + is( v(p(0,0), p(3,4)).len, 5, "Vector Length works" ); + is( t(p(0,0), p(0,3), p(4,0)).area, 6, "Triangle Area works" ); + is( t(p(0,1),p(1,0),p(2,2)).point-inside(p(0,0)), False, "Origin not in Triangle" ); + is( t(p(1,1),p(-1,1),p(0,-3)).point-inside(p(0,0)), True, "Origin in Triangle" ); + is( t(p(0,1),p(2,0),p(-6,0)).point-inside(p(0,0)), True, "Origin on edge test" ); +} + +#| Does the triangle made from the 6 gives points contain the origin? +multi sub MAIN( Rat() $p1x, Rat() $p1y, + Rat() $p2x, Rat() $p2y, + Rat() $p3x, Rat() $p3y ) { + say t(p($p1x,$p1y), + p($p2x,$p2y), + p($p3x,$p3y)).point-inside(p(0,0)) ?? 1 !! 0; +} |
