buggy 2 with n 90degree instead of one rotation
[aoc20.git] / 12 / two.icl
1 module two
2
3 import StdEnv
4 import Data.Func
5 import Data.Tuple
6
7 read :: *File -> [(Char, Int)]
8 read f
9 # (l, f) = freadline f
10 | l.[size l - 1] <> '\n' = []
11 = [(l.[0], toInt (l % (1, size l - 2))):read f]
12
13 Start w
14 # (io, w) = stdio w
15 # ls = read io
16 = (\s->abs s.sx+abs s.sy)
17 $ foldl move {sx=0,sy=0,wx=10,wy=1} ls
18
19 :: Ship = { sx :: Int, sy :: Int, wx :: Int, wy :: Int }
20
21 move s ('N', n) = {s & wy=s.wy+n}
22 move s ('S', n) = {s & wy=s.wy-n}
23 move s ('E', n) = {s & wx=s.wx+n}
24 move s ('W', n) = {s & wx=s.wx-n}
25 move s ('F', n)
26 # dx = s.wx-s.sx
27 # dy = s.wy-s.sy
28 # s = {s & sx=s.sx+dx*n, sy=s.sy+dy*n}
29 = {s & wx=s.sx+dx, wy=s.sy+dy}
30 move s ('R', n) = rot (n/90) s
31 move s ('L', n) = rot (3*(n/90)) s
32
33 //https://stackoverflow.com/questions/2259476/rotating-a-point-about-another-point-2d/25196651#25196651
34 rot :: Int Ship -> Ship
35 rot 0 ship = ship
36 rot n ship=:{sx, sy, wx, wy}
37 # s = toInt (sin 90.0)
38 # c = toInt (cos 90.0)
39 # nx = sx + ( (wx-sx) * c + (wy-sy) * s)
40 # ny = sy + (~(wx-sx) * s + (wy-sy) * c)
41 = rot (n-1) {ship & wx=nx, wy=ny}