heh
| -rw-r--r-- | src/main.rs | 23 | ||||
| -rw-r--r-- | src/util.rs | 9 |
2 files changed, 23 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs index ea8f0d2..23f25a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ extern crate test; pub mod util; pub use util::prelude::*; +#[repr(u8)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)] enum D { N, @@ -26,8 +27,9 @@ enum D { W, } -macro_rules! sret { +macro_rules! csub { ($a:ident -= $b:expr) => { + // faster than a overflowing sub :/ $a = match $a.checked_sub($b) { Some(x) => x, None => break, @@ -40,13 +42,14 @@ const SZ: u8 = 110; fn test(mat: &[[u8; SZ as usize + 1]; SZ as usize], p: (u8, u8), d: D) -> u16 { use D::*; let mut e = vec![0u128; SZ.nat()]; - let mut been = HashSet::new(); + // *three dimensions* omg + let mut been = vec![[0; 110]; 110]; fn beam( mat: &[[u8; SZ as usize + 1]; SZ as usize], (mut x, mut y): (u8, u8), mut d: D, e: &mut [u128], - been: &mut HashSet<(u8, u8, D)>, + been: &mut [[u8; 110]], ) { loop { if y >= SZ || x >= SZ { @@ -56,7 +59,8 @@ fn test(mat: &[[u8; SZ as usize + 1]; SZ as usize], p: (u8, u8), d: D) -> u16 { let w = (mat[y.nat()][x.nat()], d); mat! { w { (b'|', E | W) => { - if been.insert((x, y, N)) { + if !bits!(been[x.nat()][y.nat()][d as u8]) { + bits!(been[x.nat()][y.nat()] + d as u8); if let Some(v) = y.checked_sub(1) { beam(mat, (x, v), N, e, been); } @@ -67,7 +71,8 @@ fn test(mat: &[[u8; SZ as usize + 1]; SZ as usize], p: (u8, u8), d: D) -> u16 { } }, (b'-', N | S) => { - if been.insert((x, y, N)) { + if !bits!(been[x.nat()][y.nat()][d as u8]) { + bits!(been[x.nat()][y.nat()] + d as u8); if let Some(v) = x.checked_sub(1) { beam(mat, (v, y), W, e, been); } @@ -77,21 +82,21 @@ fn test(mat: &[[u8; SZ as usize + 1]; SZ as usize], p: (u8, u8), d: D) -> u16 { return; } }, - (b'|' | b'.', N) => sret!(y -= 1), + (b'|' | b'.', N) => csub!(y -= 1), (b'-' | b'.', E) => x += 1, (b'|' | b'.', S) => y += 1, - (b'-' | b'.', W) => sret!(x -= 1), + (b'-' | b'.', W) => csub!(x -= 1), (b'/', N) | (b'\\', S) => { d = E; x += 1; }, (b'/', E) | (b'\\', W) => { d = N; - sret!(y -= 1); + csub!(y -= 1); }, (b'/', S) | (b'\\', N) => { d = W; - sret!(x -= 1); + csub!(x -= 1); }, (b'/', W) | (b'\\', E) => { d = S; diff --git a/src/util.rs b/src/util.rs index 91b9286..fbfbcee 100644 --- a/src/util.rs +++ b/src/util.rs @@ -635,6 +635,15 @@ macro_rules! bits { ($bitset:ident[$bit:expr]) => { ($bitset & 1 << $bit) != 0 }; + ($holder:ident[$index:expr][$bit:expr]) => { + ($holder[$index] & 1 << $bit) != 0 + }; + ($holder:ident[$index:expr][$index2:expr][$bit:expr]) => { + ($holder[$index][$index2] & 1 << $bit) != 0 + }; + ($holder:ident[$index:expr][$index2:expr] + $bit:expr) => { + $holder[$index][$index2] |= 1 << $bit + }; ($bitset:ident[$bit:expr] = $val:expr) => { $bitset = ($bitset & !(1 << $bit)) | (crate::util::cast_to($val, $bitset) << $bit) }; |