Skip to content

Commit e85b75c

Browse files
committed
finished day 21 part 1, thinking about part 2
1 parent d3c697c commit e85b75c

File tree

3 files changed

+98
-48
lines changed

3 files changed

+98
-48
lines changed

README.md

Lines changed: 2 additions & 1 deletion
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: 40](https://img.shields.io/badge/⭐_Stars-40-yellow)](https://adventofcode.com/2024)
4+
[![Stars: 41](https://img.shields.io/badge/⭐_Stars-41-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,3 +39,4 @@ 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)

src/day21/solution.gleam

Lines changed: 95 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import gleam/int
22
import gleam/io
33
import gleam/list
44
import gleam/order
5+
import gleam/result
56
import gleam/string
67
import internal/aoc_utils
8+
import internal/memoize
79
import internal/point.{type Point}
810

911
pub fn main() {
@@ -61,39 +63,74 @@ pub fn main() {
6163
// Part 1
6264
pub fn solve_p1(lines: List(String)) -> Result(String, String) {
6365
list.map(lines, fn(line) {
64-
decode_numeric_sequence(line)
65-
|> io.debug
66-
|> decode_directional_sequence
67-
|> io.debug
68-
|> decode_directional_sequence
69-
|> io.debug
70-
|> string.length
71-
|> io.debug
66+
let length =
67+
decode_numeric_sequence(line)
68+
|> decode_directional_sequence
69+
|> decode_directional_sequence
70+
|> list.map(fn(l) { string.length(l) })
71+
|> list.reduce(int.min)
72+
|> result.unwrap(0)
73+
get_numeric_portions(line) * length
7274
})
73-
74-
todo
75+
|> int.sum
76+
|> int.to_string
77+
|> Ok
7578
}
7679

7780
// Part 2
7881
pub fn solve_p2(lines: List(String)) -> Result(String, String) {
79-
Error("Unimplemented")
82+
// I think I will need to memoize, but I need to figure out what.
83+
use cache <- memoize.with_cache()
84+
85+
list.map(lines, fn(line) {
86+
let length =
87+
decode_numeric_sequence(line)
88+
|> todo
89+
|> list.map(fn(l) { string.length(l) })
90+
|> list.reduce(int.min)
91+
|> result.unwrap(0)
92+
get_numeric_portions(line) * length
93+
})
94+
|> int.sum
95+
|> int.to_string
96+
|> Ok
8097
}
8198

82-
fn decode_numeric_sequence(sequence: String) -> String {
99+
fn decode_numeric_sequence(sequence: String) -> List(String) {
83100
string.to_graphemes("A" <> sequence)
84101
|> list.window_by_2
85102
|> list.map(fn(pair) { find_motion_numeric(pair.0, pair.1) })
86-
|> string.join("")
103+
|> list.reduce(fn(solutions, next_set) {
104+
solutions
105+
|> list.map(fn(s) {
106+
next_set
107+
|> list.map(fn(n) { s <> n })
108+
})
109+
|> list.flatten
110+
})
111+
|> result.unwrap([])
87112
}
88113

89-
fn decode_directional_sequence(sequence: String) -> String {
90-
string.to_graphemes("A" <> sequence)
91-
|> list.window_by_2
92-
|> list.map(fn(pair) { find_motion_directional(pair.0, pair.1) })
93-
|> string.join("")
114+
fn decode_directional_sequence(sequences: List(String)) -> List(String) {
115+
sequences
116+
|> list.map(fn(sequence) {
117+
string.to_graphemes("A" <> sequence)
118+
|> list.window_by_2
119+
|> list.map(fn(pair) { find_motion_directional(pair.0, pair.1) })
120+
|> list.reduce(fn(solutions, next_set) {
121+
solutions
122+
|> list.map(fn(s) {
123+
next_set
124+
|> list.map(fn(n) { s <> n })
125+
})
126+
|> list.flatten
127+
})
128+
|> result.unwrap([])
129+
})
130+
|> list.flatten
94131
}
95132

96-
fn find_motion_directional(start: String, push: String) -> String {
133+
fn find_motion_directional(start: String, push: String) -> List(String) {
97134
let assert Ok(start_pos) = get_directional_position(start)
98135
let assert Ok(push_pos) = get_directional_position(push)
99136

@@ -106,23 +143,26 @@ fn find_motion_directional(start: String, push: String) -> String {
106143
order.Gt -> string.join(list.repeat("<", -right_count), "")
107144
}
108145

109-
case int.compare(start_pos.1, push_pos.1) {
110-
order.Lt -> {
111-
// Go up first then left or right
112-
horizontal <> string.join(list.repeat("^", up_count), "") <> "A"
113-
}
114-
order.Eq -> {
115-
// Go left or right
116-
horizontal <> "A"
117-
}
118-
order.Gt -> {
119-
// Go left or right first, then down
120-
string.join(list.repeat("v", -up_count), "") <> horizontal <> "A"
121-
}
146+
let vertical = case int.compare(start_pos.1, push_pos.1) {
147+
order.Lt -> string.join(list.repeat("^", up_count), "")
148+
order.Eq -> ""
149+
order.Gt -> string.join(list.repeat("v", -up_count), "")
150+
}
151+
152+
case start_pos, push_pos {
153+
#(_, 1), #(0, _) -> [vertical <> horizontal <> "A"]
154+
#(0, _), #(_, 1) -> [horizontal <> vertical <> "A"]
155+
_, _ ->
156+
case vertical, horizontal {
157+
"", "" -> ["A"]
158+
"", _ -> [horizontal <> "A"]
159+
_, "" -> [vertical <> "A"]
160+
_, _ -> [vertical <> horizontal <> "A", horizontal <> vertical <> "A"]
161+
}
122162
}
123163
}
124164

125-
fn find_motion_numeric(start: String, push: String) -> String {
165+
fn find_motion_numeric(start: String, push: String) -> List(String) {
126166
let assert Ok(start_pos) = get_numeric_position(start)
127167
let assert Ok(push_pos) = get_numeric_position(push)
128168

@@ -135,19 +175,22 @@ fn find_motion_numeric(start: String, push: String) -> String {
135175
order.Gt -> string.join(list.repeat("<", -right_count), "")
136176
}
137177

138-
case int.compare(start_pos.1, push_pos.1) {
139-
order.Lt -> {
140-
// Go up first then left or right
141-
string.join(list.repeat("^", up_count), "") <> horizontal <> "A"
142-
}
143-
order.Eq -> {
144-
// Go left or right
145-
horizontal <> "A"
146-
}
147-
order.Gt -> {
148-
// Go left or right first, then down
149-
horizontal <> string.join(list.repeat("v", -up_count), "") <> "A"
150-
}
178+
let vertical = case int.compare(start_pos.1, push_pos.1) {
179+
order.Lt -> string.join(list.repeat("^", up_count), "")
180+
order.Eq -> ""
181+
order.Gt -> string.join(list.repeat("v", -up_count), "")
182+
}
183+
184+
case start_pos, push_pos {
185+
#(_, 0), #(0, _) -> [vertical <> horizontal <> "A"]
186+
#(0, _), #(_, 0) -> [horizontal <> vertical <> "A"]
187+
_, _ ->
188+
case vertical, horizontal {
189+
"", "" -> ["A"]
190+
"", _ -> [horizontal <> "A"]
191+
_, "" -> [vertical <> "A"]
192+
_, _ -> [vertical <> horizontal <> "A", horizontal <> vertical <> "A"]
193+
}
151194
}
152195
}
153196

@@ -178,3 +221,9 @@ fn get_numeric_position(key: String) -> Result(Point, Nil) {
178221
_ -> Error(Nil)
179222
}
180223
}
224+
225+
fn get_numeric_portions(s: String) -> Int {
226+
string.drop_end(s, 1)
227+
|> int.parse
228+
|> result.unwrap(0)
229+
}

test/day21_test.gleam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const testinput = "029A
1111
pub fn part1_test() {
1212
let lines = string.split(testinput, "\n")
1313
solution.solve_p1(lines)
14-
|> should.equal(Ok(""))
14+
|> should.equal(Ok("126384"))
1515
}
1616

1717
pub fn part2_test() {

0 commit comments

Comments
 (0)