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
|
import gleam/io
import gleam/int
import gleam/list
import gleam/bool
import gleam/result as res
import ext/listx
import ext/pairx
import ext/genericx as genx
import util/input_util
import util/cache.{type Cache}
const outlet_joltage = 0
const max_increase = 3
fn process_adapters(numbers: List(Int)) -> List(Int) {
let numbers = list.sort(numbers, by: int.compare)
let assert Ok(device_joltage) =
numbers
|> list.last
|> res.map(with: int.add(_, max_increase))
list.flatten([[outlet_joltage], numbers, [device_joltage]])
}
fn part1(numbers: List(Int)) -> Int {
let adapters = process_adapters(numbers)
let diffs =
adapters
|> list.window_by_2
|> list.map(with: pairx.difference)
let ones = listx.count(diffs, satisfying: genx.equals(_, 1))
let threes = listx.count(diffs, satisfying: genx.equals(_, 3))
ones * threes
}
fn arrangements(number: Int, adapters: List(Int), cache: Cache(Int, Int)) -> Int {
use <- bool.guard(when: number == 0, return: 1)
use <- bool.guard(when: !list.contains(adapters, number), return: 0)
use <- cache.memoize(with: cache, this: number)
list.range(from: 1, to: max_increase)
|> list.map(with: fn(j) { arrangements(number - j, adapters, cache) })
|> int.sum
}
fn part2(numbers: List(Int)) -> Int {
let adapters = process_adapters(numbers)
let assert Ok(device_joltage) = list.last(adapters)
use cache <- cache.create()
arrangements(device_joltage, adapters, cache)
}
pub fn main() -> Nil {
let testing = input_util.read_numbers("test10")
let assert 220 = part1(testing)
let assert 19_208 = part2(testing)
let input = input_util.read_numbers("day10")
io.debug(part1(input))
io.debug(part2(input))
Nil
}
|