garnet/rust/puzzles/day1.rs

86 lines
2.1 KiB
Rust
Raw Normal View History

2025-12-09 19:17:25 +00:00
use crate::puzzle::Puzzle;
2025-12-10 12:39:12 +00:00
use nom::{
Parser,
branch::alt,
character::complete::{char, i32, newline},
combinator::{eof, value},
2025-12-10 12:39:12 +00:00
error::Error,
multi::separated_list1,
sequence::{pair, terminated},
};
2025-12-09 19:17:25 +00:00
pub const PUZZLE: Puzzle<Vec<(Direction, i32)>, 2> = Puzzle {
2025-12-09 19:17:25 +00:00
number: 1,
parser: |_, input| {
terminated::<_, _, Error<&str>, _, _>(
2025-12-10 12:39:12 +00:00
terminated(
separated_list1(
newline,
pair(
alt((
value(Direction::L, char('L')),
value(Direction::R, char('R')),
)),
i32,
2025-12-10 12:39:12 +00:00
),
),
newline,
),
eof,
)
.parse(input)
.unwrap()
.1
2025-12-09 19:17:25 +00:00
},
parts: [
|instructions| {
let mut p = 50;
let mut r = 0;
for (d, i) in instructions {
let (_, p1) = step(*i, *d, p);
if p1 == 0 {
r += 1;
}
p = p1;
}
r.to_string()
2025-12-09 19:17:25 +00:00
},
|instructions| {
let mut p = 50;
let mut r = 0;
for (d, i) in instructions {
let (c, p1) = step(*i, *d, p);
let c1 = match d {
Direction::R => c.abs(),
Direction::L => {
if p == 0 {
c.abs() - 1
} else if p1 == 0 {
c.abs() + 1
} else {
c.abs()
}
}
};
r += c1;
p = p1;
}
r.to_string()
2025-12-09 19:17:25 +00:00
},
],
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
L,
R,
}
fn step(i: i32, d: Direction, p: i32) -> (i32, i32) {
let p1 = match d {
Direction::L => p - i,
Direction::R => p + i,
};
(p1.div_euclid(100), p1.rem_euclid(100))
}