From 0da49cd4dfe6f8b0cd380b669c514a892a3ff463 Mon Sep 17 00:00:00 2001 From: Ishan Jain Date: Sat, 16 Dec 2023 13:47:13 +0530 Subject: [PATCH] day16: added/optimized --- src/day16/1.rs | 154 ++++++++++++++++++++++++++++++++++- src/day16/2.rs | 188 ++++++++++++++++++++++++++++++++++++++++++- src/day16/input.txt | 110 +++++++++++++++++++++++++ src/day16/sample.txt | 10 +++ 4 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 src/day16/input.txt create mode 100644 src/day16/sample.txt diff --git a/src/day16/1.rs b/src/day16/1.rs index b51073e..7bd747a 100644 --- a/src/day16/1.rs +++ b/src/day16/1.rs @@ -1 +1,153 @@ -const INPUTS: [&'static str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")]; +#![feature(test)] +extern crate test; + +const INPUTS: [&[u8]; 2] = [ + include_bytes!("./sample.txt"), + include_bytes!("./input.txt"), +]; + +#[derive(Debug, Clone, Eq, PartialEq, Copy)] +enum Direction { + North = 0, + South = 1, + East = 2, + West = 3, +} + +fn process(data: &[u8]) -> usize { + let size = data.iter().filter(|&&x| x == b'\n').count(); + use Direction::*; + + solve(data, size as i32, (0, 0, East)) +} + +fn solve(grid: &[u8], size: i32, (sx, sy, dir): (i32, i32, Direction)) -> usize { + use Direction::*; + + let mut visited: BitSet<100> = BitSet::new(); + let mut seen: BitSet<400> = BitSet::new(); + + let mut stack = vec![]; + + stack.push((sx, sy, dir)); + + while let Some((sx, sy, dir)) = stack.pop() { + if sx < 0 || sy < 0 || sx >= size || sy >= size { + continue; + } + + if seen.get(size * size * dir as i32 + size * sx + sy) { + continue; + } else { + seen.set(size * size * dir as i32 + size * sx + sy); + } + + visited.set(sx * size + sy); + let c = grid[(sx * size + sy + sx) as usize]; + + let mut x = sx; + let mut y = sy; + + match (c, dir) { + (b'\\', East) => stack.push((x + 1, y, South)), + (b'\\', North) => stack.push((x, y - 1, West)), + (b'\\', West) => stack.push((x - 1, y, North)), + (b'\\', South) => stack.push((x, y + 1, East)), + (b'/', East) => stack.push((x - 1, y, North)), + (b'/', West) => stack.push((x + 1, y, South)), + (b'/', South) => stack.push((x, y - 1, West)), + (b'/', North) => stack.push((x, y + 1, East)), + (b'|', North) => stack.push((x - 1, y, dir)), + (b'|', South) => stack.push((x + 1, y, dir)), + (b'|', _) => { + stack.push((x - 1, y, North)); + stack.push((x + 1, y, South)); + } + (b'-', East) => stack.push((x, y + 1, dir)), + (b'-', West) => stack.push((x, y - 1, dir)), + (b'-', _) => { + stack.push((x, y + 1, East)); + stack.push((x, y - 1, West)); + } + (b'.', _) => { + let (r, s) = match dir { + North => (-1, 0), + South => (1, 0), + East => (0, 1), + West => (0, -1), + }; + + loop { + visited.set(x * size + y); + x += r; + y += s; + if x < 0 || y < 0 || x >= size || y >= size { + break; + } + let c = grid[(x * size + y + x) as usize]; + if c != b'.' { + break; + } + } + if !(x < 0 || y < 0 || x >= size || y >= size) { + stack.push((x, y, dir)); + } + } + + _ => unreachable!(), + } + } + + visited.count() +} + +struct BitSet { + bits: [u128; N], +} + +impl BitSet { + const fn new() -> Self { + Self { bits: [0; N] } + } + + #[inline] + fn set(&mut self, loc: i32) { + let idx = loc / 128; + let b_idx = loc & 127; + + self.bits[idx as usize] |= 1 << b_idx; + } + + #[inline] + const fn get(&self, loc: i32) -> bool { + let idx = loc / 128; + let b_idx = loc & 127; + + (self.bits[idx as usize] & (1 << b_idx)) > 0 + } + + const fn count(&self) -> usize { + let mut count = 0; + let mut i = 0; + while i < self.bits.len() * 128 { + count += self.get(i as i32) as usize; + i += 1; + } + + count + } +} + +fn main() { + for input in INPUTS.iter() { + println!("answer = {}", process(input)); + } +} + +#[bench] +fn part1(b: &mut test::Bencher) { + b.iter(|| { + let v = process(INPUTS[INPUTS.len() - 1]); + test::black_box(v); + }); +} diff --git a/src/day16/2.rs b/src/day16/2.rs index b51073e..c5bd488 100644 --- a/src/day16/2.rs +++ b/src/day16/2.rs @@ -1 +1,187 @@ -const INPUTS: [&'static str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")]; +#![feature(test)] +extern crate test; + +const INPUTS: [&[u8]; 2] = [ + include_bytes!("./sample.txt"), + include_bytes!("./input.txt"), +]; + +#[derive(Debug, Clone, Eq, PartialEq, Copy)] +enum Direction { + North = 0, + South = 1, + East = 2, + West = 3, +} + +fn process(data: &[u8]) -> usize { + let mut maximum = 0; + + let size = data.iter().filter(|&&x| x == b'\n').count(); + + use Direction::*; + let mut stack = vec![]; + + for j in 0..size { + let visited = solve(&mut stack, data, size as i32, (0, j as i32, South)); + maximum = std::cmp::max(maximum, visited); + + let visited = solve( + &mut stack, + data, + size as i32, + (size as i32 - 1, j as i32, North), + ); + maximum = std::cmp::max(maximum, visited); + } + + for i in 0..size { + let visited = solve(&mut stack, data, size as i32, (i as i32, 0, East)); + maximum = std::cmp::max(maximum, visited); + + let visited = solve( + &mut stack, + data, + size as i32, + (i as i32, size as i32 - 1, West), + ); + maximum = std::cmp::max(maximum, visited); + } + + maximum +} + +fn solve( + stack: &mut Vec<(i32, i32, Direction)>, + grid: &[u8], + size: i32, + (sx, sy, dir): (i32, i32, Direction), +) -> usize { + use Direction::*; + + let mut visited: BitSet<100> = BitSet::new(); + let mut seen: BitSet<400> = BitSet::new(); + + stack.push((sx, sy, dir)); + + while let Some((sx, sy, dir)) = stack.pop() { + if sx < 0 || sy < 0 || sx >= size || sy >= size { + continue; + } + + if seen.get(size * size * dir as i32 + size * sx + sy) { + continue; + } else { + seen.set(size * size * dir as i32 + size * sx + sy); + } + + visited.set(sx * size + sy); + let c = grid[(sx * size + sy + sx) as usize]; + + let mut x = sx; + let mut y = sy; + + match (c, dir) { + (b'\\', East) => stack.push((x + 1, y, South)), + (b'\\', North) => stack.push((x, y - 1, West)), + (b'\\', West) => stack.push((x - 1, y, North)), + (b'\\', South) => stack.push((x, y + 1, East)), + (b'/', East) => stack.push((x - 1, y, North)), + (b'/', West) => stack.push((x + 1, y, South)), + (b'/', South) => stack.push((x, y - 1, West)), + (b'/', North) => stack.push((x, y + 1, East)), + (b'|', North) => stack.push((x - 1, y, dir)), + (b'|', South) => stack.push((x + 1, y, dir)), + (b'|', _) => { + stack.push((x - 1, y, North)); + stack.push((x + 1, y, South)); + } + (b'-', East) => stack.push((x, y + 1, dir)), + (b'-', West) => stack.push((x, y - 1, dir)), + (b'-', _) => { + stack.push((x, y + 1, East)); + stack.push((x, y - 1, West)); + } + (b'.', _) => { + let (r, s) = match dir { + North => (-1, 0), + South => (1, 0), + East => (0, 1), + West => (0, -1), + }; + + loop { + visited.set(x * size + y); + x += r; + y += s; + if x < 0 || y < 0 || x >= size || y >= size { + break; + } + + let c = grid[(x * size + y + x) as usize]; + if c != b'.' { + break; + } + } + if !(x < 0 || y < 0 || x >= size || y >= size) { + stack.push((x, y, dir)); + } + } + + _ => unreachable!(), + } + } + + visited.count() +} + +struct BitSet { + bits: [u128; N], +} + +impl BitSet { + const fn new() -> Self { + Self { bits: [0; N] } + } + + #[inline] + fn set(&mut self, loc: i32) { + let idx = loc / 128; + let b_idx = loc & 127; + + self.bits[idx as usize] |= 1 << b_idx; + } + + #[inline] + const fn get(&self, loc: i32) -> bool { + let idx = loc / 128; + let b_idx = loc & 127; + + (self.bits[idx as usize] & (1 << b_idx)) > 0 + } + + const fn count(&self) -> usize { + let mut count = 0; + let mut i = 0; + while i < self.bits.len() * 128 { + count += self.get(i as i32) as usize; + i += 1; + } + + count + } +} + +fn main() { + for input in INPUTS.iter() { + println!("answer = {}", process(input)); + } +} + +#[bench] +fn part2(b: &mut test::Bencher) { + b.iter(|| { + let v = process(INPUTS[INPUTS.len() - 1]); + test::black_box(v); + }); +} diff --git a/src/day16/input.txt b/src/day16/input.txt new file mode 100644 index 0000000..666eb61 --- /dev/null +++ b/src/day16/input.txt @@ -0,0 +1,110 @@ +\..-.-..../.....|......\......................\............\.................|..............|........./.|..... +...-\...|............|......../.|........-../................|.-..............-....\.|..|..................... +.|..........\................\\|................../..........................\\../|...-...-.|..........\...... +..................|\....|.....-.......................-........\.............................|/............... +.......-...........-......................./........../.......-............................\.....-.....-.../.. +./.\...../....../..........\..............|............|....|........................\..../.../...|\.......... +..................................../...............................................\..................-.\.... +......../.........................|...............................|...............\|\........\....|....\...... +.--.........................../.../.......-.\........../.\.........|...............\..|.....\-.....\....||\... +......\............|......../..\................-..............\-..-...|\.../-............/.........|...\..... +.........|.........-.........|............/............-..............\../.......-.|\\..|......./............. +..........................\........|.....\...../..-......-............../.-|.............\.\...../.......\.... +.....\.................-........../........-....|.....-......|.....................................-......-\.. +......|\......................................./...../........|...|....../..................-....-.-..../..... +.../......\...|./|..........\.......-./..-../.................\.....\......../........./..|......-...|.../.... +--|................\.................|........../......\|......|.........................\.................... +......../...........|./............../.....-.....-......../.................................-.....-........... +........................-.../..../..\|..............................|\..|.|\................/........-...\...| +\.........-....../...|.\............./......\.......\..../....\|./-|.........|......-.......\............|.... +....|..........-.....|..../..........-/...-.............\..\...................\................|......|...... +............-..|...........-..../...-........../.../...-....-....../\..............|........\..............--. +.....\.../......|..-..............|..-........................|......|.......|.........\............/...\...-. +|....................-.........../.....-........\.../..........|.............................................. +..-.............|..../............|........................|..../.........................\..........-..-.../. +........-.|......\.........../................/..|..\................./.|....-................../...-......./. +\|..-.......\..............\.|/......-|.........../........../.-...............\....\....\..|..|.............. +..........|.........\............\\.../../|...........-................|....................|....|-\/\...\.... +.-........\............-.......\............-.............\.\......./...........././.|.\-...-.\./..........-/. +../.................-........//--...........|........./..../....|.....................................|....\.. +.............|....|........|........./.....\..../..-..................../........|.....././................... +......................-....\..........--.....\..\........../...........................--/.................... +.|.../.......-.......\.......|.............................-.............\..-.\../.......|............|......\ +...../.......-......|.............../.../...........................................|......-..........-....... +.............\............................................../......................\......../................. +|....................-...-\..................\................/.../........................................... +..|....-............/....................../......../...../......./.......\.-................/................ +.........../..-/...-...\..............-..../...............-|.........-............/........|.|.-...|...\..... +....../..-../.........-|...../...........................\..............-..................--...-............. +-.................-......../.....|....................\....................-../....................|./.....-.. +......./...\......../.|.|.........-.................................../....|.................................. +...|........\|\.........\...\...-......-...............................\.......//.|.....-.............../..... +........................../.|-...|....\..........\...................-..-............../............../....... +........../..-.......-....\.......\.............\.|................................|......../..............-.. +.......-................................-..................|../...\....................................-...... +...................................................................................../...\...................- +..\.-...................................|..............-.....|.........\..................../.........-....\.. +...................../\......-...........--.../............|...........|.....\....//.....-........./...-|..... +......||.........|.-.........................|.........|.||..-....-......|.................\.-../............. +...|.........|.......\....\................................../.................../....\................\...... +..................../|...............||.-/........|../..................................../.\......\...-...... +......./........./..-............................-.................\...|...............-................-..... +.............................--...-....\......................................|..........\...-......./........ +.......\...-.............../......\/.........................|........./..........|........................... +.........|.................................|.........../.|................................../...........-....| +...|...-...|...........................-....-.....................|../|........|...................../.....|.. +.......-.....-..................\.-........|...-..../........\.......................\......|..........-...... +|......................\..........-...............|........................../...........|.................... +................|....|..................-......-/.......-....|..\.../\.|.....-..../...................../.|..\ +............/........................../....-........-...............-...|...............|..\............./... +................./................\.............../...........\........\....../............\.....|........./.. +..\......./.-.....................-............-./......|..........-.............\..../....................... +/..../....-........\................................\....|.............../\-.............................-|... +................\..................\.--.|......//....|..|....|....../..................|.|...|....-|-......... +...................\............\....-............\...........................................-./............. +.........................\../............|..\.........../................/..../.............-................. +..-..\.........../............|..................................../............/.....-..............|.....|.. +..|/......\||.......\............/....|........|.-........./.............|.....................|./............ +..........-............../...........................................|.............|..-..../.|................ +..|.../..|......................./..-.-..............\../....................-..|............-...../.-........ +.-....../..............\..................\................./....-...\....\...-.....\.....-.-..............\./ +............./..../.\........-..\................................\....../.|.....|.......|.........|....\...... +.-.....\.-......-.|.-.........../..|...........\....................................\........|.//./.......-... +......-.......-/.........................-...../........|............./..................../............-..... +.............\....|......-../...........\...................../............................................... +../.......................................-...../.|..\......|...-......../....|./..........\.........|........ +....../.............\...................................\........\....-.........../..../..\..................| +.../...-.....-................/.........|....................|..............-.........\....................... +...................../..............-.......|......................./...|.....|../.|............../..........\ +.././....../........-........|.../.........../|..........|....../......-.....\.............................\.. +............|........|................/....\..............\............/.....\../..............|....../....... +|................\..../...........................|.......\......\.....\........../....../.................... +........./...-...\......./....................-...................................-............\........-..../ +............./............../.....................\.-..../.................\.........|.|............../.-...\\ +.........|......-\......\.................../..|.........|......\....\..-..\-................................. +...............|../.......................-.../......\......|||................|.............................. +.|...-............./...........-.......................|...............................|..............\....... +.|.............|.........................................-........|-.\.................-/.|................... +.|.......-||.........../..\....\.....................-....-....-.......-......-.........-|........|........... +.........\........-...|........../............/.................../......./........................-.......... +............\.........................../..\.......-............/.......................|.........\........... +..\..\............/..................../..............-....../|.../...................|............./..../.... +..\.\....\.../............/.../.........................../.-.......-.....\......|........|...../.........|.\| +.....-...........\..............-......-....-...../........-......|...../..\..|/........-............./.../... +.....\.......-........\...-.............................................|....||.........|...-......\.......... +............|......................../.....-........././..............................................\.....\. +.\.........\......../........................-.............|........\../.../...-......\................|.....- +....|................|/.....................\........|........................./|.....\...-../.|......../-.... +/..............-......-..............|..|.|.....................-\.|../...\..............................|.../ +....\/.........|\....-..............\......-.....................\............\........................\...... +......-...................\...............-/../........-.../....................\./..........-................ +..........................\.......|......\.|\....../......\......../........-/............................/.|. +.......-....\...................................../..............|../.......|......./..........|--.......-.... +...-...|.............................|........-.....-.|...........|.....|..............\..............-....... +-.\...........\......|.\.............................\...........|.........\.............../\................. +...../....................\../|...........................\.........|..................|........\.|..-../..... +.-....-../.................................\....../......|....../..............-...........-../...\.../....... +.\........-............................../..-...................|/..........|............................/.... +../|..........|.........../...-....../.....|.-./...\....-....\|.\.....|........./.-.....\.....|./........|.... +............\.....\...................-.\-.-\|...............................\...............\.....-.......... +...|................-......................\....|..\.-..........|............../.....-...................../.. diff --git a/src/day16/sample.txt b/src/day16/sample.txt new file mode 100644 index 0000000..d6805ce --- /dev/null +++ b/src/day16/sample.txt @@ -0,0 +1,10 @@ +.|...\.... +|.-.\..... +.....|-... +........|. +.......... +.........\ +..../.\\.. +.-.-/..|.. +.|....-|.\ +..//.|....