Skip to content

Commit d3c697c

Browse files
committed
first attempt and my assumptions are wrong.
1 parent 709d54e commit d3c697c

File tree

3 files changed

+202
-1
lines changed

3 files changed

+202
-1
lines changed

inputs

src/day21/solution.gleam

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import gleam/int
2+
import gleam/io
3+
import gleam/list
4+
import gleam/order
5+
import gleam/string
6+
import internal/aoc_utils
7+
import internal/point.{type Point}
8+
9+
pub fn main() {
10+
let filename = "inputs/day21.txt"
11+
12+
let lines_result = aoc_utils.read_lines(from: filename)
13+
case lines_result {
14+
Ok(lines) -> {
15+
// If the file was converting into a list of lines
16+
// successfully then run each part of the problem
17+
aoc_utils.run_part_and_print("Part 1", fn() { solve_p1(lines) })
18+
aoc_utils.run_part_and_print("Part 2", fn() { solve_p2(lines) })
19+
}
20+
Error(_) -> io.println("Error reading file")
21+
}
22+
}
23+
24+
// +---+---+---+
25+
// | 7 | 8 | 9 |
26+
// +---+---+---+
27+
// | 4 | 5 | 6 |
28+
// +---+---+---+
29+
// | 1 | 2 | 3 |
30+
// +---+---+---+
31+
// | 0 | A |
32+
// +---+---+
33+
//
34+
// ^, >, <, v <- order for keypad
35+
//
36+
// +---+---+
37+
// | ^ | A |
38+
// +---+---+---+
39+
// | < | v | > |
40+
// +---+---+---+
41+
//
42+
// v, >, <, ^ <- order for directional keypad
43+
//
44+
// ^ -> <A>A
45+
// < -> v<<A>>^A
46+
// v -> v<A>^A
47+
// > -> vA^A
48+
49+
// 379A
50+
// ^A^^<<A>>AvvvA
51+
// 12345678 1 123456789 1 12345678
52+
// ^ A ^ ^ < < A > >A v vvA
53+
// < A > A < A A v < A A > >^ A v A A^ A v < A AA> ^ A
54+
// v<<A>>^AvA^A v<<A>>^A A v<A<A>>^A A vAA<^A>A v<A>^AA<A>Av<A<A>>^AAAvA<^A>A
55+
// <v<A>>^AvA^A <vA<AA>>^A A vA<^A>A A vA^A <vA>^AA<A>A<v<A>A>^AAAvA<^A>A
56+
// < A > A v < <A A > ^ A A > A v A A^ A < v A AA> ^ A
57+
// ^ A < < ^ ^ A > >A v vvA
58+
// 1234567890 1 1234567 1 1234
59+
// ^A<<^^A>>AvvvA
60+
61+
// Part 1
62+
pub fn solve_p1(lines: List(String)) -> Result(String, String) {
63+
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
72+
})
73+
74+
todo
75+
}
76+
77+
// Part 2
78+
pub fn solve_p2(lines: List(String)) -> Result(String, String) {
79+
Error("Unimplemented")
80+
}
81+
82+
fn decode_numeric_sequence(sequence: String) -> String {
83+
string.to_graphemes("A" <> sequence)
84+
|> list.window_by_2
85+
|> list.map(fn(pair) { find_motion_numeric(pair.0, pair.1) })
86+
|> string.join("")
87+
}
88+
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("")
94+
}
95+
96+
fn find_motion_directional(start: String, push: String) -> String {
97+
let assert Ok(start_pos) = get_directional_position(start)
98+
let assert Ok(push_pos) = get_directional_position(push)
99+
100+
let right_count = push_pos.0 - start_pos.0
101+
let up_count = push_pos.1 - start_pos.1
102+
103+
let horizontal = case int.compare(start_pos.0, push_pos.0) {
104+
order.Lt -> string.join(list.repeat(">", right_count), "")
105+
order.Eq -> ""
106+
order.Gt -> string.join(list.repeat("<", -right_count), "")
107+
}
108+
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+
}
122+
}
123+
}
124+
125+
fn find_motion_numeric(start: String, push: String) -> String {
126+
let assert Ok(start_pos) = get_numeric_position(start)
127+
let assert Ok(push_pos) = get_numeric_position(push)
128+
129+
let right_count = push_pos.0 - start_pos.0
130+
let up_count = push_pos.1 - start_pos.1
131+
132+
let horizontal = case int.compare(start_pos.0, push_pos.0) {
133+
order.Lt -> string.join(list.repeat(">", right_count), "")
134+
order.Eq -> ""
135+
order.Gt -> string.join(list.repeat("<", -right_count), "")
136+
}
137+
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+
}
151+
}
152+
}
153+
154+
fn get_directional_position(key: String) -> Result(Point, Nil) {
155+
case key {
156+
"^" -> Ok(#(1, 1))
157+
"A" -> Ok(#(2, 1))
158+
"<" -> Ok(#(0, 0))
159+
"v" -> Ok(#(1, 0))
160+
">" -> Ok(#(2, 0))
161+
_ -> Error(Nil)
162+
}
163+
}
164+
165+
fn get_numeric_position(key: String) -> Result(Point, Nil) {
166+
case key {
167+
"7" -> Ok(#(0, 3))
168+
"8" -> Ok(#(1, 3))
169+
"9" -> Ok(#(2, 3))
170+
"4" -> Ok(#(0, 2))
171+
"5" -> Ok(#(1, 2))
172+
"6" -> Ok(#(2, 2))
173+
"1" -> Ok(#(0, 1))
174+
"2" -> Ok(#(1, 1))
175+
"3" -> Ok(#(2, 1))
176+
"0" -> Ok(#(1, 0))
177+
"A" -> Ok(#(2, 0))
178+
_ -> Error(Nil)
179+
}
180+
}

test/day21_test.gleam

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import day21/solution
2+
import gleam/string
3+
import gleeunit/should
4+
5+
const testinput = "029A
6+
980A
7+
179A
8+
456A
9+
379A"
10+
11+
pub fn part1_test() {
12+
let lines = string.split(testinput, "\n")
13+
solution.solve_p1(lines)
14+
|> should.equal(Ok(""))
15+
}
16+
17+
pub fn part2_test() {
18+
let lines = string.split(testinput, "\n")
19+
solution.solve_p2(lines)
20+
|> should.equal(Ok(""))
21+
}

0 commit comments

Comments
 (0)