From 608c8fae924e7dd26eca33c68b508045792a0856 Mon Sep 17 00:00:00 2001 From: SOFe Date: Sun, 8 Dec 2024 12:42:17 +0800 Subject: [PATCH] d6q1 --- .github/workflows/bench.yml | 1 + input/d6.sample.input.txt | 10 +++++ src/all.rs | 7 +++ src/all/d5.rs | 1 - src/all/d6.rs | 89 +++++++++++++++++++++++++++++++++++++ src/util.rs | 23 ++++++++-- 6 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 input/d6.sample.input.txt create mode 100644 src/all/d6.rs diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 8de612f..ff18791 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -9,6 +9,7 @@ jobs: name: run benchmark runs-on: ubuntu-latest steps: + - run: sudo apt install valgrind - name: Check out base uses: actions/checkout@v4 - name: Install Rust diff --git a/input/d6.sample.input.txt b/input/d6.sample.input.txt new file mode 100644 index 0000000..a4eb402 --- /dev/null +++ b/input/d6.sample.input.txt @@ -0,0 +1,10 @@ +....#..... +.........# +.......... +..#....... +.......#.. +.......... +.#..^..... +........#. +#......... +......#... diff --git a/src/all.rs b/src/all.rs index bc9d4e6..81d793c 100644 --- a/src/all.rs +++ b/src/all.rs @@ -137,4 +137,11 @@ macros::all! { "btreemap-vec" => p1_btreemap_vec, } } + day 6 { + part 1 { + "ticked-fxhash-loc" => p1_ticked_fxhash_loc, + "ticked-fxhash-index" => p1_ticked_fxhash_index, + "ticked-bitvec" => p1_ticked_bitvec, + } + } } diff --git a/src/all/d5.rs b/src/all/d5.rs index aea705c..d603fa7 100644 --- a/src/all/d5.rs +++ b/src/all/d5.rs @@ -107,7 +107,6 @@ fn p1(input: Input) -> u32 } let mut result = 0; - let mut disallowed = DisallowedSetT::default(); 'update: for Update(items) in input.updates { diff --git a/src/all/d6.rs b/src/all/d6.rs new file mode 100644 index 0000000..06a5f28 --- /dev/null +++ b/src/all/d6.rs @@ -0,0 +1,89 @@ +use std::{collections::HashSet, hash::BuildHasher}; + +use bitvec::vec::BitVec; +use rustc_hash::FxHashSet; + +use crate::util::{DirectTaxicab, GridLoc, GridView}; + +trait Collector { + fn new(capacity: usize) -> Self; + fn insert(&mut self, loc: impl FnOnce() -> GridLoc, index: impl FnOnce() -> u32); + fn count(&self) -> u32; +} + +fn p1_ticked(input: String) -> u32 { + let grid = GridView::new(&input); + + let mut loc = grid.index_to_loc(input.find('^').unwrap()).unwrap(); + let mut direct = DirectTaxicab::Up; + + let mut collector = CollectorT::new(input.len()); + 'ticks: loop { + collector.insert(|| loc, || grid.loc_to_index(loc)); + + 'directs: loop { + match loc.direct(direct, grid) { + None => return collector.count(), // leave map + Some(new_loc) => { + match grid.get(new_loc).unwrap() { + b'^' | b'.' => { + loc = new_loc; + continue 'ticks + } + b'#' => { + direct = direct.clockwise(); + continue 'directs + } + _ => unreachable!(), + } + } + } + } + } +} + +impl Collector for HashSet { + fn new(capacity: usize) -> Self { + Self::with_capacity_and_hasher(capacity, S::default()) + } + + fn insert(&mut self, loc: impl FnOnce() -> GridLoc, _: impl FnOnce() -> u32) { + HashSet::insert(self, loc()); + } + + fn count(&self) -> u32 { + self.len() as u32 + } +} + +impl Collector for HashSet { + fn new(capacity: usize) -> Self { + Self::with_capacity_and_hasher(capacity, S::default()) + } + + fn insert(&mut self, _: impl FnOnce() -> GridLoc, index: impl FnOnce() -> u32) { + HashSet::insert(self, index()); + } + + fn count(&self) -> u32 { + self.len() as u32 + } +} + +impl Collector for BitVec { + fn new(capacity: usize) -> Self { + Self::repeat(false, capacity) + } + + fn insert(&mut self, _: impl FnOnce() -> GridLoc, index: impl FnOnce() -> u32) { + self.set(index() as usize, true); + } + + fn count(&self) -> u32 { + self.count_ones() as u32 + } +} + +pub fn p1_ticked_fxhash_loc(input: String) -> u32 { p1_ticked::>(input) } +pub fn p1_ticked_fxhash_index(input: String) -> u32 { p1_ticked::>(input) } +pub fn p1_ticked_bitvec(input: String) -> u32 { p1_ticked::(input) } diff --git a/src/util.rs b/src/util.rs index deacb05..c149b77 100644 --- a/src/util.rs +++ b/src/util.rs @@ -17,7 +17,11 @@ impl<'a> GridView<'a> { } pub fn get(&self, loc: GridLoc) -> Option { - self.input.get((loc.y * self.width + loc.x) as usize).copied() + self.input.get(self.loc_to_index(loc) as usize).copied() + } + + pub fn loc_to_index(&self, loc: GridLoc) -> u32 { + loc.y * self.width + loc.x } pub fn index_to_loc(&self, index: usize) -> Option { @@ -31,10 +35,10 @@ impl<'a> GridView<'a> { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct GridLoc { - x: u32, - y: u32, + pub x: u32, + pub y: u32, } impl GridLoc { @@ -91,6 +95,17 @@ pub enum DirectTaxicab { Down, } +impl DirectTaxicab { + pub fn clockwise(self) -> Self { + match self { + Self::Left => Self::Up, + Self::Up => Self::Right, + Self::Right => Self::Down, + Self::Down => Self::Left, + } + } +} + impl Direct for DirectTaxicab { const ALL: &[Self] = &[Self::Left, Self::Right, Self::Up, Self::Down];