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
79
80
81
|
import gary.{type ErlangArray}
import gary/array.{type ArrayError}
import gleam/bool
import gleam/int
import gleam/list
import gleam/result
import gleam/string
pub fn parse(input: String) -> ErlangArray(Int) {
input
|> string.split(",")
|> list.map(int.parse)
|> result.values()
|> array.from_list(default: -1)
|> array.make_fixed()
}
pub fn pt_1(input: ErlangArray(Int)) -> Int {
let assert Ok(result) =
input
|> edit_starting_intcodes(12, 2)
|> run_intcode(0)
result
}
pub fn pt_2(input: ErlangArray(Int)) -> Int {
let assert [result] = {
use noun <- list.flat_map(list.range(0, 99))
use verb <- list.filter_map(list.range(0, 99))
let result = input |> edit_starting_intcodes(noun, verb) |> run_intcode(0)
case result == Ok(19_690_720) {
True -> Ok(100 * noun + verb)
False -> Error(Nil)
}
}
result
}
fn run_intcode(
intcode: ErlangArray(Int),
pointer: Int,
) -> Result(Int, ArrayError) {
let assert Ok(op_code) = array.get(intcode, pointer)
let op = get_op(op_code)
use <- bool.guard(result.is_error(op), array.get(intcode, 0))
let assert Ok(position_1) = array.get(intcode, pointer + 1)
let assert Ok(position_2) = array.get(intcode, pointer + 2)
let assert Ok(position_3) = array.get(intcode, pointer + 3)
let assert Ok(value_1) = array.get(intcode, position_1)
let assert Ok(value_2) = array.get(intcode, position_2)
let assert Ok(f) = op
let new_value = f(value_1, value_2)
let assert Ok(updated_intcode) = array.set(intcode, position_3, new_value)
run_intcode(updated_intcode, pointer + 4)
}
fn edit_starting_intcodes(
intcodes: ErlangArray(Int),
new_code_1: Int,
new_code_2: Int,
) -> ErlangArray(Int) {
let assert Ok(updated) =
intcodes
|> array.set(at: 1, put: new_code_1)
|> result.try(array.set(into: _, at: 2, put: new_code_2))
updated
}
fn get_op(code: Int) -> Result(fn(Int, Int) -> Int, Nil) {
case code {
1 -> Ok(int.add)
2 -> Ok(int.multiply)
99 -> Error(Nil)
_ -> panic as "bad opcode"
}
}
|