Skip to content

Commit 50cf355

Browse files
committed
Finished day 22
1 parent e85b75c commit 50cf355

File tree

7 files changed

+172
-9
lines changed

7 files changed

+172
-9
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Advent of Code 2024
22

33
[![Tests](https://github.com/devries/advent_of_code_2024/actions/workflows/test.yml/badge.svg)](https://github.com/devries/advent_of_code_2024/actions/workflows/test.yml)
4-
[![Stars: 41](https://img.shields.io/badge/⭐_Stars-41-yellow)](https://adventofcode.com/2024)
4+
[![Stars: 43](https://img.shields.io/badge/⭐_Stars-43-yellow)](https://adventofcode.com/2024)
55

66
This year I am going to try to do Advent of Code in [Gleam](https://gleam.run).
77
To run a day's problems use the command
@@ -39,4 +39,5 @@ information.
3939
- [Day 18](https://adventofcode.com/2024/day/18): [⭐ ⭐ solution](src/day18/solution.gleam)
4040
- [Day 19](https://adventofcode.com/2024/day/19): [⭐ ⭐ solution](src/day19/solution.gleam)
4141
- [Day 20](https://adventofcode.com/2024/day/20): [⭐ ⭐ solution](src/day20/solution.gleam)
42-
- [Day 21](https://adventofcode.com/2024/day/21): [⭐ solution](src/day21/solution.gleam)
42+
- [Day 21](https://adventofcode.com/2024/day/21): [⭐ solution](src/day21/solution.gleam)
43+
- [Day 22](https://adventofcode.com/2024/day/22): [⭐ ⭐ solution](src/day22/solution.gleam)

gleam.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ birl = ">= 1.7.1 and < 2.0.0"
2121
gleam_erlang = ">= 0.33.0 and < 1.0.0"
2222
gleam_otp = ">= 0.16.0 and < 1.0.0"
2323
envoy = ">= 1.0.2 and < 2.0.0"
24+
gleam_yielder = ">= 1.1.0 and < 2.0.0"
2425

2526
[dev-dependencies]
2627
gleeunit = ">= 1.0.0 and < 2.0.0"

inputs

manifest.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ packages = [
1010
{ name = "gleam_otp", version = "0.16.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "FA0EB761339749B4E82D63016C6A18C4E6662DA05BAB6F1346F9AF2E679E301A" },
1111
{ name = "gleam_regexp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "A3655FDD288571E90EE9C4009B719FEF59FA16AFCDF3952A76A125AF23CF1592" },
1212
{ name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" },
13+
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
1314
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
1415
{ name = "ranger", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "ranger", source = "hex", outer_checksum = "B8F3AFF23A3A5B5D9526B8D18E7C43A7DFD3902B151B97EC65397FE29192B695" },
1516
{ name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" },
@@ -23,5 +24,6 @@ gleam_erlang = { version = ">= 0.33.0 and < 1.0.0" }
2324
gleam_otp = { version = ">= 0.16.0 and < 1.0.0" }
2425
gleam_regexp = { version = ">= 1.0.0 and < 2.0.0" }
2526
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
27+
gleam_yielder = { version = ">= 1.1.0 and < 2.0.0" }
2628
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
2729
simplifile = { version = ">= 2.2.0 and < 3.0.0" }

src/day22/solution.gleam

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import gleam/dict.{type Dict}
2+
import gleam/int
3+
import gleam/io
4+
import gleam/list
5+
import gleam/pair
6+
import gleam/result
7+
import gleam/yielder
8+
import internal/aoc_utils
9+
10+
pub fn main() {
11+
let filename = "inputs/day22.txt"
12+
13+
let lines_result = aoc_utils.read_lines(from: filename)
14+
case lines_result {
15+
Ok(lines) -> {
16+
// If the file was converting into a list of lines
17+
// successfully then run each part of the problem
18+
aoc_utils.run_part_and_print("Part 1", fn() { solve_p1(lines) })
19+
aoc_utils.run_part_and_print("Part 2", fn() { solve_p2(lines) })
20+
}
21+
Error(_) -> io.println("Error reading file")
22+
}
23+
}
24+
25+
// Part 1
26+
pub fn solve_p1(lines: List(String)) -> Result(String, String) {
27+
use numberlist <- result.map({
28+
lines
29+
|> list.try_map(int.parse)
30+
|> result.replace_error("Unable to parse input")
31+
})
32+
33+
numberlist
34+
|> list.map(step_times(_, 2000))
35+
|> int.sum
36+
|> int.to_string
37+
}
38+
39+
// Part 2
40+
pub fn solve_p2(lines: List(String)) -> Result(String, String) {
41+
use numberlist <- result.try({
42+
lines
43+
|> list.try_map(int.parse)
44+
|> result.replace_error("Unable to parse input")
45+
})
46+
47+
use best_pair <- result.map({
48+
numberlist
49+
|> list.map(find_sequence_sets(_, 2000))
50+
|> list.map(build_values)
51+
|> list.fold(dict.new(), fn(da, d) {
52+
dict.to_list(d)
53+
|> list.fold(da, fn(da, tup) {
54+
let #(seq, price) = tup
55+
let value = dict.get(da, seq) |> result.unwrap(0)
56+
dict.insert(da, seq, value + price)
57+
})
58+
})
59+
|> dict.to_list
60+
|> list.sort(fn(a, b) { int.compare(a.1, b.1) })
61+
|> list.last
62+
|> result.replace_error("Something went wront")
63+
})
64+
65+
pair.second(best_pair)
66+
|> int.to_string
67+
}
68+
69+
pub fn step(start: Int) -> Int {
70+
let first = int.bitwise_exclusive_or({ start * 64 }, start) % 16_777_216
71+
let second = int.bitwise_exclusive_or({ first / 32 }, first) % 16_777_216
72+
int.bitwise_exclusive_or({ second * 2048 }, second) % 16_777_216
73+
}
74+
75+
fn step_times(start: Int, times: Int) -> Int {
76+
case times {
77+
0 -> start
78+
n -> step_times(step(start), n - 1)
79+
}
80+
}
81+
82+
fn price_sequence(start: Int, length: Int) -> List(Int) {
83+
yielder.unfold(start, fn(v) {
84+
let r = step(v)
85+
yielder.Next(v, r)
86+
})
87+
|> yielder.take(length + 1)
88+
|> yielder.to_list
89+
|> list.map(fn(v) { v % 10 })
90+
}
91+
92+
fn differences(numbers: List(Int)) -> List(Int) {
93+
list.window_by_2(numbers)
94+
|> list.map(fn(tup) { tup.1 - tup.0 })
95+
}
96+
97+
fn find_sequence_sets(start: Int, length: Int) -> List(#(Int, List(Int))) {
98+
let prices = price_sequence(start, length)
99+
100+
let sequences = differences(prices) |> list.window(4)
101+
102+
list.zip(list.drop(prices, 4), sequences)
103+
}
104+
105+
fn build_values(sequences: List(#(Int, List(Int)))) -> Dict(List(Int), Int) {
106+
list.fold(sequences, dict.new(), fn(d, tup) {
107+
let #(price, sequence) = tup
108+
109+
case dict.get(d, sequence) {
110+
Ok(_) -> d
111+
Error(Nil) -> {
112+
dict.insert(d, sequence, price)
113+
}
114+
}
115+
})
116+
}

test/day21_test.gleam

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ pub fn part1_test() {
1313
solution.solve_p1(lines)
1414
|> should.equal(Ok("126384"))
1515
}
16-
17-
pub fn part2_test() {
18-
let lines = string.split(testinput, "\n")
19-
solution.solve_p2(lines)
20-
|> should.equal(Ok(""))
21-
}
16+
// Uncomment when done
17+
// pub fn part2_test() {
18+
// let lines = string.split(testinput, "\n")
19+
// solution.solve_p2(lines)
20+
// |> should.equal(Ok(""))
21+
// }

test/day22_test.gleam

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import day22/solution
2+
import gleam/io
3+
import gleam/list
4+
import gleam/string
5+
import gleam/yielder
6+
import gleeunit/should
7+
8+
const testinput = "1
9+
10
10+
100
11+
2024"
12+
13+
pub fn part1_test() {
14+
let lines = string.split(testinput, "\n")
15+
solution.solve_p1(lines)
16+
|> should.equal(Ok("37327623"))
17+
}
18+
19+
const testinput_p2 = "1
20+
2
21+
3
22+
2024"
23+
24+
pub fn part2_test() {
25+
let lines = string.split(testinput_p2, "\n")
26+
solution.solve_p2(lines)
27+
|> should.equal(Ok("23"))
28+
}
29+
30+
const testsequence = [
31+
15_887_950, 16_495_136, 527_345, 704_524, 1_553_684, 12_683_156, 11_100_544,
32+
12_249_484, 7_753_432, 5_908_254,
33+
]
34+
35+
pub fn step_test() {
36+
yielder.unfold(123, fn(v) {
37+
let r = solution.step(v)
38+
yielder.Next(r, r)
39+
})
40+
|> yielder.take(list.length(testsequence))
41+
|> yielder.to_list
42+
|> should.equal(testsequence)
43+
}

0 commit comments

Comments
 (0)