From f45b0891c1be11b89cb5321821a643d737a2f5ef Mon Sep 17 00:00:00 2001 From: Timothy Quilling Date: Tue, 2 Dec 2025 00:30:40 -0500 Subject: [PATCH] cleanup, comment --- README.md | 9 +++++++-- src/2025/day1/rust/common.rs | 31 ++++++++++++++----------------- src/2025/day1/rust/part_a.rs | 4 ++-- src/2025/day1/rust/part_b.rs | 2 +- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 7e12cf7..1d28fe5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Advent of Code -My solutions for Advent of Code in Typescript, Python, and Rust. +My solutions for Advent of Code in Rust, Typescript, and Python. -![image](https://github.com/Teqed/advent-of-code-2023/assets/5181964/a00fb449-1b3b-4e33-a999-6eef20c773f4) +For 2025 I'll mostly be focusing on Rust, unless I feel like trying out something new. + +I try to leave comments along the way to explain my reasoning, but if you have any questions feel free to ask me to elaborate on [Bluesky](https://bsky.app/profile/quilling.dev). +Jump straight to my 2025 Day 1 solution's [Dial struct here!](https://tangled.org/quilling.dev/advent-of-code/blob/main/src/2025/day1/rust/common.rs) Modulo arithmetic handles the dial rotation wraparound logic, and for the second part we just determine the magnitude of the rotation using division before applying it. + +![image](https://github.com/Teqed/advent-of-code-2023/assets/5181964/a00fb449-1b3b-4e33-a999-6eef20c773f4) diff --git a/src/2025/day1/rust/common.rs b/src/2025/day1/rust/common.rs index e445ebf..a9780fb 100644 --- a/src/2025/day1/rust/common.rs +++ b/src/2025/day1/rust/common.rs @@ -7,7 +7,7 @@ pub enum Direction { /// An instruction to rotate the dial. pub struct Instruction { pub direction: Direction, // L or R. - pub distance: i16, // How many clicks to rotate. + pub distance: u16, // How many clicks to rotate. } impl Instruction { /// Parse an instruction from a line of input (e.g. "L68" or "R48"). @@ -27,7 +27,7 @@ impl Instruction { /// A safe dial with positions 0-99 that wraps around. pub struct Dial { - pub position: i16, // Current position on the dial. + pub position: u16, // Current position on the dial. } impl Dial { /// Create a new dial starting at position 50. @@ -35,11 +35,14 @@ impl Dial { Self { position: 50 } } - /// Rotate the dial according to an instruction, wrapping around at 0/100. + /// Rotate the dial according to an instruction, wrapping around at 0/99 using modulo arithmetic. + /// + /// The remainder of the modulo operation is effectively, "what remains after subtracting 100 as many times as possible?" + /// This allows us to account for full rotations around the dial and determining what position we should have landed on. pub const fn rotate(&mut self, instruction: &Instruction) { self.position = match instruction.direction { - Direction::Left => (self.position - instruction.distance).rem_euclid(100), // Wrap around at 0. - Direction::Right => (self.position + instruction.distance).rem_euclid(100), // Wrap around at 100. + Direction::Left => (self.position + 100 - instruction.distance % 100) % 100, // For Left, add 100 before subtracting to avoid negative values. + Direction::Right => (self.position + instruction.distance) % 100, // For Right, simply wrap around at 100. }; } @@ -48,21 +51,15 @@ impl Dial { self.position == 0 } - /// Count how many times the dial passes through 0 during a rotation. - pub const fn count_zero_crossings(&self, instruction: &Instruction) -> i16 { + /// Count how many times the dial passes through 0 during a rotation using division. + pub const fn count_zero_crossings(&self, instruction: &Instruction) -> u16 { match instruction.direction { Direction::Left => { - let mut first_crossing = self.position; - if first_crossing == 0 { - first_crossing = 100; // If starting at 0, first crossing Left is after full rotation. - } - if instruction.distance < first_crossing { - 0 // Did not reach 0 during this rotation. - } else { - (instruction.distance - first_crossing) / 100 + 1 // Returns number of Left crossings. - } + let first_crossing = if self.position == 0 { 100 } else { self.position }; + if instruction.distance < first_crossing { 0 } // Distance too short to reach first crossing. + else { (instruction.distance - first_crossing) / 100 + 1 } // First crossing + additional full rotations. } - Direction::Right => (self.position + instruction.distance) / 100, // Returns number of Right crossings. + Direction::Right => (self.position + instruction.distance) / 100, // Count complete 100-step cycles. } } } diff --git a/src/2025/day1/rust/part_a.rs b/src/2025/day1/rust/part_a.rs index e82853d..a28bb92 100644 --- a/src/2025/day1/rust/part_a.rs +++ b/src/2025/day1/rust/part_a.rs @@ -1,13 +1,13 @@ use super::common::{Dial, Instruction}; /// Count how many times the dial is left pointing at 0 after each rotation. -pub fn part_a(input: &str) -> i16 { +pub fn part_a(input: &str) -> u16 { let mut dial = Dial::new(); // Dial starts at position 50. let mut count = 0; // Count times dial is left pointing at 0. for line in input.lines().filter(|l| !l.is_empty()) { let instruction = Instruction::parse(line); dial.rotate(&instruction); // Rotate the dial, first. - count += i16::from(dial.is_at_zero()); // Then increment count if at 0. + count += u16::from(dial.is_at_zero()); // Then increment count if at 0. } count // Return the count of times the dial pointed at 0. } diff --git a/src/2025/day1/rust/part_b.rs b/src/2025/day1/rust/part_b.rs index f08c923..6fc9077 100644 --- a/src/2025/day1/rust/part_b.rs +++ b/src/2025/day1/rust/part_b.rs @@ -1,7 +1,7 @@ use super::common::{Dial, Instruction}; /// Count how many times the dial passes through 0 during any rotation. -pub fn part_b(input: &str) -> i16 { +pub fn part_b(input: &str) -> u16 { let mut dial = Dial::new(); let mut count = 0; for line in input.lines().filter(|l| !l.is_empty()) { -- 2.51.2