Skip to content

Commit f649299

Browse files
committed
all in Rust!
1 parent 58fa2fe commit f649299

File tree

6 files changed

+245
-35
lines changed

6 files changed

+245
-35
lines changed

2019/Cargo.toml

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,6 @@
11
# https://adventofcode.com/2019
22

33
[workspace]
4-
members = [
5-
"day1",
6-
"day2",
7-
"day3",
8-
"day4",
9-
"day5",
10-
"day6",
11-
"day7",
12-
"day8",
13-
"day9",
14-
"day10",
15-
"day11",
16-
"day12",
17-
"day13",
18-
"day14",
19-
"day15",
20-
"day16",
21-
"day17",
22-
"day18",
23-
"day19",
24-
"day20",
25-
"day21",
26-
"day22",
27-
"day23",
28-
"day24",
29-
"intcode-rs",
30-
]
4+
members = [ "day*", "intcode-rs" ]
315

326
resolver = "2"

2019/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![AoC2019](https://img.shields.io/badge/Advent_of_Code-2019-8A2BE2)
44
![Stars: 50](https://img.shields.io/badge/Stars-50⭐-blue)
5-
![Rust: 24](https://img.shields.io/badge/Rust-24-cyan?logo=Rust)
5+
![Rust: 25](https://img.shields.io/badge/Rust-25-cyan?logo=Rust)
66
![Python: 23](https://img.shields.io/badge/Python-23-cyan?logo=Python)
77

88
## 2019 ([Calendar](https://adventofcode.com/2019)) ([Solutions](../2019/)) : 50⭐
@@ -33,4 +33,4 @@ Puzzle
3333
[Day 22: Slam Shuffle](https://adventofcode.com/2019/day/22) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day22/day22.rs)
3434
[Day 23: Category Six](https://adventofcode.com/2019/day/23) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day23/day23.rs) [![Python](../scripts/assets/python.png)](../2019/day23/day23.py)
3535
[Day 24: Planet of Discord](https://adventofcode.com/2019/day/24) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day24/day24.rs) [![Python](../scripts/assets/python.png)](../2019/day24/day24.py)
36-
[Day 25: Cryostasis](https://adventofcode.com/2019/day/25) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day25/day25.py)
36+
[Day 25: Cryostasis](https://adventofcode.com/2019/day/25) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day25/day25.rs) [![Python](../scripts/assets/python.png)](../2019/day25/day25.py)

2019/day25/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "day25"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
aoc = { path = "../../aoc" }
8+
intcode = { path = "../intcode-rs" }
9+
regex = "1.11.1"
10+
11+
[[bin]]
12+
name = "day25"
13+
path = "day25.rs"

2019/day25/day25.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import argparse
55
import re
66
import sys
7+
import typing as t
78
from collections import defaultdict
89
from pathlib import Path
9-
import typing as t
1010

1111
sys.path.append(Path(__file__).parent.parent.as_posix())
1212
from intcode.Intcode import Computer # noqa
@@ -155,10 +155,10 @@ def solve(software):
155155
# find path to the detection room
156156
path = find_path(map, start_room, "Pressure-Sensitive Floor")
157157

158-
# the diretion to get to Security Checkpoint from Pressure-Sensitive Floor
158+
# the direction to get to Security Checkpoint from Pressure-Sensitive Floor
159159
checkpoint_dir = [k for k, v in map["Security Checkpoint"].items() if v == "Pressure-Sensitive Floor"][0]
160160

161-
# go to the pre
161+
# go to the Pressure-Sensitive Floor
162162
for step in path:
163163
run(computer, step)
164164

2019/day25/day25.rs

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
//! [Day 25: Cryostasis](https://adventofcode.com/2019/day/25)
2+
3+
use std::collections::{HashMap, HashSet};
4+
5+
use intcode::{Computer, State};
6+
7+
type Room = String;
8+
type Direction = String;
9+
type Map = HashMap<Room, HashMap<Direction, Room>>;
10+
11+
fn run(computer: &mut Computer, command: &str) -> String {
12+
computer.input_flush();
13+
14+
if !command.is_empty() {
15+
command.bytes().for_each(|byte| computer.push_byte(byte));
16+
computer.push_byte(b'\n');
17+
}
18+
19+
let mut output = String::new();
20+
for _ in 1..10000 {
21+
match computer.run() {
22+
State::Output(ch) => {
23+
output.push(char::from_u32(u32::try_from(ch).unwrap()).unwrap());
24+
}
25+
State::Halted | State::Input => return output,
26+
}
27+
}
28+
29+
String::new()
30+
}
31+
32+
fn parse(output: &str) -> (&str, Vec<&str>, Vec<&str>) {
33+
let mut dirs = Vec::new();
34+
let mut items = Vec::new();
35+
let mut room = "";
36+
37+
for line in output.lines() {
38+
if let Some(s) = line.strip_prefix("== ") {
39+
if let Some(s) = s.strip_suffix(" ==") {
40+
if room.is_empty() {
41+
room = s;
42+
}
43+
}
44+
}
45+
46+
if let Some(s) = line.strip_prefix("- ") {
47+
match s {
48+
"north" | "east" | "south" | "west" => dirs.push(s),
49+
_ => items.push(s),
50+
};
51+
}
52+
}
53+
54+
(room, dirs, items)
55+
}
56+
57+
fn reverse(direction: &str) -> &'static str {
58+
match direction {
59+
"north" => "south",
60+
"south" => "north",
61+
"east" => "west",
62+
"west" => "east",
63+
_ => "none",
64+
}
65+
}
66+
67+
fn explore(computer: &mut Computer, map: &mut Map, output: &str) {
68+
//
69+
70+
let (room, dirs, items) = parse(output);
71+
72+
for dir in &dirs {
73+
if map.contains_key(room) && map[room].contains_key(*dir) {
74+
continue;
75+
}
76+
77+
// go next room
78+
let output = run(computer, dir);
79+
80+
let (newroom, _, _) = parse(&output);
81+
let known = map.contains_key(newroom);
82+
83+
map.entry(room.to_string())
84+
.or_default()
85+
.insert((*dir).to_string(), newroom.to_string());
86+
map.entry(newroom.to_string())
87+
.or_default()
88+
.insert(reverse(dir).to_string(), room.to_string());
89+
90+
if output.contains("A loud") {
91+
continue;
92+
}
93+
94+
if !known {
95+
explore(computer, map, &output);
96+
}
97+
98+
run(computer, reverse(dir));
99+
}
100+
101+
for item in items {
102+
let mut temp_computer = computer.clone();
103+
104+
let command = format!("take {item}");
105+
106+
let output = run(&mut temp_computer, &command);
107+
if output.is_empty() {
108+
// stuck
109+
continue;
110+
}
111+
112+
let output = run(&mut temp_computer, "inv");
113+
if output.contains("Items in your inventory") {
114+
run(computer, &command);
115+
}
116+
}
117+
}
118+
119+
fn find_path<'a>(map: &'a Map, start: &str, target: &str) -> Vec<&'a str> {
120+
let mut seen = HashSet::new();
121+
122+
let mut stack = Vec::new();
123+
124+
stack.push((start, Vec::new()));
125+
126+
while let Some((current, path)) = stack.pop() {
127+
if current == target {
128+
return path;
129+
}
130+
131+
for (dir, cell) in &map[current] {
132+
if seen.insert(cell) {
133+
let mut new_path = path.clone();
134+
new_path.push(dir);
135+
stack.push((cell, new_path));
136+
}
137+
}
138+
}
139+
140+
Vec::new()
141+
}
142+
143+
fn find_weight(computer: &mut Computer, inventory: &[&str], checkpoint_dir: &str) -> u64 {
144+
let re = regex::Regex::new(
145+
r"You should be able to get in by typing (\d+) on the keypad at the main airlock.",
146+
)
147+
.unwrap();
148+
149+
let mut prev_code = 0i32;
150+
151+
for code in 0..(1 << inventory.len()) {
152+
let gray_code = code ^ (code >> 1);
153+
let diff = gray_code - prev_code;
154+
155+
if diff != 0 {
156+
let action = if diff > 0 { "drop" } else { "take" };
157+
158+
let mut diff = diff.abs();
159+
let mut item = 0;
160+
while diff & 1 == 0 {
161+
diff >>= 1;
162+
item += 1;
163+
}
164+
165+
let command = format!("{action} {}", inventory[item]);
166+
run(computer, &command);
167+
}
168+
169+
let output = run(computer, checkpoint_dir);
170+
171+
if let Some(caps) = re.captures(&output) {
172+
return caps[1].parse().unwrap();
173+
}
174+
175+
prev_code = gray_code;
176+
}
177+
178+
0
179+
}
180+
181+
fn solve(program: &str) -> u64 {
182+
let mut computer = Computer::load(program);
183+
184+
let mut map = HashMap::new();
185+
186+
let output = run(&mut computer, "");
187+
let (start_room, _, _) = parse(&output);
188+
189+
// visit all rooms and collect items
190+
explore(&mut computer, &mut map, &output);
191+
192+
// find path to the Pressure-Sensitive Floor
193+
let path = find_path(&map, start_room, "Pressure-Sensitive Floor");
194+
195+
// the direction to go to Security Checkpoint from Pressure-Sensitive Floor
196+
let checkpoint_dir = map["Security Checkpoint"]
197+
.iter()
198+
.filter(|(_, room)| room == &"Pressure-Sensitive Floor")
199+
.map(|(dir, _)| dir)
200+
.next()
201+
.unwrap();
202+
203+
// go to the Pressure-Sensitive Floor
204+
for step in path {
205+
run(&mut computer, step);
206+
}
207+
208+
// the inventory
209+
let inventory = run(&mut computer, "inv");
210+
let inventory = inventory
211+
.lines()
212+
.filter_map(|line| line.strip_prefix("- "))
213+
.collect::<Vec<&str>>();
214+
215+
// get the unlock code
216+
find_weight(&mut computer, &inventory, checkpoint_dir)
217+
}
218+
219+
fn main() {
220+
let args = aoc::parse_args();
221+
222+
println!("{}", solve(&args.input));
223+
}

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# [Advent of Code](https://adventofcode.com) in Rust 🦀
22

33
![Stars: 500](https://img.shields.io/badge/Stars-500⭐-blue)
4-
![Rust: 249](https://img.shields.io/badge/Rust-249-cyan?logo=Rust)
4+
![Rust: 250](https://img.shields.io/badge/Rust-250-cyan?logo=Rust)
55
![Python: 123](https://img.shields.io/badge/Python-123-cyan?logo=Python)
66

77
<img src="./scripts/assets/christmas_ferris_2015_2024.png" alt="Christmas Ferris" width="164" />
88

9-
Solutions of [Advent of Code](https://adventofcode.com/) in [Rust](https://www.rust-lang.org), and sometimes in [Python](https://www.python.org/) and other languages 🎄✨.
9+
*Complete* solutions of [Advent of Code](https://adventofcode.com/) in [Rust](https://www.rust-lang.org), and sometimes in [Python](https://www.python.org/) and other languages 🎄✨.
1010

1111
Made for fun 😎 and to practice Rust. Many thanks to [Eric Wastl](https://twitter.com/ericwastl).
1212

@@ -49,7 +49,7 @@ Calendar | Solutions | Stars | Rust | Python | 🎁
4949
[Advent of Code 2022](https://adventofcode.com/2022) | [Solutions](2022/README.md) | 50⭐ | 25 | 18 | 1
5050
[Advent of Code 2021](https://adventofcode.com/2021) | [Solutions](2021/README.md) | 50⭐ | 25 | 12 |
5151
[Advent of Code 2020](https://adventofcode.com/2020) | [Solutions](2020/README.md) | 50⭐ | 25 | 23 |
52-
[Advent of Code 2019](https://adventofcode.com/2019) | [Solutions](2019/README.md) | 50⭐ | 24 | 23 | 2
52+
[Advent of Code 2019](https://adventofcode.com/2019) | [Solutions](2019/README.md) | 50⭐ | 25 | 23 | 2
5353
[Advent of Code 2018](https://adventofcode.com/2018) | [Solutions](2018/README.md) | 50⭐ | 25 | 4 | 1
5454
[Advent of Code 2017](https://adventofcode.com/2017) | [Solutions](2017/README.md) | 50⭐ | 25 | 17 |
5555
[Advent of Code 2016](https://adventofcode.com/2016) | [Solutions](2016/README.md) | 50⭐ | 25 | 0 |

0 commit comments

Comments
 (0)