aboutsummaryrefslogtreecommitdiff
path: root/aoc-2020-gleam/src/days/day25.gleam
blob: b70d7201cc0030fda023e16a087ad9d7e7011da9 (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
import gleam/io
import gleam/bool
import util/input_util

const mod = 20_201_227

const init_subject = 7

fn forward_transform(value: Int, subject: Int, loop: Int) -> Int {
  use <- bool.guard(when: loop == 0, return: value)
  forward_transform({ value * subject } % mod, subject, loop - 1)
}

fn backward_transform(value: Int, subject: Int, loop: Int, result: Int) -> Int {
  use <- bool.guard(when: value == result, return: loop)
  backward_transform({ value * subject } % mod, subject, loop + 1, result)
}

fn find_result(subject: Int, loop: Int) -> Int {
  forward_transform(1, subject, loop)
}

fn find_loop(subject: Int, result: Int) -> Int {
  backward_transform(1, subject, 0, result)
}

fn part1(keys: List(Int)) -> Int {
  let assert [card_key, door_key] = keys

  let card_loop = find_loop(init_subject, card_key)
  let card_result = find_result(door_key, card_loop)

  let door_loop = find_loop(init_subject, door_key)
  let door_result = find_result(card_key, door_loop)

  let assert True = card_result == door_result
  card_result
}

pub fn main() -> Nil {
  let testing = input_util.read_numbers("test25")
  let assert 14_897_079 = part1(testing)

  let input = input_util.read_numbers("day25")
  io.debug(part1(input))

  Nil
}