summaryrefslogtreecommitdiff
path: root/lib/AdventOfCode/Utils.rakumod
diff options
context:
space:
mode:
authorMatias Linares <matiaslina@gmail.com>2019-12-10 09:29:12 -0300
committerMatias Linares <matiaslina@gmail.com>2019-12-10 09:29:12 -0300
commit8f35c2dc6516303ae0786d08cc7912ccb8218f78 (patch)
treef27e82ddd3d7044e19d964345e2991d5cbf67f00 /lib/AdventOfCode/Utils.rakumod
downloadadvent-of-code-2019-8f35c2dc6516303ae0786d08cc7912ccb8218f78.tar.gz
Initial commit
Diffstat (limited to 'lib/AdventOfCode/Utils.rakumod')
-rw-r--r--lib/AdventOfCode/Utils.rakumod78
1 files changed, 78 insertions, 0 deletions
diff --git a/lib/AdventOfCode/Utils.rakumod b/lib/AdventOfCode/Utils.rakumod
new file mode 100644
index 0000000..9abedb8
--- /dev/null
+++ b/lib/AdventOfCode/Utils.rakumod
@@ -0,0 +1,78 @@
+class Point {
+ has Real $.x = 0;
+ has Real $.y = 0;
+
+ method Str(--> Str) {
+ try { "<$.x, $.y>" } or "undefined"
+ }
+}
+
+class Line {
+ has Point $.p;
+ has Point $.q;
+
+ multi method new(Point $p, Point $q) {
+ self.bless(:$p, :$q)
+ }
+
+ multi method new(Point :$p, Point :$q) {
+ self.bless(:$p, :$q)
+ }
+}
+
+sub intersection(Line $l1, Line $l2) is export {
+ my $a1 = $l1.q.y - $l1.p.y;
+ my $b1 = $l1.p.x - $l1.q.x;
+ my $c1 = $a1 * $l1.p.x + $b1 * $l1.p.y;
+
+ my $a2 = $l2.q.y - $l2.p.y;
+ my $b2 = $l2.p.x - $l2.q.x;
+ my $c2 = $a2 * $l2.p.x + $b2 * $l2.p.y;
+
+ my $delta = $a1 * $b2 - $a2 * $b1;
+
+ return Point.new(
+ :x(($b2 * $c1 - $b1 * $c2) / $delta),
+ :y(($a1 * $c2 - $a2 * $c1) / $delta)
+ )
+}
+
+sub manhattan-distance(Point $p, Point $q) is export {
+ abs($p.x - $q.x) + abs($p.y - $q.y)
+}
+
+
+class Wire is export {
+ has Point @.points;
+
+ submethod new(Str $input) {
+ my @movements = $input.split(',');
+ my @points;
+ my $x = 0;
+ my $y = 0;
+
+ for @movements -> $move {
+ if $move ~~ /$<direction> = [ <[ UDLR ]> ] $<size> = [ \d+]/ {
+ given $<direction> {
+ when "U" { $y += $<size>.Int }
+ when "D" { $y += -$<size>.Int }
+ when "L" { $x += -$<size>.Int }
+ when "R" { $x += $<size>.Int }
+ }
+ @points.append: Point.new(:$x, :$y);
+ }
+ }
+
+ self.bless(:@points);
+ }
+
+ method segments {
+ @.points[0..^*-1] Z @.points[1..*]
+ }
+
+ method lines {
+ gather for self.segments -> $s {
+ take Line.new($s[0], $s[1]);
+ }
+ }
+}