diff options
| author | Aaron Smith <asmith@sumologic.com> | 2021-02-27 10:53:34 -0600 |
|---|---|---|
| committer | Aaron Smith <asmith@sumologic.com> | 2021-02-27 10:53:34 -0600 |
| commit | 63aaecd78819c85904b2bd54105872eca199b883 (patch) | |
| tree | 8cd70532f5a33a9902a145915047c258703d91bf /challenge-101 | |
| parent | 2c26164a5a90aa14a19078d845769d3ec9fbb5ae (diff) | |
| download | perlweeklychallenge-club-63aaecd78819c85904b2bd54105872eca199b883.tar.gz perlweeklychallenge-club-63aaecd78819c85904b2bd54105872eca199b883.tar.bz2 perlweeklychallenge-club-63aaecd78819c85904b2bd54105872eca199b883.zip | |
Challenge 101 - Raku
Diffstat (limited to 'challenge-101')
| -rw-r--r-- | challenge-101/aaronreidsmith/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-101/aaronreidsmith/raku/ch-1.raku | 117 | ||||
| -rw-r--r-- | challenge-101/aaronreidsmith/raku/ch-2.raku | 41 |
3 files changed, 159 insertions, 0 deletions
diff --git a/challenge-101/aaronreidsmith/blog.txt b/challenge-101/aaronreidsmith/blog.txt new file mode 100644 index 0000000000..5b28a37b24 --- /dev/null +++ b/challenge-101/aaronreidsmith/blog.txt @@ -0,0 +1 @@ +https://aaronreidsmith.github.io/blog/perl-weekly-challenge-101/ diff --git a/challenge-101/aaronreidsmith/raku/ch-1.raku b/challenge-101/aaronreidsmith/raku/ch-1.raku new file mode 100644 index 0000000000..0892686069 --- /dev/null +++ b/challenge-101/aaronreidsmith/raku/ch-1.raku @@ -0,0 +1,117 @@ +#!/usr/bin/env raku + +# Finds all factor pairs of a given numbers +sub factors(Int $n) returns Positional { + my $max = $n.sqrt.floor; + my $number = 1; + my @factors; + while $number <= $max { + my $potential-factor = $n / $number; + if $potential-factor == $potential-factor.Int { + @factors.push(($number.clone, $potential-factor)); + } + $number++; + } + @factors; +} + +# Formats a 2D array into a multi-line string +sub format(@two-d) returns Str { + my $width = @two-d[*;*].max(*.chars).chars; + my @formatted = gather { + for @two-d -> @row { + take @row.map(-> $num { sprintf('%*s', $width, $num) }).join(' '); + } + } + @formatted.join("\n"); +} + +sub challenge(@A) returns Str { + enum Direction <NORTH EAST SOUTH WEST>; + + my @factors = factors(@A.elems); + my ($m, $n) = @factors.min(-> ($a, $b) { abs($a - $b) }); + my (@matrix, @output); + for ^$m { + my (@matrix-row, @output-row); + for ^$n { + @matrix-row.push({ :!visited }); + @output-row.push(Nil) + } + @matrix.push(@matrix-row); + @output.push(@output-row); + } + + sub visit-cell($i, $j, $element) { + my %cell = @matrix[$i][$j]; + if !%cell<visited> { + @output[$i][$j] = $element; + } + @matrix[$i][$j]<visited> = True; + } + + my ($min-row, $min-col) = 0, 0; + my ($max-row, $max-col) = @matrix.elems - 1, @matrix.tail.elems - 1; + my ($current-row, $current-col, $current-direction) = $min-row, $min-col, EAST; + + for @A -> $element { + visit-cell($current-row, $current-col, $element); + given $current-direction { + when EAST { + if $current-col == $max-col || @matrix[$current-row][$current-col+1]<visited> { + $current-direction = SOUTH; + $current-row += 1; + } else { + $current-col += 1; + } + } + when SOUTH { + if ($current-row == $max-row && $current-col == $max-col) || @matrix[$current-row+1][$current-col]<visited> { + $current-direction = WEST; + $current-col -= 1; + } else { + $current-row += 1; + } + } + when WEST { + if $current-col == $min-col || @matrix[$current-row][$current-col-1]<visited> { + $current-direction = NORTH; + $current-row -= 1; + } else { + $current-col -= 1; + } + } + when NORTH { + # No need to check for special case here, because we always start in the top left + if @matrix[$current-row-1][$current-col]<visited> { + $current-direction = EAST; + $current-col += 1; + } else { + $current-row -= 1; + } + } + } + } + + format(@output.reverse); +} + +multi sub MAIN(*@A) { + say challenge(@A); +} + +multi sub MAIN(Bool :$test) { + use Test; + + my @tests = ( + ((1..4), "4 3\n1 2"), + ((1..6), "6 5 4\n1 2 3"), + ((1..12), " 9 8 7 6\n10 11 12 5\n 1 2 3 4") + ); + + for @tests -> (@input, $expected) { + is(challenge(@input), $expected); + } + + done-testing; +} diff --git a/challenge-101/aaronreidsmith/raku/ch-2.raku b/challenge-101/aaronreidsmith/raku/ch-2.raku new file mode 100644 index 0000000000..79572db84e --- /dev/null +++ b/challenge-101/aaronreidsmith/raku/ch-2.raku @@ -0,0 +1,41 @@ +#!/usr/bin/env raku + +class Point { + has Int $.x; + has Int $.y; + + multi method new($x, $y) { + self.bless(:$x, :$y); + } +} + +sub challenge(Point $A, Point $B, Point $C, Point $target = Point.new(0, 0)) returns Int { + my $area = 0.5 * (-$B.y * $C.x + $A.y * (-$B.x + $C.x) + $A.x * ($B.y - $C.y) + $B.x * $C.y); + my $s = 1 / (2 * $area) * ($A.y * $C.x - $A.x * $C.y + ($C.y - $A.y) * $target.x + ($A.x - $C.x) * $target.y); + my $t = 1 / (2 * $area) * ($A.x * $B.y - $A.y * $B.x + ($A.y - $B.y) * $target.x + ($B.x - $A.x) * $target.y); + (0 <= $s <= 1 && 0 <= $t <= 1 && $s + $t <= 1).Int; +} + +multi sub MAIN(Int $x1, Int $y1, Int $x2, Int $y2, Int $x3, Int $y3) { + say challenge( + Point.new($x1, $y1), + Point.new($x2, $y2), + Point.new($x3, $y3) + ); +} + +multi sub MAIN(Bool :$test) { + use Test; + + my @tests = ( + (Point.new(0, 1), Point.new(1, 0), Point.new(2, 2), 0), + (Point.new(1, 1), Point.new(-1, 1), Point.new(0, -3), 1), + (Point.new(0, 1), Point.new(2, 0), Point.new(-6, 0), 1) + ); + + for @tests -> ($A, $B, $C, $expected) { + is(challenge($A, $B, $C), $expected); + } + + done-testing; +} |
