Skip to content

Commit 1dae1ae

Browse files
committed
Day 7 part 1
1 parent 3cd5da6 commit 1dae1ae

File tree

3 files changed

+126
-1
lines changed

3 files changed

+126
-1
lines changed

src/adventofcode2024.gleam

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import day3
1313
import day4
1414
import day5
1515
import day6
16+
import day7
1617

1718
pub fn main() {
1819
case argv.load().arguments {
@@ -21,7 +22,7 @@ pub fn main() {
2122
Ok(d) -> run(d)
2223
Error(_) -> io.println("Invalid day: " <> arg)
2324
}
24-
_ -> list.range(1, 6) |> list.each(fn(d) { run(d) })
25+
_ -> list.range(1, 7) |> list.each(fn(d) { run(d) })
2526
}
2627
}
2728

@@ -35,6 +36,7 @@ fn run(d: Int) -> Nil {
3536
4 -> day4.part1(input) |> int.to_string
3637
5 -> day5.part1(input) |> int.to_string
3738
6 -> day6.part1(input) |> int.to_string
39+
7 -> day7.part1(input) |> int.to_string
3840
_ -> "(not implemented)"
3941
}
4042
})

src/day7.gleam

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import gleam/int
2+
import gleam/io
3+
import gleam/list
4+
import gleam/pair
5+
import gleam/result
6+
import gleam/string
7+
import parse
8+
9+
pub fn part1(input: String) -> Int {
10+
input
11+
|> parse_input
12+
|> list.filter(is_valid)
13+
|> list.map(pair.first)
14+
|> int.sum
15+
}
16+
17+
pub type Op {
18+
Number(Int)
19+
Add
20+
Multiply
21+
}
22+
23+
fn evaluate(ops: List(Op)) -> Int {
24+
ops |> list.reverse |> forward_evaluate
25+
}
26+
27+
fn forward_evaluate(ops: List(Op)) -> Int {
28+
case ops {
29+
[Number(a), Add, ..rest] -> a + forward_evaluate(rest)
30+
[Number(a), Multiply, ..rest] -> a * forward_evaluate(rest)
31+
[Number(a)] -> a
32+
_ -> panic as { "Invalid expression" }
33+
}
34+
}
35+
36+
fn is_valid(equation: #(Int, List(Op))) -> Bool {
37+
let _debug_equation = fn(ops: List(Op)) {
38+
io.println_error("")
39+
io.println_error(
40+
"checking if "
41+
<> int.to_string(equation.0)
42+
<> " == "
43+
<> debug_ops(ops)
44+
<> case evaluate(ops) == equation.0 {
45+
True -> " (yes!)"
46+
False -> " (no, " <> int.to_string(evaluate(ops)) <> ")"
47+
},
48+
)
49+
ops
50+
}
51+
52+
possible_ops(equation.1)
53+
// |> list.map(debug_equation)
54+
|> list.find(fn(ops) { evaluate(ops) == equation.0 })
55+
|> result.is_ok
56+
}
57+
58+
fn possible_ops(ops: List(Op)) -> List(List(Op)) {
59+
case ops {
60+
[Number(a)] -> [[Number(a)]]
61+
[Number(a), ..rest] -> {
62+
possible_ops(rest)
63+
|> list.flat_map(fn(restops) {
64+
[[Number(a), Add, ..restops], [Number(a), Multiply, ..restops]]
65+
})
66+
}
67+
[] -> []
68+
[Add, ..] | [Multiply, ..] ->
69+
panic as "possible_ops() requires numeric operands only"
70+
}
71+
}
72+
73+
fn debug_ops(ops: List(Op)) -> String {
74+
ops
75+
|> list.map(fn(op) {
76+
case op {
77+
Number(a) -> int.to_string(a)
78+
Add -> "+"
79+
Multiply -> "*"
80+
}
81+
})
82+
|> string.join(" ")
83+
}
84+
85+
fn parse_input(input: String) -> List(#(Int, List(Op))) {
86+
input
87+
|> parse.lines
88+
|> list.map(fn(line) {
89+
line |> string.split_once(": ") |> result.unwrap(#("0", "0"))
90+
})
91+
|> list.map(fn(row) {
92+
#(
93+
row.0 |> int.parse |> result.unwrap(0),
94+
row.1
95+
|> string.split(" ")
96+
|> list.filter_map(int.parse)
97+
|> list.map(fn(i) { Number(i) }),
98+
)
99+
})
100+
}

test/day7_test.gleam

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import gleeunit
2+
import gleeunit/should
3+
4+
import day7
5+
6+
pub fn main() {
7+
gleeunit.main()
8+
}
9+
10+
const example1 = "190: 10 19
11+
3267: 81 40 27
12+
83: 17 5
13+
156: 15 6
14+
7290: 6 8 6 15
15+
161011: 16 10 13
16+
192: 17 8 14
17+
21037: 9 7 18 13
18+
292: 11 6 16 20
19+
"
20+
21+
pub fn part1_test() {
22+
day7.part1(example1) |> should.equal(3749)
23+
}

0 commit comments

Comments
 (0)