advent of code 2025
adventofcode.com/2025
aoc
rust
1#![allow(dead_code)]
2use anyhow::Context;
3const INPUT: &str = include_str!("input/1/actual.txt");
4
5pub fn main() -> anyhow::Result<()> {
6 let rotations = Rotation::parse_file(INPUT).context("parsing input")?;
7
8 let mut dial = Dial::new(50, true);
9
10 dial.apply_rotations(&rotations);
11
12 println!("{:?}", dial);
13
14 Ok(())
15}
16
17#[derive(Debug)]
18struct Dial {
19 value: i32,
20 times_left_at_zero: u32,
21 /// for extra challenge thing
22 extra_mode: bool,
23}
24
25impl Dial {
26 const SIZE: i32 = 100;
27
28 pub fn new(initial_value: i32, extra: bool) -> Dial {
29 Dial {
30 value: initial_value,
31 times_left_at_zero: 0,
32 extra_mode: extra,
33 }
34 }
35
36 pub fn apply_rotations(&mut self, rotations: &Vec<Rotation>) {
37 rotations.iter().for_each(|rotation| {
38 if self.extra_mode {
39 self.times_left_at_zero += self.hits_zero_during(rotation);
40 self.apply_rotation(rotation);
41 } else {
42 self.apply_rotation(rotation);
43 if self.value == 0 {
44 self.times_left_at_zero += 1;
45 }
46 }
47 });
48 }
49
50 fn apply_rotation(&mut self, rotation: &Rotation) {
51 match rotation.direction {
52 Direction::Left => self.value -= rotation.amount,
53 Direction::Right => self.value += rotation.amount,
54 }
55
56 self.value = self.value.rem_euclid(Self::SIZE);
57 }
58
59 fn hits_zero_during(&self, rotation: &Rotation) -> u32 {
60 if rotation.amount <= 0 {
61 return 0;
62 }
63
64 // how many steps until next hit 0
65 // this gave me a headache. boy do i suck at maths.
66 // this is my punishment for sleeping through every maths class in school.
67 let turns_needed = match rotation.direction {
68 Direction::Right => {
69 if self.value == 0 {
70 Self::SIZE
71 } else {
72 Self::SIZE - self.value
73 }
74 }
75 Direction::Left => {
76 if self.value == 0 {
77 Self::SIZE
78 } else {
79 self.value
80 }
81 }
82 };
83
84 if rotation.amount < turns_needed {
85 0
86 } else {
87 1 + ((rotation.amount - turns_needed) / Self::SIZE) as u32
88 }
89 }
90}
91
92#[derive(Debug, PartialEq, Eq)]
93enum Direction {
94 Left,
95 Right,
96}
97
98impl Direction {
99 pub fn parse(character: char) -> anyhow::Result<Direction> {
100 match character {
101 'L' => Ok(Self::Left),
102 'R' => Ok(Self::Right),
103 _ => Err(anyhow::anyhow!("unknown direction char '{}'", character)),
104 }
105 }
106}
107
108#[derive(Debug)]
109struct Rotation {
110 direction: Direction,
111 amount: i32,
112}
113
114impl Rotation {
115 pub fn parse_file(text: &str) -> anyhow::Result<Vec<Rotation>> {
116 text.lines().map(Rotation::parse).collect()
117 }
118
119 pub fn parse(line: &str) -> anyhow::Result<Rotation> {
120 let mut chars = line.chars();
121
122 let direction = Direction::parse(chars.next().context("popping first char")?)
123 .context("parsing direction")?;
124
125 let amount = chars
126 .collect::<String>()
127 .parse::<i32>()
128 .context("parsing remaining number")?;
129
130 Ok(Self { direction, amount })
131 }
132}