blob: 9abedb81575479bcfae49ec1518a78bfb51d1c96 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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]);
}
}
}
|