Compare commits

...

2 Commits

Author SHA1 Message Date
52e7bb9af7
day22: part 1 solution
Some checks failed
test / AoC 2024 (push) Failing after 4m11s
2024-12-21 21:16:04 -08:00
02fc154547
grid: use coord2d more consistently 2024-12-21 21:01:16 -08:00
7 changed files with 101 additions and 15 deletions

View File

@ -25,7 +25,7 @@ impl TrailMap {
.iter()
.enumerate()
.filter(|(_, v)| **v == b'0')
.map(|(i, _v)| self.map.coord(i as i64).unwrap())
.map(|(i, _v)| self.map.coord(i as i64).unwrap().into())
.collect_vec()
}
fn count_reachable_from(&self, pos: &(i64, i64), needle: u8, visited: &mut Grid<bool>) -> u64 {

View File

@ -1,5 +1,5 @@
use aoc_runner_derive::aoc;
use grid::Grid;
use grid::{Coord2d, Grid};
use std::{
cmp::Ordering,
collections::{BinaryHeap, HashMap},
@ -108,10 +108,10 @@ impl Maze {
})
}
fn dijkstra(&self) -> usize {
let (start_x, start_y) = self.map.find(&b'S').expect("can't find start");
let Coord2d {x: start_x, y: start_y} = self.map.find(&b'S').expect("can't find start");
let start = (start_x as CoordType, start_y as CoordType);
let (finish_x, finish_y) = self.map.find(&b'E').expect("can't find finish");
let Coord2d {x: finish_x, y: finish_y} = self.map.find(&b'E').expect("can't find finish");
let finish = (finish_x as CoordType, finish_y as CoordType);
let mut distances = HashMap::new();
@ -149,10 +149,11 @@ impl Maze {
usize::MAX
}
fn path_dijkstra(&mut self) -> (usize, Vec<Vec<Coord>>) {
let (start_x, start_y) = self.map.find(&b'S').expect("can't find start");
let start = (start_x.try_into().unwrap(), start_y.try_into().unwrap());
let (finish_x, finish_y) = self.map.find(&b'E').expect("can't find finish");
let finish = (finish_x.try_into().unwrap(), finish_y.try_into().unwrap());
let Coord2d {x: start_x, y: start_y} = self.map.find(&b'S').expect("can't find start");
let start = (start_x as CoordType, start_y as CoordType);
let Coord2d {x: finish_x, y: finish_y} = self.map.find(&b'E').expect("can't find finish");
let finish = (finish_x as CoordType, finish_y as CoordType);
let mut distances = HashMap::new();
let mut queue = BinaryHeap::with_capacity(self.map.data.len());

View File

@ -118,7 +118,7 @@ fn part1_impl(input: &str, cheat_min: usize) -> i64 {
let track = parse(input);
let start = track.map.find(&b'S').unwrap();
let goal = track.map.find(&b'E').unwrap();
let (best_path, costs) = track.path_costs(start, goal);
let (best_path, costs) = track.path_costs(start.into(), goal.into());
let cheats = track.find_cheats(&best_path, &costs, cheat_min);
cheats.len() as i64

64
src/day22.rs Normal file
View File

@ -0,0 +1,64 @@
use aoc_runner_derive::{aoc, aoc_generator};
fn evolve_secret(mut n: i64) -> i64 {
n = ((n * 64) ^ n) % 16777216;
n = ((n / 32) ^ n) % 16777216;
n = ((n * 2048) ^ n) % 16777216;
n
}
fn rounds(mut secret: i64, n: i64) -> i64 {
for _ in 0..n {
secret = evolve_secret(secret)
}
secret
}
fn parse(input: &str) -> Vec<i64> {
input.lines().map(|l| l.parse().unwrap()).collect()
}
#[aoc(day22, part1)]
fn part1(input: &str) -> i64 {
let secrets = parse(input);
secrets.iter().map(|s| rounds(*s, 2000)).sum::<i64>()
}
#[aoc(day22, part2)]
fn part2(input: &str) -> i64 {
todo!()
}
#[cfg(test)]
mod tests {
use super::*;
const EXAMPLE: &str = "1
10
100
2024";
#[test]
fn evolution() {
assert_eq!(evolve_secret(123), 15887950);
assert_eq!(evolve_secret(15887950), 16495136);
assert_eq!(evolve_secret(16495136), 527345);
}
#[test]
fn test_rounds() {
assert_eq!(rounds(1, 2000), 8685429);
assert_eq!(rounds(10, 2000), 4700978);
}
#[test]
fn part1_example() {
assert_eq!(part1(EXAMPLE),37327623);
}
#[test]
fn part2_example() {
assert_eq!(part2(EXAMPLE), 0);
}
}

View File

@ -104,7 +104,7 @@ impl<T: BufRead> From<T> for Map {
let guard_facing = FacingDirection::Up;
Self {
grid,
guard_pos,
guard_pos: guard_pos.into(),
guard_facing,
visited_from,
path: Vec::new(),

View File

@ -42,9 +42,9 @@ impl AntennaMap {
// permutations generates both pairs, ie. ((1,2),(2,1)) and ((2,1),(1,2)) so we don't need
// to consider the 'negative' side of the line, which will be generated by the other pair
let (a, b) = (pair[0], pair[1]);
let offset = (a.0 - b.0, a.1 - b.1);
let offset = (a.x - b.x, a.y - b.y);
for i in (start..).map_while(|i| if Some(i - start) != reps { Some(i as i64) } else { None }) {
let node_pos = (a.0 + i * offset.0, a.1 + i * offset.1);
let node_pos = (a.x + i * offset.0, a.y + i * offset.1);
if antinodes.set(&node_pos, true).is_none() {
// left the grid
break;

View File

@ -82,6 +82,12 @@ where
}
}
impl From<Coord2d> for (i64, i64) {
fn from(value: Coord2d) -> Self {
(value.x, value.y)
}
}
#[derive(Debug)]
pub struct GridRowIter<'a, T> {
iter: std::slice::Iter<'a, T>,
@ -164,13 +170,28 @@ impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
pub fn pos<C: AsCoord2d>(&self, c: &C) -> i64 {
c.y() * self.width + c.x()
}
pub fn coord(&self, pos: i64) -> Option<(i64, i64)> {
pub fn coord(&self, pos: i64) -> Option<Coord2d> {
if pos < 0 || pos >= self.data.len() as i64 {
None
} else {
Some((pos % self.width, pos / self.width))
Some(Coord2d {
x: pos % self.width,
y: pos / self.width,
})
}
}
// pub fn coord_iter(&self) -> CoordIter<_> {
// CoordIter { pos: 0, grid: self }
// }
pub fn is_valid<C: AsCoord2d>(&self, c: &C) -> bool {
if c.x() < 0 || c.x() >= self.width {
return false;
}
if c.y() < 0 || c.y() as usize >= self.height() {
return false;
}
return true;
}
fn valid_pos<C: AsCoord2d>(&self, c: &C) -> Option<usize> {
if c.x() < 0 || c.x() >= self.width {
return None;
@ -249,7 +270,7 @@ impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
}
}
pub fn find(&self, haystack: &T) -> Option<(i64, i64)> {
pub fn find(&self, haystack: &T) -> Option<Coord2d> {
self.coord(
self.data
.iter()