Skip to content

Commit 0ccf203

Browse files
committed
2025: Solution for Day 2, parts 1 & 2
1 parent 7cfb39e commit 0ccf203

File tree

10 files changed

+150
-274
lines changed

10 files changed

+150
-274
lines changed

2024/day17/src/main.rs

Lines changed: 0 additions & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -1,273 +0,0 @@
1-
//! Advent of Code 2024: Day 17
2-
//! https://adventofcode.com/2024/day/17
3-
4-
use std::{fs, io};
5-
use std::path::Path;
6-
7-
fn main() {
8-
//let input = Input::from_file(format!("{}/input.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
9-
let input = Input::from_file(format!("{}/example2.txt", env!("CARGO_MANIFEST_DIR"))).expect("failed to read input");
10-
11-
// Part 1
12-
println!("Part 1: {}", part1(&input));
13-
14-
// Part 2
15-
let p2 = part2(&input);
16-
assert_eq!(State::new([p2, 0, 0]).run(&input.program), input.program);
17-
//println!("Part 2: {}", part2(&input));
18-
}
19-
20-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
21-
enum Op {
22-
/// Division (output Register A)
23-
Adv,
24-
/// Bitwise XOR of Register B and literal
25-
Bxl,
26-
/// Combo
27-
Bst,
28-
/// Jump Non-Zero
29-
Jnz,
30-
/// Bitwise XOR of Register B and Register C
31-
Bxc,
32-
/// Output
33-
Out,
34-
/// Division (output Register B)
35-
Bdv,
36-
/// Division (output Register C)
37-
Cdv,
38-
}
39-
40-
impl TryFrom<usize> for Op {
41-
type Error = usize;
42-
43-
fn try_from(value: usize) -> Result<Self, Self::Error> {
44-
match value {
45-
0 => Ok(Self::Adv),
46-
1 => Ok(Self::Bxl),
47-
2 => Ok(Self::Bst),
48-
3 => Ok(Self::Jnz),
49-
4 => Ok(Self::Bxc),
50-
5 => Ok(Self::Out),
51-
6 => Ok(Self::Bdv),
52-
7 => Ok(Self::Cdv),
53-
opcode => Err(opcode)
54-
}
55-
}
56-
}
57-
58-
const BITMASK: usize = 0b111;
59-
60-
#[derive(Debug, Clone)]
61-
struct State {
62-
ip: usize,
63-
regs: [usize; 3],
64-
}
65-
66-
impl State {
67-
fn new(regs: [usize; 3]) -> Self {
68-
State {
69-
ip: 0,
70-
regs,
71-
}
72-
}
73-
74-
fn combo(&self, operand: usize) -> usize {
75-
match operand {
76-
0..=3 => operand,
77-
4 => self.regs[REG_A],
78-
5 => self.regs[REG_B],
79-
6 => self.regs[REG_C],
80-
_ => panic!("invalid combo operand: {operand}"),
81-
}
82-
}
83-
84-
fn run(&mut self, program: &[usize]) -> Vec<usize> {
85-
let mut ip = 0;
86-
let mut output = vec![];
87-
88-
while ip < program.len() {
89-
let op = Op::try_from(program[ip]).unwrap();
90-
let operand = program[ip + 1];
91-
ip += 2;
92-
93-
match op {
94-
Op::Adv => {
95-
self.regs[REG_A] = self.regs[REG_A] >> self.combo(operand);
96-
}
97-
Op::Bxl => {
98-
self.regs[REG_B] = self.regs[REG_B] ^ operand;
99-
}
100-
Op::Bst => {
101-
self.regs[REG_B] = self.combo(operand) & BITMASK;
102-
}
103-
Op::Jnz => {
104-
if self.regs[REG_A] != 0 {
105-
ip = operand;
106-
}
107-
}
108-
Op::Bxc => {
109-
self.regs[REG_B] = self.regs[REG_B] ^ self.regs[REG_C];
110-
}
111-
Op::Out => {
112-
output.push(self.combo(operand) & BITMASK);
113-
}
114-
Op::Bdv => {
115-
self.regs[REG_B] = self.regs[REG_A] >> self.combo(operand);
116-
}
117-
Op::Cdv => {
118-
self.regs[REG_C] = self.regs[REG_A] >> self.combo(operand);
119-
}
120-
}
121-
}
122-
123-
output
124-
}
125-
126-
fn run2(&mut self, program: &[usize]) -> usize {
127-
let mut acc = 0;
128-
129-
let mut z = 0;
130-
'outer: for x in program.iter().copied().rev() {
131-
println!("{x}: acc={acc}");
132-
133-
for n in 0..=0b1111111111 {
134-
self.regs = [acc << 6 | n, 0, 0];
135-
136-
let mut ip = 0;
137-
while ip < program.len() {
138-
let op = Op::try_from(program[ip]).unwrap();
139-
let operand = program[ip + 1];
140-
ip += 2;
141-
142-
match op {
143-
Op::Adv => {
144-
self.regs[REG_A] = self.regs[REG_A] >> self.combo(operand);
145-
}
146-
Op::Bxl => {
147-
self.regs[REG_B] = self.regs[REG_B] ^ operand;
148-
}
149-
Op::Bst => {
150-
self.regs[REG_B] = self.combo(operand) & BITMASK;
151-
}
152-
Op::Jnz => {
153-
if self.regs[REG_A] != 0 {
154-
ip = operand;
155-
}
156-
}
157-
Op::Bxc => {
158-
self.regs[REG_B] = self.regs[REG_B] ^ self.regs[REG_C];
159-
}
160-
Op::Out => {
161-
if self.combo(operand) & BITMASK == x {
162-
acc = (acc << 3) | (n >> 3);
163-
z += 1;
164-
if z == program.len() {
165-
acc = (acc << 3) | (n & 0b111);
166-
}
167-
continue 'outer;
168-
}
169-
}
170-
Op::Bdv => {
171-
self.regs[REG_B] = self.regs[REG_A] >> self.combo(operand);
172-
}
173-
Op::Cdv => {
174-
self.regs[REG_C] = self.regs[REG_A] >> self.combo(operand);
175-
}
176-
}
177-
178-
}
179-
}
180-
panic!();
181-
}
182-
183-
println!("acc = {acc}");
184-
acc
185-
}
186-
187-
fn combo2(&mut self, operand: usize, value: usize) {
188-
match operand {
189-
0 => assert_eq!(value, 0),
190-
1 => assert_eq!(value, 1),
191-
2 => assert_eq!(value, 2),
192-
3 => assert_eq!(value, 3),
193-
4 => self.regs[REG_A] = (self.regs[REG_A] & !0b111) | (value & 0b111),
194-
5 => self.regs[REG_B] = (self.regs[REG_B] & !0b111) | (value & 0b111),
195-
6 => self.regs[REG_C] = (self.regs[REG_C] & !0b111) | (value & 0b111),
196-
_ => panic!("unknown combo operand {operand}"),
197-
}
198-
}
199-
}
200-
201-
fn part1(input: &Input) -> String {
202-
let output = State::new(input.registers).run(&input.program);
203-
204-
let output: Vec<_> = output.into_iter().map(|x| x.to_string()).collect();
205-
206-
output.join(",")
207-
}
208-
209-
fn part2(input: &Input) -> usize {
210-
State::new(input.registers).run2(&input.program)
211-
}
212-
213-
const REG_A: usize = 0;
214-
const REG_B: usize = 1;
215-
const REG_C: usize = 2;
216-
217-
#[derive(Debug, Clone)]
218-
struct Input {
219-
registers: [usize; 3],
220-
program: Vec<usize>,
221-
}
222-
223-
impl Input {
224-
fn from_file(path: impl AsRef<Path>) -> io::Result<Self> {
225-
let input = fs::read_to_string(path)?;
226-
let (chunk1, chunk2) = input.split_once("\n\n").unwrap();
227-
228-
let mut registers = [0; 3];
229-
for (n, line) in chunk1.lines().enumerate() {
230-
let (_, value) = line.trim().split_once(": ").unwrap();
231-
registers[n] = value.parse().unwrap();
232-
}
233-
234-
let (_, program) = chunk2.split_once(": ").unwrap();
235-
let program = program.trim().split(',').map(|s| s.parse().unwrap()).collect();
236-
237-
Ok(Self { registers, program })
238-
}
239-
}
240-
241-
#[cfg(test)]
242-
mod test {
243-
use super::*;
244-
245-
#[test]
246-
fn test_part1() {
247-
let input = Input::from_file("example1.txt").unwrap();
248-
249-
assert_eq!(part1(&input), "4,6,3,5,6,3,5,2,1,0");
250-
}
251-
252-
#[test]
253-
fn test_part1_solution() {
254-
let input = Input::from_file("input.txt").unwrap();
255-
256-
assert_eq!(part1(&input), "5,1,3,4,3,7,2,1,7");
257-
}
258-
259-
#[test]
260-
fn test_part2() {
261-
let input = Input::from_file("example2.txt").unwrap();
262-
263-
assert_eq!(part2(&input), 117440);
264-
}
265-
266-
#[test]
267-
fn test_part2_solution() {
268-
let input = Input::from_file("input.txt").unwrap();
269-
270-
// Not 217269162253005
271-
assert_eq!(part2(&input), 0);
272-
}
273-
}

2024/day24/example1.txt

Whitespace-only changes.

2024/day24/example2.txt

Whitespace-only changes.

2025/Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

2025/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[workspace]
22
members = [
33
"day01",
4-
#"day02",
4+
"day02",
55
#"day03",
66
#"day04",
77
#"day05",

2025/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ cargo run --bin day01
1111
## Solutions
1212

1313
1. [Secret Entrance](day01) 🌟🌟
14+
2. [Gift Shop](day02) 🌟🌟

2025/day02/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "day02"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]

2025/day02/example1.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124

2025/day02/input.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
194-253,81430782-81451118,7709443-7841298,28377-38007,6841236050-6841305978,2222204551-2222236166,2623-4197,318169-385942,9827-16119,580816-616131,646982-683917,147-181,90-120,3545483464-3545590623,4304-5747,246071-314284,8484833630-8484865127,743942-795868,42-53,1435-2086,50480-60875,16232012-16441905,94275676-94433683,61509567-61686956,3872051-4002614,6918792899-6918944930,77312-106847,282-387,829099-1016957,288251787-288311732,6271381-6313272,9877430-10095488,59-87,161112-224439,851833788-851871307,6638265-6688423,434-624,1-20,26-40,6700-9791,990-1307,73673424-73819233

0 commit comments

Comments
 (0)