Initial commit: day01 solved

This commit is contained in:
2025-12-02 00:48:11 -05:00
commit db47fe7947
7 changed files with 598 additions and 0 deletions

10
src/day01/input/test1.txt Normal file
View File

@@ -0,0 +1,10 @@
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82

142
src/day01/mod.rs Normal file
View File

@@ -0,0 +1,142 @@
use std::str::FromStr;
use color_eyre::{
Result,
eyre::{Error, eyre},
};
use tracing::{debug, info, instrument};
const INPUT: &str = include_str!("input/input.txt");
const LOCK_SIZE: i32 = 100;
const LOCK_STARTING_POSITION: i32 = 50;
#[derive(Debug)]
enum Direction {
Left,
Right,
}
impl FromStr for Direction {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s {
"L" => Ok(Direction::Left),
"R" => Ok(Direction::Right),
_ => Err(eyre!("Invalid direction")),
}
}
}
#[instrument(skip(input))]
fn part1(input: &str) -> Result<i32> {
let mut dial = LOCK_STARTING_POSITION;
let mut visited_zero_count = 0;
for line in input.trim().split('\n') {
let dir: &Direction = &line[0..1].parse()?;
let clicks: i32 = line[1..].parse()?;
match dir {
Direction::Left => {
debug!("Turn left {} clicks", clicks);
dial = (dial - clicks).rem_euclid(LOCK_SIZE);
debug!("Dial is now {}", dial);
}
Direction::Right => {
debug!("Turn right {} clicks", clicks);
dial = (dial + clicks).rem_euclid(LOCK_SIZE);
debug!("Dial is now {}", dial);
}
}
if dial == 0 {
visited_zero_count += 1;
debug!("Visited zero, count is now {}", visited_zero_count);
}
}
Ok(visited_zero_count)
}
#[instrument(skip(input))]
fn part2(input: &str) -> Result<i32> {
let mut dial = LOCK_STARTING_POSITION;
let mut visited_zero_count = 0;
for line in input.trim().split('\n') {
let dir: &Direction = &line[0..1].parse()?;
let clicks: i32 = line[1..].parse()?;
match dir {
Direction::Left => {
debug!("Turn left {} clicks", clicks);
let end = dial - clicks;
let passing_zero_count =
(dial - 1).div_euclid(LOCK_SIZE) - (end - 1).div_euclid(LOCK_SIZE);
if passing_zero_count > 0 {
visited_zero_count += passing_zero_count;
debug!(
"Passed zero {} times, count is now {}",
passing_zero_count, visited_zero_count
);
}
dial = end.rem_euclid(LOCK_SIZE);
debug!("Dial is now {}", dial);
}
Direction::Right => {
debug!("Turn right {} clicks", clicks);
let end = dial + clicks;
let passing_zero_count = end.div_euclid(LOCK_SIZE);
if passing_zero_count > 0 {
visited_zero_count += passing_zero_count;
debug!(
"Passed zero {} times, count is now {}",
passing_zero_count, visited_zero_count
);
}
dial = end.rem_euclid(LOCK_SIZE);
debug!("Dial is now {}", dial);
}
}
}
Ok(visited_zero_count)
}
pub fn solve() -> Result<()> {
info!("Day 1");
{
let _span = tracing::info_span!("day01").entered();
let p1 = part1(INPUT)?;
info!("Part 1: {}", p1);
let p2 = part2(INPUT)?;
info!("Part 2: {}", p2);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use test_log::test;
const TEST_INPUT1: &str = include_str!("input/test1.txt");
#[test]
fn test_parse_direction() {
let result = "L".parse::<Direction>();
assert!(matches!(result.unwrap(), Direction::Left));
}
#[test]
fn test_invalid_direction() {
let result = "U".parse::<Direction>();
let err = result.unwrap_err();
assert!(err.to_string().contains("Invalid direction"));
}
#[test]
fn test_part1() {
assert_eq!(part1(TEST_INPUT1).unwrap(), 3);
}
#[test]
fn test_part2() {
assert_eq!(part2(TEST_INPUT1).unwrap(), 6);
}
}

29
src/main.rs Normal file
View File

@@ -0,0 +1,29 @@
pub mod day01;
use color_eyre::Result;
use tracing::info;
use tracing_error::ErrorLayer;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::prelude::*;
fn main() -> Result<()> {
color_eyre::install()?;
tracing_subscriber::registry()
.with(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()))
.with(ErrorLayer::default())
.with(
tracing_subscriber::fmt::layer()
.with_line_number(true)
.with_span_events(FmtSpan::CLOSE),
)
.init();
info!("Advent of Code 2025");
{
let _span = tracing::info_span!("aoc").entered();
day01::solve()?;
}
Ok(())
}