aboutsummaryrefslogtreecommitdiff
path: root/challenge-101
diff options
context:
space:
mode:
authorAaron Smith <asmith@sumologic.com>2021-02-27 10:53:34 -0600
committerAaron Smith <asmith@sumologic.com>2021-02-27 10:53:34 -0600
commit63aaecd78819c85904b2bd54105872eca199b883 (patch)
tree8cd70532f5a33a9902a145915047c258703d91bf /challenge-101
parent2c26164a5a90aa14a19078d845769d3ec9fbb5ae (diff)
downloadperlweeklychallenge-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.txt1
-rw-r--r--challenge-101/aaronreidsmith/raku/ch-1.raku117
-rw-r--r--challenge-101/aaronreidsmith/raku/ch-2.raku41
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;
+}