aboutsummaryrefslogtreecommitdiff
path: root/2020/twelve.nim
blob: db98f3a7e27277c2a7c6bd5976d9c662d0bc7157 (plain) (blame)
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
# Day Twelve: Rain Risk
import os, strutils, sequtils, math, sugar

let input: string = paramStr(1)
let instructions: seq[tuple[action: char, value: int]] =
  input.readFile().strip().split('\n')
    .map(instruction => (instruction[0], parseInt(instruction[1..^1])))

var ferry, actual: tuple[latitude, longitude, bearing: int] = (0, 0, 0)
var waypoint: tuple[latitude, longitude: int] = (1, 10)
for instruction in instructions:
  let value: int = instruction.value
  let current: tuple[latitude, longitude: int] = waypoint
  case instruction.action
  of 'N':
    inc(ferry.latitude, value)
    inc(waypoint.latitude, value)
  of 'S':
    dec(ferry.latitude, value)
    dec(waypoint.latitude, value)
  of 'E':
    inc(ferry.longitude, value)
    inc(waypoint.longitude, value)
  of 'W':
    dec(ferry.longitude, value)
    dec(waypoint.longitude, value)
  of 'L':
    inc(ferry.bearing, value)
    let bearing: float = degToRad(toFloat(value))
    case value
    of 0, 180:
      waypoint.latitude = sgn(cos(bearing)) * current.latitude
      waypoint.longitude = sgn(cos(bearing)) * current.longitude
    of 90, 270:
      waypoint.latitude = sgn(sin(bearing)) * current.longitude
      waypoint.longitude = -sgn(sin(bearing)) * current.latitude
    else:
      discard
  of 'R':
    dec(ferry.bearing, value)
    let bearing: float = degToRad(toFloat(value))
    case value
    of 0, 180:
      waypoint.latitude = sgn(cos(bearing)) * current.latitude
      waypoint.longitude = sgn(cos(bearing)) * current.longitude
    of 90, 270:
      waypoint.latitude = -sgn(sin(bearing)) * current.longitude
      waypoint.longitude = sgn(sin(bearing)) * current.latitude
    else:
      discard
  of 'F':
    let bearing: float = degToRad(toFloat(ferry.bearing))
    if abs(cos(bearing)) == 1.0:
      inc(ferry.longitude, sgn(cos(bearing)) * value)
    elif abs(sin(bearing)) == 1.0:
      inc(ferry.latitude, sgn(sin(bearing)) * value)
    inc(actual.longitude, value * waypoint.longitude)
    inc(actual.latitude, value * waypoint.latitude)
  else:
    discard
echo abs(ferry.longitude) + abs(ferry.latitude)
echo abs(actual.longitude) + abs(actual.latitude)