heh
| -rw-r--r-- | src/main.rs | 50 | ||||
| -rw-r--r-- | src/util.rs | 32 |
2 files changed, 74 insertions, 8 deletions
diff --git a/src/main.rs b/src/main.rs index 0805fc9..fa3a6ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,13 +18,17 @@ extern crate test; pub mod util; pub use util::prelude::*; -pub fn run(i: &str) -> impl Display { +pub fn p1(i: &str) -> u32 { let mut x = 0i32; let mut y = 0i32; // boundary points, shoelace let (b, a) = i.行().fold((0, 0), |(b, a), i| { - let d = unsafe { std::mem::transmute::<u8, Dir>(i[0]) }; - let c = i.μ(' ').1.μ(' ').0.λ::<u8>(); + let d = unsafe { rint::<_, Dir>(C! { i[0] }) }; + let c = if C! { i[3] } == b' ' { + (C! { i[2] } - b'0') + } else { + (C! { i[2] } - b'0') * 10 + C! { i[3] } - b'0' + }; let (ox, oy) = (x, y); for _ in 0..c { (x, y) = match d { @@ -35,10 +39,46 @@ pub fn run(i: &str) -> impl Display { Dir::W => (x - 1, y), }; } - (b + c as u16, a + ((x + ox) * (y - oy))) + (b + c as u32, a + ((x + ox) * (y - oy))) }); // use shoelace formula to get the area, then use picks formula to count the number of inner points - ((a.abs() / 2) as u16) + (1 + b / 2) + ((a.abs() / 2) as u32) + (1 + b / 2) +} + +pub fn p2(i: &str) -> u64 { + let mut x = 0i32; + let mut y = 0i32; + let (b, a) = i.行().fold((0, 0), |(b, a), i| { + let dat = unsafe { + &*(if C! { i[3] } == b' ' { + C! { &i[6..] } + } else { + C! { &i[7..] } + } + .as_ptr() as *const [u8; 6]) + }; + let c = 読む::hex(&dat[0..5]).unwrap(); + let (ox, oy) = (x, y); + for _ in 0..c { + let d = 読む::hex_dig(dat[5]).unwrap(); + (x, y) = mat!(d { + 0 => (x + 1, y), + 1 => (x, y - 1), + 2 => (x - 1, y), + 3 => (x, y + 1), + }); + } + ( + b + c as u64, + a + ((x as i64 + ox as i64) * (y as i64 - oy as i64)), + ) + }); + + ((a.abs() / 2) as u64) + (1 + b / 2) +} + +pub fn run(i: &str) -> impl Display { + p1(i) } fn main() { diff --git a/src/util.rs b/src/util.rs index 778f0fa..f642d38 100644 --- a/src/util.rs +++ b/src/util.rs @@ -31,9 +31,18 @@ pub mod prelude { } macro_rules! C { - ($buf:ident[$n:expr]) => { - unsafe { *$buf.get_unchecked($n) } - }; + (&$buf:ident[$n:expr]) => {{ + #[allow(unused_unsafe)] + unsafe { + $buf.get_unchecked($n) + } + }}; + ($buf:ident[$n:expr]) => {{ + #[allow(unused_unsafe)] + unsafe { + *$buf.get_unchecked($n) + } + }}; ($buf:ident[$a:expr] = $rbuf:ident[$b:expr]) => { *unsafe { $buf.get_unchecked_mut($a) } = unsafe { *$rbuf.get_unchecked($b) } }; @@ -671,6 +680,23 @@ pub mod 読む { } } + pub fn hex_dig(b: u8) -> Result<u8, ()> { + match b { + b'0'..=b'9' => Ok(b as u8 - b'0' as u8), + b'a'..=b'f' => Ok(b as u8 - (b'a' as u8 - 10)), + _ => Err(()), + } + } + + pub fn hex(mut d: &[u8]) -> Result<u32, ()> { + let &b = d.take_first().ok_or(())?; + let mut num = hex_dig(b)? as u32; + while let Some(&b) = d.take_first() { + num = num * 16 + hex_dig(b)? as u32; + } + Ok(num) + } + pub fn 不全の(x: &mut &[u8]) -> u64 { let mut n = 0; loop { |