heh
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs70
1 files changed, 20 insertions, 50 deletions
diff --git a/src/main.rs b/src/main.rs
index 2d8ed86..0805fc9 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,57 +18,27 @@ extern crate test;
pub mod util;
pub use util::prelude::*;
-// const MUST: u8 = 3;
-// const NEEDS: u8 = 0;
-const MUST: u8 = 10;
-const NEEDS: u8 = 4;
-
-fn neighbor(
- (x, y, δx, δy, gone): (u8, u8, i8, i8, u8),
- v: &[[u8; 142]; 141],
-) -> impl Iterator<Item = ((u8, u8, i8, i8, u8), u16)> + '_ {
- [
- Dir::W + (x, y),
- Dir::E + (x, y),
- Dir::N + (x, y),
- Dir::S + (x, y),
- ]
- .into_iter()
- .flatten()
- .filter(|&(x, _)| x < 141)
- .filter(|&(_, y)| y < 141)
- .filter_map(move |(nx, ny)| {
- let go;
- let nδx = (nx as i16 - x as i16) as i8;
- let nδy = (ny as i16 - y as i16) as i8;
- if nδx == δx && nδy == δy {
- if gone == MUST {
- return None;
- }
- go = gone + 1;
- } else if (nδx == -δx && nδx != 0) || (nδy == -δy && nδy != 0) {
- return None;
- } else {
- if gone < NEEDS {
- return None;
- }
- go = 1;
- }
-
- Some((
- (nx, ny, nδx, nδy, go),
- (C! { v[ny as usize][nx as usize] } - b'0') as u16,
- ))
- })
-}
-
pub fn run(i: &str) -> impl Display {
- let v = unsafe { &*(i.as_bytes().as_ptr() as *const [[u8; 142]; 141]) };
- util::dijkstra(
- |n| neighbor(n, v),
- (0u8, 0u8, 0i8, 0i8, NEEDS),
- |(x, y, _, _, g)| x == 140 && y == 140 && g >= NEEDS,
- )
+ 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 (ox, oy) = (x, y);
+ for _ in 0..c {
+ (x, y) = match d {
+ // y down
+ Dir::N => (x, y + 1),
+ Dir::E => (x + 1, y),
+ Dir::S => (x, y - 1),
+ Dir::W => (x - 1, y),
+ };
+ }
+ (b + c as u16, 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)
}
fn main() {