class Point { has $.x = 0; has $.y = 0; method Str(--> Str) { "Point ($.x, $.y)" } } class Line { has Point $.p; has Point $.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) { abs($p.x - $q.x) + abs($p.y - $q.y) } class Wire { has Point @.points; submethod new(Str $input) { my @movements = $input.split(','); my @points; for @movements -> $move { if $move ~~ /$ = [ <[ UDLR ]> ] $ = [ \d+]/ { my $x = 0; my $y = 0; given $ { when "U" { $y += $.Int } when "D" { $y += -$.Int } when "L" { $x += -$.Int } when "R" { $x += $.Int } } @points.append: Point.new(:$x, :$y); } } self.bless(:@points); } method segments { @.points[0..^*-1] Z @.points[1..*] } }