From 1b476265f3f6043529d252db5353c27ebd0507b3 Mon Sep 17 00:00:00 2001 From: Aria Shrimpton Date: Thu, 29 Feb 2024 16:10:26 +0000 Subject: rename benchmark stuff to be more consistent --- src/tests/Cargo.toml | 8 +- src/tests/aoc-2021-09/Cargo.toml | 17 - src/tests/aoc-2021-09/benches/main.rs | 31 - src/tests/aoc-2021-09/src/lib.rs | 270 ----- src/tests/aoc-2021-09/src/types.pr.rs | 8 - src/tests/aoc-2022-08/Cargo.toml | 17 - src/tests/aoc-2022-08/benches/main.rs | 31 - src/tests/aoc-2022-08/src/lib.rs | 288 ----- src/tests/aoc-2022-08/src/types.pr.rs | 3 - src/tests/aoc-2022-09/Cargo.toml | 17 - src/tests/aoc-2022-09/benches/main.rs | 31 - src/tests/aoc-2022-09/src/lib.rs | 2126 --------------------------------- src/tests/aoc-2022-09/src/types.pr.rs | 7 - src/tests/aoc-2022-14/Cargo.toml | 17 - src/tests/aoc-2022-14/benches/main.rs | 34 - src/tests/aoc-2022-14/src/lib.rs | 170 --- src/tests/aoc-2022-14/src/types.pr.rs | 12 - src/tests/aoc_2021_09/Cargo.toml | 17 + src/tests/aoc_2021_09/benches/main.rs | 39 + src/tests/aoc_2021_09/src/lib.rs | 270 +++++ src/tests/aoc_2021_09/src/types.pr.rs | 8 + src/tests/aoc_2022_08/Cargo.toml | 17 + src/tests/aoc_2022_08/benches/main.rs | 39 + src/tests/aoc_2022_08/src/lib.rs | 288 +++++ src/tests/aoc_2022_08/src/types.pr.rs | 3 + src/tests/aoc_2022_09/Cargo.toml | 17 + src/tests/aoc_2022_09/benches/main.rs | 39 + src/tests/aoc_2022_09/src/lib.rs | 2126 +++++++++++++++++++++++++++++++++ src/tests/aoc_2022_09/src/types.pr.rs | 7 + src/tests/aoc_2022_14/Cargo.toml | 17 + src/tests/aoc_2022_14/benches/main.rs | 34 + src/tests/aoc_2022_14/src/lib.rs | 170 +++ src/tests/aoc_2022_14/src/types.pr.rs | 12 + 33 files changed, 3107 insertions(+), 3083 deletions(-) delete mode 100644 src/tests/aoc-2021-09/Cargo.toml delete mode 100644 src/tests/aoc-2021-09/benches/main.rs delete mode 100644 src/tests/aoc-2021-09/src/lib.rs delete mode 100644 src/tests/aoc-2021-09/src/types.pr.rs delete mode 100644 src/tests/aoc-2022-08/Cargo.toml delete mode 100644 src/tests/aoc-2022-08/benches/main.rs delete mode 100644 src/tests/aoc-2022-08/src/lib.rs delete mode 100644 src/tests/aoc-2022-08/src/types.pr.rs delete mode 100644 src/tests/aoc-2022-09/Cargo.toml delete mode 100644 src/tests/aoc-2022-09/benches/main.rs delete mode 100644 src/tests/aoc-2022-09/src/lib.rs delete mode 100644 src/tests/aoc-2022-09/src/types.pr.rs delete mode 100644 src/tests/aoc-2022-14/Cargo.toml delete mode 100644 src/tests/aoc-2022-14/benches/main.rs delete mode 100644 src/tests/aoc-2022-14/src/lib.rs delete mode 100644 src/tests/aoc-2022-14/src/types.pr.rs create mode 100644 src/tests/aoc_2021_09/Cargo.toml create mode 100644 src/tests/aoc_2021_09/benches/main.rs create mode 100644 src/tests/aoc_2021_09/src/lib.rs create mode 100644 src/tests/aoc_2021_09/src/types.pr.rs create mode 100644 src/tests/aoc_2022_08/Cargo.toml create mode 100644 src/tests/aoc_2022_08/benches/main.rs create mode 100644 src/tests/aoc_2022_08/src/lib.rs create mode 100644 src/tests/aoc_2022_08/src/types.pr.rs create mode 100644 src/tests/aoc_2022_09/Cargo.toml create mode 100644 src/tests/aoc_2022_09/benches/main.rs create mode 100644 src/tests/aoc_2022_09/src/lib.rs create mode 100644 src/tests/aoc_2022_09/src/types.pr.rs create mode 100644 src/tests/aoc_2022_14/Cargo.toml create mode 100644 src/tests/aoc_2022_14/benches/main.rs create mode 100644 src/tests/aoc_2022_14/src/lib.rs create mode 100644 src/tests/aoc_2022_14/src/types.pr.rs (limited to 'src/tests') diff --git a/src/tests/Cargo.toml b/src/tests/Cargo.toml index de68bbe..85b4f1c 100644 --- a/src/tests/Cargo.toml +++ b/src/tests/Cargo.toml @@ -4,10 +4,10 @@ members = [ "example_sets", "example_stack", "example_mapping", - "aoc-2021-09", - "aoc-2022-08", - "aoc-2022-09", - "aoc-2022-14", + "aoc_2021_09", + "aoc_2022_08", + "aoc_2022_09", + "aoc_2022_14", "prime_sieve" ] diff --git a/src/tests/aoc-2021-09/Cargo.toml b/src/tests/aoc-2021-09/Cargo.toml deleted file mode 100644 index 49da8bb..0000000 --- a/src/tests/aoc-2021-09/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "aoc-2021-09" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = { workspace = true } -primrose-library = { path = "../../crates/library" } - -[dev-dependencies] -criterion = { workspace = true } - -[[bench]] -name = "main" -harness = false diff --git a/src/tests/aoc-2021-09/benches/main.rs b/src/tests/aoc-2021-09/benches/main.rs deleted file mode 100644 index c5a2037..0000000 --- a/src/tests/aoc-2021-09/benches/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -use aoc_2021_09::HeightMap; -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; -use rand::{rngs::StdRng, SeedableRng}; - -fn run_benches(c: &mut Criterion) { - let mut rng = StdRng::seed_from_u64(42); - for size in [100].iter() { - c.bench_with_input(BenchmarkId::new("aoc-202109-part1", size), size, |b, &n| { - b.iter_batched_ref( - || HeightMap::gen(&mut rng, n), - |map| map.part1(), - BatchSize::SmallInput, - ) - }); - - c.bench_with_input(BenchmarkId::new("aoc-202109-part2", size), size, |b, &n| { - b.iter_batched_ref( - || HeightMap::gen(&mut rng, n), - |map| map.part2(), - BatchSize::SmallInput, - ) - }); - } -} - -criterion_group!( - name = benches; - config = Criterion::default().sample_size(10); - targets = run_benches -); -criterion_main!(benches); diff --git a/src/tests/aoc-2021-09/src/lib.rs b/src/tests/aoc-2021-09/src/lib.rs deleted file mode 100644 index 9ada752..0000000 --- a/src/tests/aoc-2021-09/src/lib.rs +++ /dev/null @@ -1,270 +0,0 @@ -#![feature(type_alias_impl_trait)] - -use primrose_library::traits::*; -use rand::{rngs::StdRng, Rng}; -use std::collections::VecDeque; - -mod types; -use types::*; - -type Queue = VecDeque; // TODO: would be nice for this to be in primrose - -pub struct HeightMap { - map: Map<(usize, usize), usize>, - cols: usize, - rows: usize, -} - -impl HeightMap { - pub fn new(map: Map<(usize, usize), usize>, cols: usize, rows: usize) -> Self { - Self { map, cols, rows } - } - - pub fn gen(rng: &mut StdRng, n: usize) -> Self { - let mut map = Map::default(); - for x in 0..n { - for y in 0..n { - map.insert((x, y), rng.gen()); - } - } - - Self { - map, - cols: n, - rows: n, - } - } - - fn is_low_point(&self, x: usize, y: usize) -> bool { - [ - self.map.get(&(x + 1, y)), - self.map.get(&(x.overflowing_sub(1).0, y)), - self.map.get(&(x, y + 1)), - self.map.get(&(x, y.overflowing_sub(1).0)), - ] - .into_iter() - .flatten() - .all(|v| v > self.map.get(&(x, y)).unwrap()) - } - - fn risk_level(&self, x: usize, y: usize) -> usize { - self.map.get(&(x, y)).unwrap() + 1 - } - - pub fn part1(&self) -> usize { - let coords = (0..self.cols).flat_map(|x| (0..self.rows).map(move |y| (x, y))); - - coords - .filter(|(x, y)| self.is_low_point(*x, *y)) - .map(|(x, y)| self.risk_level(x, y)) - .sum::() - } - - fn basin_size(&self, x: usize, y: usize) -> usize { - let mut visited = Set::default(); - let mut queue = Queue::default(); - queue.push_back((x, y)); - - let mut size = 0; - while let Some((x, y)) = queue.pop_front() { - if !(0..self.cols).contains(&x) - || !(0..self.rows).contains(&y) - || visited.contains(&(x, y)) - { - continue; - } - - let val = self.map.get(&(x, y)).unwrap(); - if *val == 9 { - continue; - } - - size += 1; - visited.insert((x, y)); - for coord in [ - (x + 1, y), - (x.overflowing_sub(1).0, y), - (x, y + 1), - (x, y.overflowing_sub(1).0), - ] { - queue.push_back(coord) - } - } - - size - } - - pub fn part2(&self) -> usize { - let mut basins = (0..self.cols) - .flat_map(|x| (0..self.rows).map(move |y| (x, y))) - .filter(|(x, y)| self.is_low_point(*x, *y)) - .map(|(x, y)| self.basin_size(x, y)) - .collect::>(); - - basins.sort(); - basins.reverse(); - basins.iter().take(3).product() - } -} - -#[cfg(test)] -mod tests { - use crate::HeightMap; - - macro_rules! mkRow { - ($($v:expr) *) => {{ - let mut c = Vec::default(); - $(c.push($v);)* - c - }} - } - macro_rules! mkMap { - ($rows:expr, $cols:expr, $($r:expr),*) => {{ - let mut c = Vec::default(); - $( - let r = $r; - assert_eq!(r.len(), $cols); - c.push($r); - )* - assert_eq!(c.len(), $rows); - HeightMap::new( - c.into_iter().enumerate().flat_map(|(y, xs)| xs.into_iter().enumerate().map(move |(x, v)| ((x, y), v))).collect(), - $cols, - $rows - ) - }} - } - - #[test] - fn test_small() { - let map = small_input(); - - assert_eq!(map.part1(), 15); - assert_eq!(map.part2(), 1134); - } - - #[test] - fn test_large() { - let map = large_input(); - - assert_eq!(map.part1(), 560); - assert_eq!(map.part2(), 959136); - } - - fn small_input() -> HeightMap { - mkMap! { - 5, 10, - mkRow!{2 1 9 9 9 4 3 2 1 0}, - mkRow!{3 9 8 7 8 9 4 9 2 1}, - mkRow!{9 8 5 6 7 8 9 8 9 2}, - mkRow!{8 7 6 7 8 9 6 7 8 9}, - mkRow!{9 8 9 9 9 6 5 6 7 8} - } - } - - fn large_input() -> HeightMap { - mkMap! { - 100, 100, - mkRow!{9 7 5 6 7 8 9 5 4 5 9 8 7 6 5 2 3 4 5 8 9 1 0 1 2 3 6 7 8 9 9 9 8 9 9 9 1 3 5 9 9 9 9 8 6 6 4 3 5 9 7 4 3 2 1 9 2 1 2 3 4 9 8 9 9 9 4 3 4 6 6 7 9 8 9 8 7 9 9 9 9 8 7 6 5 4 9 8 7 6 5 4 3 5 6 9 7 6 5 4}, - mkRow!{6 5 4 5 8 9 8 9 5 9 8 7 6 5 4 1 2 3 6 7 8 9 2 4 5 4 5 8 9 8 9 8 7 8 9 8 9 4 9 8 9 8 7 6 5 4 3 2 3 9 6 5 6 3 9 8 9 2 9 4 9 8 7 8 9 8 9 1 3 4 5 6 9 6 5 6 6 7 8 9 9 7 6 5 4 3 4 9 9 7 9 8 5 6 7 8 9 5 4 3}, - mkRow!{5 4 3 4 5 6 7 8 9 9 7 6 5 4 3 0 4 4 5 6 7 8 9 9 7 9 6 9 8 7 6 5 6 9 8 7 8 9 8 7 6 9 9 5 4 3 2 1 9 8 9 6 7 9 8 7 8 9 8 9 4 3 6 5 6 7 8 9 4 5 6 9 8 7 4 4 5 6 7 9 9 8 7 6 5 1 3 4 5 9 8 7 6 7 8 9 9 4 3 2}, - mkRow!{6 5 4 5 6 7 8 9 3 2 9 8 4 3 2 1 2 6 7 7 8 9 7 8 9 8 9 1 9 9 7 6 7 8 9 6 7 8 9 6 5 9 8 7 5 9 9 0 9 7 8 9 9 8 7 6 7 6 7 8 9 2 3 4 7 8 9 6 5 9 9 8 7 6 3 2 4 5 6 7 8 9 6 5 4 3 5 6 7 8 9 8 7 8 9 7 8 9 2 1}, - mkRow!{7 6 5 7 7 8 9 7 9 3 9 6 5 4 3 2 4 5 7 8 9 4 6 9 8 7 9 0 1 9 8 9 8 9 4 5 6 7 8 9 4 7 9 8 9 8 8 9 8 6 6 7 8 9 6 5 5 5 6 7 8 9 4 5 6 7 8 9 7 8 9 9 7 5 4 3 8 6 7 8 9 8 7 8 5 4 6 7 8 9 3 9 8 9 5 6 7 8 9 2}, - mkRow!{9 8 6 9 8 9 5 6 7 9 8 7 6 5 6 6 5 6 8 9 2 3 9 8 7 6 8 9 2 4 9 9 9 2 3 6 5 8 9 2 3 5 7 9 8 7 6 7 6 5 5 7 8 9 9 4 3 4 5 6 7 8 9 6 9 8 9 9 8 9 9 8 7 6 5 6 7 8 9 9 3 9 9 9 6 5 7 9 9 3 2 1 9 3 4 5 6 9 4 3}, - mkRow!{4 9 8 9 9 5 4 2 3 4 9 8 9 8 7 8 6 7 9 0 1 9 8 7 6 5 7 8 9 9 8 9 9 1 2 3 4 5 9 5 4 5 6 7 9 6 5 4 3 4 3 4 6 7 8 9 2 3 6 7 8 9 9 9 8 9 8 7 9 9 9 9 8 7 8 9 8 9 9 1 2 3 9 8 7 9 8 9 5 2 1 0 1 2 3 9 7 8 9 4}, - mkRow!{3 4 9 6 5 4 3 1 2 9 9 9 8 9 8 8 7 8 9 3 2 9 8 7 6 4 3 9 9 7 7 7 8 9 3 4 5 7 8 9 5 9 7 9 8 7 6 3 2 1 2 9 7 8 9 2 1 2 3 4 9 9 9 8 7 8 9 6 9 8 9 8 9 8 9 7 9 7 8 9 9 4 5 9 8 9 9 5 4 3 2 4 2 6 7 8 9 9 6 5}, - mkRow!{2 1 2 9 6 9 2 0 9 8 9 8 7 5 9 9 9 9 8 9 9 8 7 6 5 3 2 9 8 6 5 6 7 8 9 6 8 9 9 7 6 7 8 9 9 8 5 4 9 0 9 8 9 9 4 3 2 3 5 6 7 9 8 7 6 7 8 9 8 7 6 7 8 9 7 6 6 6 5 9 8 9 6 8 9 8 7 6 5 4 3 5 3 4 9 9 9 8 7 6}, - mkRow!{3 0 9 8 9 8 9 9 8 7 5 9 5 4 3 4 5 6 7 8 9 9 8 7 6 4 3 4 9 7 4 5 6 7 8 9 9 3 9 8 7 8 9 9 8 7 6 9 8 9 8 7 8 9 6 4 3 4 9 8 9 8 9 6 5 5 7 9 9 6 5 6 7 8 9 5 4 3 4 8 7 8 9 9 9 9 8 7 8 5 4 5 4 5 6 7 8 9 9 8}, - mkRow!{5 9 8 7 6 7 8 9 7 6 4 3 4 3 2 3 5 6 8 9 6 7 9 8 6 5 4 9 8 6 5 6 7 8 9 4 3 2 3 9 8 9 2 0 9 8 9 8 7 6 7 6 9 8 7 9 7 6 8 9 8 7 6 5 3 4 6 7 9 9 6 7 8 9 9 4 3 2 3 4 6 9 4 3 9 9 9 8 9 6 6 6 5 6 7 9 9 1 0 9}, - mkRow!{9 8 7 6 5 6 7 8 9 7 3 2 1 0 1 2 6 7 8 9 5 7 7 9 7 6 5 6 9 7 6 8 9 9 6 5 5 3 9 9 9 8 9 9 9 9 8 7 6 5 4 5 8 9 8 9 8 7 9 7 9 9 4 3 2 3 5 6 7 8 9 8 9 9 8 6 5 5 4 5 6 8 9 9 8 9 9 9 9 8 7 7 6 7 9 8 8 9 1 2}, - mkRow!{9 9 6 5 4 7 8 9 8 9 4 3 2 3 2 4 5 8 9 3 4 5 6 9 8 8 9 8 9 8 9 9 3 8 9 6 6 9 8 9 9 7 8 8 9 9 9 8 9 6 5 6 7 8 9 3 9 9 8 6 5 4 3 2 1 3 3 7 8 8 9 9 3 2 9 7 6 7 6 6 8 9 9 8 7 8 9 4 3 9 8 9 7 9 8 7 7 8 9 4}, - mkRow!{9 8 5 4 3 6 5 6 7 9 6 4 5 4 6 5 6 7 8 9 5 6 7 8 9 9 9 9 9 9 0 1 2 7 8 9 9 8 7 9 8 6 7 7 8 9 1 9 9 9 8 7 8 9 1 2 4 5 9 9 8 9 4 3 0 1 2 4 5 6 7 8 9 1 9 8 7 8 7 9 9 8 6 5 6 7 8 9 2 3 9 9 9 8 6 5 6 7 8 9}, - mkRow!{8 7 4 3 2 3 4 5 6 8 9 5 6 9 7 7 8 9 9 7 6 7 9 9 8 7 8 8 9 5 4 3 5 6 9 9 8 7 6 5 9 4 5 6 9 1 0 1 9 9 9 8 9 4 3 3 5 6 9 8 7 8 7 5 1 2 3 8 6 9 8 9 1 0 1 9 8 9 9 8 7 6 5 4 5 6 7 8 9 4 5 9 8 7 5 4 5 6 8 9}, - mkRow!{7 6 5 4 5 6 5 6 9 9 9 6 7 9 8 9 9 9 8 9 7 8 9 8 7 6 8 7 8 9 5 9 6 8 9 9 8 9 5 4 3 2 3 9 8 9 1 9 8 7 8 9 6 5 9 7 6 7 9 9 6 5 4 3 2 3 4 7 8 9 9 9 9 9 9 9 9 3 9 8 6 7 6 3 4 5 6 9 9 9 9 8 7 6 4 3 4 7 9 9}, - mkRow!{8 7 6 5 7 7 6 7 8 9 8 7 8 9 9 8 7 6 7 9 9 9 0 9 6 5 5 6 9 9 9 8 9 9 9 8 7 6 4 3 2 1 9 8 7 8 9 8 7 6 9 8 7 9 8 9 9 9 8 9 8 8 6 5 3 4 5 6 7 9 9 8 7 8 8 9 1 2 9 9 5 4 3 2 3 4 5 6 7 8 9 9 8 7 5 4 5 9 8 9}, - mkRow!{9 8 7 8 9 8 7 8 9 5 9 8 9 9 8 7 6 5 6 7 8 9 1 9 5 3 4 8 9 8 6 7 8 9 3 9 8 7 6 4 3 2 9 7 6 7 9 7 6 5 4 9 9 8 7 8 7 6 7 9 9 8 7 6 4 5 6 7 8 9 9 9 6 6 7 8 9 9 8 7 6 5 4 3 4 6 6 7 8 9 6 9 8 7 6 5 9 9 7 8}, - mkRow!{4 9 8 9 2 9 8 9 3 4 5 9 9 9 9 9 7 3 2 6 7 8 9 8 9 1 9 9 8 7 5 9 9 5 4 9 9 8 7 5 4 9 8 6 5 6 8 9 6 5 3 9 8 7 6 5 4 5 6 8 9 9 9 8 7 6 7 9 9 9 9 5 4 5 6 7 8 9 9 8 7 8 5 4 5 7 8 9 9 4 5 6 9 9 7 9 8 7 6 7}, - mkRow!{3 4 9 4 3 4 9 2 1 0 2 9 8 7 9 7 6 5 3 5 6 7 9 6 7 9 8 8 9 5 4 8 9 6 9 8 9 9 7 6 9 8 7 6 4 5 6 8 9 3 2 1 9 8 7 4 3 6 5 7 8 9 9 9 8 9 8 9 9 9 8 9 3 4 5 6 8 9 9 9 8 9 8 7 6 8 9 3 4 3 4 9 2 3 9 8 9 8 5 6}, - mkRow!{4 5 9 9 9 5 9 9 2 1 2 9 8 5 9 8 7 8 7 6 7 9 4 5 9 9 7 6 5 4 3 7 8 9 9 7 8 9 9 9 8 7 6 4 3 4 5 8 9 2 1 0 9 7 6 5 2 3 4 5 9 8 9 9 9 9 9 9 7 6 7 4 2 3 4 7 9 7 8 9 9 2 9 8 7 9 4 2 1 2 9 8 9 9 8 7 6 4 3 2}, - mkRow!{5 9 8 7 8 9 7 8 9 3 9 8 7 3 2 9 8 9 8 7 9 6 5 6 7 9 8 7 6 6 5 6 7 9 5 6 7 9 9 9 6 5 4 3 2 3 5 6 8 9 2 9 8 9 7 7 3 5 5 9 8 7 8 9 9 9 8 7 6 5 4 3 1 2 3 4 5 6 7 8 9 3 9 9 9 8 9 1 0 9 8 7 8 9 7 6 5 4 2 1}, - mkRow!{9 9 9 6 4 5 6 7 8 9 8 7 6 5 3 4 9 9 9 8 9 7 6 9 8 9 9 8 9 8 7 7 8 9 4 5 9 8 9 8 7 2 1 0 1 2 4 7 8 9 9 8 7 8 9 8 9 6 6 9 8 6 7 8 9 9 9 9 7 6 2 1 0 1 2 3 4 5 6 9 9 9 8 9 8 7 8 9 9 9 7 6 5 9 8 7 5 4 3 2}, - mkRow!{8 9 6 5 3 4 7 8 9 9 9 8 9 6 7 6 7 9 9 9 9 8 9 9 9 2 3 9 8 9 8 8 9 1 2 9 8 7 6 5 4 3 2 1 5 3 4 5 9 9 8 7 6 7 8 9 8 7 9 6 6 5 3 9 9 8 7 8 9 4 3 2 3 2 3 4 5 6 7 8 9 6 7 8 9 6 7 9 8 9 8 5 4 5 9 8 7 6 4 4}, - mkRow!{7 9 9 6 7 5 6 7 8 9 4 9 9 8 9 7 9 8 9 9 8 9 9 8 7 5 4 6 7 8 9 9 2 0 9 8 9 8 7 8 5 4 3 2 6 4 5 6 7 8 9 6 5 6 9 9 9 9 8 5 4 3 2 4 4 5 6 7 8 9 5 3 4 3 4 5 6 7 8 9 6 5 3 9 4 5 9 8 7 6 5 4 3 4 6 9 8 7 5 6}, - mkRow!{6 7 8 9 7 6 7 8 9 2 3 4 9 9 8 9 8 7 8 9 7 5 5 9 9 7 6 7 8 9 6 4 3 9 8 7 6 9 8 9 7 6 5 3 4 5 6 8 8 9 2 3 4 7 8 9 9 9 7 8 4 2 1 3 3 4 5 6 7 8 9 4 6 4 5 6 7 9 9 8 7 6 2 1 3 4 5 9 8 7 6 7 2 3 4 5 9 8 8 7}, - mkRow!{5 6 7 8 9 7 8 9 2 1 2 9 8 9 7 6 5 6 7 8 9 4 4 0 9 8 9 8 9 8 9 5 9 8 7 6 5 6 9 9 9 8 7 6 5 6 7 8 9 2 1 2 5 9 9 9 8 7 6 5 2 1 0 1 2 3 4 7 8 9 9 8 7 5 6 7 8 9 9 7 6 4 3 0 2 3 9 8 7 8 5 4 1 2 3 4 5 9 9 8}, - mkRow!{4 4 4 9 8 9 9 9 1 0 9 8 7 6 6 5 4 5 6 7 9 3 2 1 9 9 7 9 8 7 8 9 9 7 9 5 4 5 6 9 9 9 8 9 8 7 8 9 7 4 2 3 6 8 9 9 9 8 5 4 3 2 1 2 3 4 5 8 9 6 5 9 9 8 7 8 9 9 9 5 4 3 2 1 3 9 8 7 6 5 4 3 2 4 4 5 6 7 8 9}, - mkRow!{3 2 3 9 7 8 9 8 9 9 8 7 6 5 3 4 3 6 7 8 9 4 9 9 8 7 6 4 7 6 9 8 8 6 7 4 3 4 6 7 8 9 9 4 9 8 9 8 6 5 6 4 7 9 9 9 8 7 6 5 6 4 2 3 4 5 6 7 8 9 4 4 5 9 8 9 3 9 8 7 6 5 4 5 4 9 9 9 7 8 5 4 5 7 5 6 7 8 9 9}, - mkRow!{4 5 9 8 5 6 6 7 9 8 9 5 4 3 2 1 2 5 6 7 8 9 8 6 9 8 4 3 4 5 9 7 6 5 4 3 2 3 5 6 9 7 4 3 2 9 2 9 9 8 7 5 6 7 8 9 9 8 7 6 7 6 3 4 5 6 7 9 9 5 2 3 4 7 9 9 2 0 9 8 7 6 5 7 9 8 7 9 8 7 6 5 6 9 6 7 8 9 9 8}, - mkRow!{5 9 8 6 4 5 4 6 7 7 8 9 4 3 1 0 3 4 5 8 9 8 9 5 4 9 9 4 5 6 9 8 7 4 3 2 1 6 7 8 9 6 5 4 1 0 1 2 3 9 8 6 7 8 9 4 6 9 8 7 8 7 4 7 6 7 9 6 5 4 3 4 5 6 7 8 9 9 9 9 9 7 6 7 9 8 6 5 9 8 7 6 8 9 7 8 9 8 7 7}, - mkRow!{6 7 9 7 3 2 3 4 7 6 9 8 9 3 2 1 2 3 8 9 9 7 8 9 9 9 8 9 6 8 9 9 8 7 4 3 4 5 8 9 6 5 4 3 2 1 2 4 4 5 9 7 8 9 3 3 4 2 9 8 9 6 5 6 7 8 9 7 6 5 4 6 7 8 8 9 9 8 9 9 9 8 9 8 9 9 9 6 8 9 8 9 9 9 8 9 8 7 5 6}, - mkRow!{8 9 8 3 2 1 2 3 4 5 6 7 8 9 3 2 3 4 6 9 8 6 9 9 7 8 7 9 9 9 9 8 7 6 5 6 5 6 9 8 7 6 5 4 3 4 4 5 6 7 9 8 9 3 2 1 0 1 2 9 8 9 7 7 8 9 9 8 7 6 9 8 8 9 9 9 8 7 8 9 9 9 9 9 3 9 8 7 9 1 9 9 9 9 9 5 9 8 4 3}, - mkRow!{9 9 7 5 9 0 3 5 5 9 7 8 9 9 9 4 5 6 9 9 7 5 9 8 6 5 6 7 8 9 6 9 8 7 6 7 7 8 9 9 8 7 6 5 4 5 5 8 7 8 9 9 6 5 3 2 1 4 3 9 7 9 8 9 9 8 9 9 8 9 8 9 9 0 1 9 7 6 7 8 9 8 9 1 2 3 9 8 9 0 9 8 9 8 9 4 3 2 3 2}, - mkRow!{4 5 9 9 8 9 9 6 7 8 9 9 9 9 8 9 7 9 8 7 5 4 5 7 8 4 5 6 9 5 5 6 9 8 9 8 8 9 2 3 9 9 7 6 5 8 6 9 8 9 9 8 7 9 4 3 2 9 9 7 6 5 9 5 6 7 8 9 9 8 7 8 9 1 2 9 6 5 4 5 6 7 8 9 3 4 5 9 9 9 8 7 6 7 8 9 2 1 0 1}, - mkRow!{5 9 8 7 7 8 8 9 8 9 9 9 9 8 7 8 9 9 8 5 4 3 4 6 2 3 4 9 5 4 3 4 5 9 8 9 9 0 1 9 8 9 8 7 7 9 7 8 9 9 8 9 9 8 9 4 9 8 7 6 5 4 3 4 5 6 9 9 8 7 6 7 9 3 9 8 7 4 3 9 7 9 9 9 9 7 6 7 8 9 7 6 5 5 5 8 9 3 1 2}, - mkRow!{9 8 7 6 5 6 7 8 9 9 8 9 8 7 6 7 9 8 7 6 6 2 1 0 1 2 6 8 9 4 2 3 9 8 7 8 9 2 9 8 6 2 9 9 8 9 8 9 9 8 7 7 5 6 8 9 9 8 7 5 5 3 2 3 4 9 8 6 5 6 5 6 8 9 9 9 9 9 9 8 9 0 1 9 8 9 7 8 9 9 8 5 4 3 4 7 8 9 2 3}, - mkRow!{9 8 9 5 4 5 6 7 9 8 7 8 6 5 4 5 6 9 8 7 7 8 2 3 2 3 5 8 9 3 1 9 8 7 6 9 9 4 9 7 5 4 5 6 9 9 9 9 9 8 6 5 4 5 6 9 7 7 6 4 4 2 1 2 9 8 7 5 4 5 4 5 7 8 8 9 8 7 8 7 8 9 9 8 7 8 9 9 9 8 7 6 3 2 7 6 7 8 9 4}, - mkRow!{8 7 5 4 2 3 4 5 9 6 5 6 5 4 3 4 7 9 7 6 5 4 3 4 5 6 6 7 8 9 9 8 7 6 5 6 8 9 8 7 6 7 6 7 8 9 9 8 8 7 8 4 3 4 5 9 6 5 4 3 2 1 0 9 8 7 6 5 3 2 3 4 5 6 7 8 9 6 5 6 7 8 9 7 6 7 8 9 8 7 6 5 2 1 2 5 6 7 8 9}, - mkRow!{9 7 6 4 3 4 5 7 8 9 4 3 2 1 2 3 4 5 9 7 6 5 4 5 6 7 7 9 9 9 9 8 7 5 4 5 7 8 9 8 7 8 9 9 9 9 8 7 9 6 5 1 2 9 9 8 7 9 6 4 5 2 1 3 9 8 9 9 2 1 2 3 7 8 9 9 2 3 4 5 6 9 8 9 5 7 8 9 7 6 5 4 3 0 1 3 8 8 9 4}, - mkRow!{9 8 6 5 7 5 6 8 9 6 5 4 3 0 1 6 5 6 9 8 7 6 7 6 7 8 9 3 4 9 8 7 6 6 3 4 6 7 8 9 8 9 4 3 4 5 9 6 5 4 3 2 9 8 9 9 9 8 7 5 9 3 2 4 5 9 9 8 2 0 1 2 6 9 2 1 0 1 2 3 7 9 7 8 4 6 9 8 6 5 4 3 2 1 2 3 9 9 9 5}, - mkRow!{2 9 7 6 7 8 7 9 9 8 6 5 2 1 2 7 6 7 8 9 8 8 8 7 8 9 3 2 3 9 8 7 5 4 2 3 7 8 9 9 9 5 3 2 3 9 8 7 6 5 4 4 9 7 9 3 2 9 8 7 8 4 3 5 7 9 8 7 6 2 2 4 5 9 3 3 1 2 6 4 9 8 6 5 3 7 8 9 7 8 5 4 3 4 3 4 6 7 8 9}, - mkRow!{1 2 9 7 8 9 8 9 9 9 7 6 3 3 4 6 7 8 9 3 9 9 9 8 9 9 0 1 2 4 9 8 3 2 1 2 6 9 8 9 7 6 2 1 2 3 9 8 7 9 5 9 8 6 8 9 1 0 9 8 7 6 5 6 7 8 9 9 5 4 3 4 9 8 9 4 5 9 8 9 8 9 7 6 2 2 3 9 8 9 6 5 6 5 6 5 6 9 9 4}, - mkRow!{0 1 2 9 9 6 9 8 9 9 8 7 4 5 5 7 8 9 5 2 1 2 9 9 9 8 9 9 4 9 8 7 4 4 3 3 5 6 7 8 9 2 1 0 1 4 5 9 9 8 9 8 9 5 7 8 9 1 2 9 8 7 6 7 9 9 8 7 6 6 4 9 8 7 8 9 6 7 9 8 7 6 5 1 0 1 4 7 9 9 7 6 7 7 8 7 8 9 2 3}, - mkRow!{1 9 9 8 6 5 4 6 9 8 9 8 6 6 6 7 8 9 4 3 2 9 8 9 6 7 8 8 9 8 7 6 5 6 5 6 7 8 9 9 4 3 2 3 4 5 6 9 8 7 6 7 5 4 5 7 9 2 9 9 9 8 7 8 9 8 9 8 7 8 9 8 7 6 9 8 9 8 9 9 8 9 3 2 4 2 3 5 6 9 8 9 8 8 9 8 9 2 1 2}, - mkRow!{9 8 8 7 6 4 3 5 6 7 8 9 8 9 8 9 9 6 5 5 9 8 7 6 5 6 7 7 5 9 8 7 6 7 7 7 9 9 8 8 9 4 3 4 5 6 7 9 6 6 5 3 4 3 8 6 8 9 8 7 9 9 8 9 6 7 8 9 8 9 8 7 6 5 6 7 8 9 1 0 9 8 9 4 5 3 5 6 7 8 9 7 9 9 9 9 9 9 0 9}, - mkRow!{8 7 9 8 4 3 2 3 4 5 9 9 9 2 9 8 9 7 8 9 8 7 6 5 4 3 5 6 4 5 9 8 7 8 9 8 9 7 6 7 8 9 4 6 7 7 9 8 5 4 3 2 1 2 3 5 7 8 9 6 8 9 9 4 5 6 8 9 9 8 7 9 7 4 5 6 9 9 2 9 8 7 8 9 7 4 5 9 8 9 5 6 7 8 9 9 9 8 9 8}, - mkRow!{9 6 5 4 3 2 1 4 5 6 8 9 0 1 9 7 8 9 9 0 9 7 5 6 3 2 3 4 3 4 6 9 8 9 9 9 5 4 5 6 7 9 5 9 8 9 8 7 7 3 2 1 0 1 7 6 7 9 3 5 6 7 9 5 6 7 9 9 9 9 6 5 6 3 5 6 7 8 9 8 7 6 7 8 9 5 6 7 9 5 4 5 6 7 8 9 8 7 6 7}, - mkRow!{8 7 6 5 4 3 0 1 2 7 7 8 9 9 8 6 7 9 2 1 9 8 4 3 2 1 0 1 2 4 5 6 9 9 8 7 6 3 4 5 8 9 9 8 9 8 7 6 5 4 3 2 1 2 8 7 9 3 2 4 5 7 8 9 9 8 9 9 8 7 9 4 3 2 3 7 9 9 8 7 6 5 6 9 8 9 7 8 9 9 3 4 9 8 9 8 7 5 4 5}, - mkRow!{9 8 7 6 5 4 1 2 3 5 6 9 9 9 7 5 6 7 9 2 3 9 9 8 3 4 3 2 3 6 7 8 9 8 7 6 5 4 5 6 9 8 7 6 5 9 8 7 6 5 4 3 2 3 4 8 9 2 1 2 5 9 8 9 9 9 9 9 8 6 5 4 2 1 2 6 7 8 9 6 5 4 5 6 7 8 9 9 6 8 9 9 9 9 8 9 6 5 3 6}, - mkRow!{2 9 8 7 6 7 8 3 4 6 9 8 8 8 5 4 5 6 8 9 4 9 8 7 6 5 4 3 4 7 8 9 4 9 8 7 6 5 9 7 9 9 8 7 6 7 9 8 7 6 5 4 3 5 6 9 4 3 0 1 4 5 7 9 9 8 9 8 7 6 5 3 1 0 4 5 8 9 7 5 4 3 4 5 6 9 1 2 5 6 7 8 9 8 7 8 9 7 4 7}, - mkRow!{1 2 9 8 8 9 8 7 6 9 8 7 6 7 4 3 4 5 7 8 9 9 9 8 7 6 5 4 5 7 9 1 3 4 9 8 7 6 7 8 9 3 9 8 9 8 9 9 8 7 6 5 4 6 7 8 9 7 1 2 3 4 6 8 9 6 7 9 8 7 4 3 2 2 3 6 9 8 6 4 2 1 2 5 7 8 9 3 4 7 8 9 6 7 6 7 8 9 5 8}, - mkRow!{0 1 9 9 9 5 9 8 9 9 7 6 5 3 2 2 3 4 6 7 8 9 7 9 9 8 6 7 8 9 8 9 9 5 9 9 9 7 8 9 0 2 3 9 9 9 9 9 9 8 8 7 6 7 8 9 9 5 4 3 4 6 7 9 6 5 6 7 9 8 5 4 3 9 8 7 8 9 5 4 3 2 3 4 8 9 9 4 5 8 9 6 5 6 5 6 9 8 9 9}, - mkRow!{9 9 8 6 5 4 5 9 9 8 7 5 4 3 0 1 2 5 8 8 9 7 6 5 8 9 7 8 9 5 6 7 8 9 8 7 9 8 9 5 2 3 5 6 9 9 9 8 8 9 9 8 7 8 9 9 8 7 5 5 6 9 8 9 7 6 9 8 9 9 8 6 4 5 9 8 9 7 6 5 5 3 6 5 6 7 8 9 6 9 6 5 4 5 4 5 6 7 8 9}, - mkRow!{8 7 6 5 4 3 4 4 5 9 6 4 3 2 1 3 4 7 8 9 7 6 5 4 6 9 8 9 3 4 5 6 7 8 9 6 7 9 9 4 3 4 5 7 8 9 7 6 7 8 9 9 8 9 6 8 9 8 6 7 8 9 9 9 8 9 8 9 8 9 7 6 5 8 9 9 9 8 7 6 9 8 7 6 7 8 9 8 7 8 9 4 3 4 3 4 5 8 9 8}, - mkRow!{9 8 7 6 3 2 1 3 9 8 9 5 4 3 4 4 5 6 9 9 8 7 6 9 7 9 9 1 2 3 6 7 8 9 4 5 6 9 8 7 6 5 6 7 9 9 8 5 6 7 8 9 9 5 4 7 7 9 7 8 9 7 6 8 9 9 7 6 7 9 8 7 6 7 8 9 2 9 8 7 8 9 8 7 8 9 9 9 8 9 9 3 2 1 2 3 4 9 8 7}, - mkRow!{2 9 9 5 4 5 6 9 8 7 8 9 6 4 7 6 7 7 8 9 9 8 9 8 9 7 5 4 3 4 7 8 9 4 3 1 2 3 9 8 7 6 8 9 8 7 5 4 5 8 7 8 9 2 3 5 6 9 8 9 6 6 5 9 8 7 6 5 4 5 9 9 7 8 9 4 3 4 9 9 9 6 9 8 9 9 9 9 9 9 8 9 3 9 3 5 9 8 7 6}, - mkRow!{1 9 8 7 5 6 9 8 7 6 7 8 9 5 6 9 8 9 9 2 4 9 8 7 8 9 6 5 4 5 6 9 6 5 3 2 3 4 6 9 8 7 9 8 7 6 5 3 4 5 6 9 0 1 2 3 4 5 9 6 4 3 4 5 9 8 7 4 3 2 1 9 8 9 8 9 4 9 8 7 6 5 6 9 9 9 8 9 9 8 7 8 9 8 9 6 7 9 6 5}, - mkRow!{0 1 9 8 6 7 8 9 7 5 6 7 9 9 7 8 9 5 4 3 9 9 8 6 7 8 9 6 5 6 7 8 9 9 4 3 4 5 9 9 9 8 9 9 8 7 5 4 5 6 7 9 9 2 3 4 6 9 8 7 6 2 3 9 7 6 4 3 2 1 0 1 9 6 7 8 9 8 7 6 5 4 5 6 9 9 7 9 5 4 6 7 5 7 7 9 9 6 5 4}, - mkRow!{3 2 3 9 9 8 9 7 6 4 5 6 7 8 9 9 9 6 7 9 7 6 5 5 6 8 9 9 7 7 8 9 7 8 9 4 9 9 7 8 9 9 3 0 9 8 6 5 6 8 9 7 8 9 6 5 9 8 7 5 4 3 4 9 9 8 9 4 3 3 1 2 4 5 9 9 9 9 8 7 6 5 7 9 8 7 6 7 6 3 2 3 4 5 6 7 8 9 4 3}, - mkRow!{4 5 9 9 8 9 9 8 6 5 6 9 8 9 9 9 8 7 9 8 6 5 4 4 5 7 9 8 9 8 9 7 6 7 8 9 8 7 6 7 8 9 2 1 2 9 7 8 9 9 7 6 7 8 9 6 7 9 8 7 5 6 9 8 9 9 8 7 6 5 3 5 5 6 7 8 9 9 9 8 7 9 9 8 7 6 5 4 3 4 1 2 9 6 7 9 9 4 3 2}, - mkRow!{5 9 8 8 7 6 7 9 7 8 9 6 9 7 8 9 9 9 8 7 6 5 3 3 4 5 6 7 8 9 3 4 5 8 9 8 9 6 5 6 7 8 9 3 9 9 8 9 9 7 6 5 6 7 8 9 8 9 9 9 6 9 8 7 6 5 9 8 8 9 4 6 7 7 8 9 8 9 9 9 9 8 9 9 8 7 9 3 2 1 0 9 8 9 9 8 9 9 4 9}, - mkRow!{9 8 7 6 5 4 3 9 8 9 6 5 6 6 7 8 9 8 7 6 5 4 1 2 5 6 7 8 9 4 2 3 4 9 8 7 6 5 4 5 6 7 9 9 8 9 9 9 8 9 7 6 7 8 9 6 9 9 9 9 9 8 7 6 5 4 6 9 9 6 5 7 8 9 9 6 7 9 9 9 8 7 9 9 9 9 8 9 3 4 9 8 7 8 5 6 7 8 9 8}, - mkRow!{6 5 6 5 4 3 2 3 9 1 2 3 4 5 6 9 9 9 8 5 4 3 2 7 6 8 8 9 5 4 3 4 5 6 9 8 5 4 3 1 0 9 8 8 7 6 7 6 7 8 9 7 8 9 9 5 9 8 7 9 9 9 8 8 6 3 2 9 8 7 6 8 9 5 4 5 6 7 8 9 5 6 8 9 9 8 7 8 9 9 8 7 6 7 4 7 9 9 6 7}, - mkRow!{5 4 3 2 1 0 1 2 3 9 3 4 5 8 9 9 9 9 8 6 6 7 9 8 9 9 9 7 6 7 5 6 6 9 8 7 6 5 4 5 9 8 7 8 5 4 3 5 6 7 8 9 9 6 8 9 8 7 6 8 9 9 9 9 9 9 1 9 9 8 7 9 5 4 3 5 7 8 9 4 4 5 6 9 8 7 6 7 9 9 9 8 4 3 2 3 4 5 5 6}, - mkRow!{8 5 5 6 2 1 4 3 9 8 9 9 6 7 9 9 8 9 8 7 7 8 9 9 9 9 9 8 7 8 7 8 9 9 9 8 7 6 5 9 8 7 6 5 4 3 2 4 8 8 9 5 4 5 9 8 7 6 5 7 8 9 9 9 8 8 9 8 9 9 8 9 9 5 5 6 8 9 5 3 3 4 9 8 9 6 5 6 7 8 9 6 5 4 0 1 2 3 4 5}, - mkRow!{7 6 7 9 3 4 5 9 8 7 8 8 9 9 8 8 7 5 9 9 8 9 9 7 8 8 9 9 8 9 8 9 9 9 9 9 9 8 7 8 9 9 7 6 5 2 1 0 1 9 7 9 3 9 8 7 6 5 4 5 6 7 9 8 7 6 6 7 8 9 9 9 8 7 8 7 9 5 4 1 2 9 8 7 6 5 4 5 6 9 9 9 6 4 1 4 4 5 6 9}, - mkRow!{8 7 9 8 9 5 6 9 8 6 6 7 9 8 7 6 5 4 3 5 9 8 7 6 7 6 9 8 9 9 9 9 9 8 8 8 9 9 8 9 0 1 9 6 5 4 2 1 4 5 6 8 9 9 8 6 5 4 3 3 4 9 8 9 6 5 5 6 7 9 2 1 9 8 9 9 5 4 3 0 1 2 9 6 5 4 3 4 7 5 9 8 9 3 2 3 4 5 7 8}, - mkRow!{9 9 8 7 8 9 9 7 6 5 4 9 8 7 6 5 4 3 2 4 8 9 6 5 6 5 9 7 8 9 9 9 8 7 6 7 9 9 9 3 1 9 8 7 8 4 3 2 3 6 7 9 8 7 6 5 4 3 1 2 9 8 7 6 5 4 4 5 9 8 9 2 3 9 6 5 4 3 2 1 2 9 8 7 7 5 2 1 2 3 8 7 8 9 3 4 5 6 7 9}, - mkRow!{9 7 6 5 9 7 8 9 6 4 3 4 9 8 7 6 4 2 1 2 7 8 9 4 5 4 5 6 7 9 9 8 7 6 5 6 8 9 4 3 2 3 9 8 7 5 6 3 4 7 8 9 9 8 8 6 5 1 0 1 2 9 8 7 6 2 3 4 6 7 8 9 9 9 8 7 6 5 3 2 3 5 9 9 9 4 3 0 1 4 5 6 7 8 9 6 8 7 8 9}, - mkRow!{8 9 6 4 5 6 8 9 9 1 2 5 6 9 9 5 4 3 2 3 5 9 9 3 2 3 4 5 6 7 9 9 8 7 4 5 9 8 5 5 9 4 5 9 8 7 8 4 5 8 9 9 9 9 7 7 6 2 1 2 9 8 7 5 4 3 4 5 6 8 9 7 8 9 9 8 8 6 4 3 5 6 9 8 6 5 4 3 2 3 6 8 9 9 8 7 9 8 9 7}, - mkRow!{7 8 4 3 4 5 6 9 8 9 3 4 6 9 8 6 5 4 8 7 6 7 8 9 1 2 3 4 8 7 8 9 9 6 5 9 8 7 6 9 8 9 6 8 9 8 9 5 6 9 9 9 8 7 6 5 4 3 4 3 4 9 8 6 6 4 5 7 7 9 7 6 7 8 7 9 9 8 5 4 6 7 8 9 7 8 5 6 5 4 5 9 9 9 9 8 9 9 8 6}, - mkRow!{6 5 3 2 3 4 5 6 7 8 9 6 7 9 8 7 6 6 9 8 7 8 9 1 0 1 2 3 5 6 7 8 9 7 6 7 9 8 9 8 7 8 9 9 9 9 7 6 7 8 9 9 9 9 7 6 5 5 6 4 5 6 9 8 7 5 6 8 9 8 6 5 8 7 6 9 8 7 6 7 7 8 9 9 8 9 8 7 6 5 6 7 8 9 9 9 7 6 7 5}, - mkRow!{4 3 2 1 2 3 4 7 8 9 8 7 9 2 9 9 8 7 9 9 8 9 8 9 2 3 4 4 5 7 9 9 9 9 9 9 9 9 8 7 6 8 9 9 8 9 9 9 8 9 9 9 8 9 8 9 6 6 7 5 8 7 8 9 8 6 7 9 8 7 8 4 5 4 5 9 9 8 9 8 9 9 8 9 9 1 9 9 7 8 7 8 9 9 8 9 6 5 4 3}, - mkRow!{3 2 1 0 3 4 5 8 9 7 9 8 9 1 2 9 9 9 7 9 9 8 7 8 9 4 5 6 6 8 9 9 8 8 8 7 8 9 9 6 5 6 9 8 7 9 3 2 9 9 9 8 7 8 9 8 9 7 9 6 9 8 9 5 9 7 8 9 7 6 4 3 2 3 4 8 9 9 4 9 6 6 7 9 9 0 1 9 8 9 9 9 7 8 7 9 5 4 3 2}, - mkRow!{4 3 2 1 2 9 6 8 9 6 5 9 1 0 9 7 8 5 6 8 9 7 6 7 8 9 6 7 7 8 9 8 7 6 5 6 9 8 9 5 4 5 4 7 6 8 9 1 0 9 8 7 6 5 6 7 9 9 8 9 2 9 2 4 9 8 9 9 8 6 5 2 1 4 6 7 8 9 3 2 4 5 6 7 8 9 2 9 9 5 6 9 6 5 6 7 9 3 2 1}, - mkRow!{6 5 4 2 3 8 9 9 8 9 4 3 2 9 7 6 5 4 5 7 3 4 5 7 7 8 9 9 8 9 3 9 8 5 4 9 8 7 6 4 3 4 3 4 5 6 8 9 1 2 9 8 5 4 5 6 9 8 7 9 1 0 1 2 5 9 7 8 9 5 4 3 0 3 4 9 9 6 4 3 4 6 7 9 9 9 9 8 7 6 7 8 9 4 5 7 8 9 1 0}, - mkRow!{9 5 4 3 5 7 8 9 7 8 9 4 9 8 6 5 4 3 4 8 2 3 4 5 6 7 8 9 9 3 2 9 8 7 6 7 9 8 6 3 2 1 2 3 4 7 8 9 2 9 9 9 9 3 5 7 9 7 6 8 9 1 3 3 4 5 6 7 8 9 4 2 1 2 5 8 9 7 5 9 5 9 8 9 9 9 8 9 8 7 8 9 4 3 4 6 7 8 9 1}, - mkRow!{8 7 5 4 6 9 9 5 6 7 8 9 9 8 7 6 3 2 1 0 1 2 5 6 7 8 9 3 2 0 1 2 9 8 7 8 9 7 5 6 1 0 1 3 5 6 7 8 9 8 9 9 8 9 6 9 8 6 5 7 8 9 9 4 5 6 7 8 9 9 5 3 2 3 6 7 9 7 6 7 7 8 9 8 7 9 7 5 9 9 9 8 9 2 3 4 8 9 8 9}, - mkRow!{8 7 6 7 9 7 6 4 5 6 9 1 2 9 8 6 5 4 2 1 5 3 4 5 7 9 5 4 3 1 4 3 4 9 8 9 7 5 4 3 2 1 2 4 6 7 8 9 6 7 9 8 7 8 9 8 7 6 4 5 9 7 8 9 6 8 8 9 9 8 9 4 3 4 8 9 9 9 7 8 8 9 6 7 6 8 9 9 9 7 6 7 9 0 1 9 9 8 7 8}, - mkRow!{9 8 9 8 9 9 5 3 4 5 8 9 3 4 9 8 5 4 3 4 6 4 7 6 8 9 6 5 3 2 6 4 5 6 9 9 9 6 5 6 3 5 3 4 7 8 9 4 5 9 8 7 6 7 8 9 5 4 3 4 5 6 7 8 9 9 9 9 8 7 8 9 4 5 9 8 7 8 9 9 9 6 5 4 5 9 9 8 7 6 5 8 9 1 9 8 9 7 6 7}, - mkRow!{3 9 1 9 8 9 4 2 3 6 7 8 9 9 8 7 6 5 5 5 7 5 8 8 9 8 7 6 5 3 9 5 6 7 8 9 8 7 6 7 7 6 4 5 8 9 4 3 9 8 7 6 5 6 9 8 9 5 2 3 4 5 8 9 9 9 8 7 7 6 7 8 9 6 7 9 5 6 5 8 9 9 8 7 6 9 8 9 8 7 6 7 9 9 8 7 5 6 5 6}, - mkRow!{2 1 0 9 7 8 9 1 2 9 8 9 4 2 9 8 9 6 7 9 8 9 9 9 9 9 8 9 7 9 8 9 7 8 9 9 9 9 7 8 8 7 9 7 8 9 5 2 0 9 9 5 4 3 6 7 8 9 1 2 5 6 7 8 9 9 9 6 5 4 5 6 8 9 8 9 4 3 4 7 8 9 9 8 7 9 7 6 9 8 7 9 8 7 6 8 4 5 4 5}, - mkRow!{3 9 9 8 6 7 9 2 9 8 9 3 2 1 2 9 8 7 8 9 9 6 8 9 9 9 9 8 9 8 7 8 9 9 9 9 9 9 8 9 9 8 9 9 9 7 6 2 1 9 8 6 5 4 5 6 7 8 9 7 6 7 8 9 8 9 8 7 6 8 6 7 9 9 9 7 6 4 5 6 7 8 9 9 8 9 6 5 7 9 9 8 9 6 5 4 3 3 3 4}, - mkRow!{9 8 7 7 5 6 8 9 9 7 8 9 3 2 4 5 9 8 9 3 4 5 6 7 8 9 9 7 6 7 6 7 9 8 9 8 9 9 9 3 4 9 8 7 6 5 4 3 9 9 9 7 8 7 6 7 8 9 4 9 9 8 9 5 6 9 9 8 7 9 7 8 9 8 9 8 7 9 6 7 8 9 7 6 9 8 7 6 8 9 8 7 8 9 9 3 2 1 2 3}, - mkRow!{9 9 6 5 4 7 9 8 7 6 7 8 9 3 4 6 7 9 0 1 2 3 7 8 9 9 7 6 5 8 5 9 8 7 6 7 8 8 9 1 9 8 9 9 7 6 9 9 8 9 9 8 9 8 7 8 9 6 3 2 1 9 3 4 9 8 7 9 8 9 8 9 6 7 8 9 9 8 9 9 9 9 9 5 3 9 8 7 9 8 7 6 6 7 8 9 9 0 1 4}, - mkRow!{7 6 5 4 3 9 8 7 6 5 6 9 5 4 5 6 9 8 9 5 4 5 6 9 9 9 8 5 4 3 4 9 7 6 5 6 7 7 8 9 8 7 8 9 8 9 8 9 7 8 4 9 7 9 8 9 6 5 4 9 0 1 2 9 9 9 6 7 9 3 9 3 5 6 7 9 8 7 9 8 9 9 8 9 2 0 9 8 9 9 8 5 4 5 6 7 8 9 2 3}, - mkRow!{8 7 4 3 2 1 9 7 5 4 9 8 9 5 7 9 8 7 9 9 5 6 7 8 9 4 9 6 9 2 9 8 9 5 4 3 4 6 7 8 9 6 6 7 9 9 7 6 5 4 3 4 6 5 9 8 9 6 9 8 9 2 9 8 7 6 5 4 3 2 1 2 3 5 6 9 7 6 7 6 7 6 7 8 9 1 5 9 9 9 5 5 3 4 5 6 7 8 9 5}, - mkRow!{9 8 5 4 5 9 8 8 5 3 8 7 8 9 9 8 7 6 7 8 9 7 9 9 2 3 4 9 8 9 9 7 8 9 3 2 3 7 8 9 6 5 5 6 7 9 8 7 6 2 1 0 3 4 6 7 8 9 9 7 9 3 4 9 8 9 6 5 4 1 0 1 2 9 9 8 7 5 6 5 4 5 6 7 9 2 3 4 9 7 4 3 2 3 5 6 7 8 9 6}, - mkRow!{8 7 6 5 9 9 7 5 4 2 3 6 7 8 8 9 6 5 8 9 8 9 3 2 1 0 9 8 7 8 5 6 7 8 9 3 4 5 7 8 9 3 4 5 6 7 9 8 5 4 2 1 2 3 5 8 9 9 7 6 7 9 5 6 9 8 9 4 3 2 1 2 9 8 7 6 5 4 3 2 3 6 7 9 9 3 9 9 8 6 3 2 1 2 4 5 5 6 8 9}, - mkRow!{9 8 7 9 8 7 6 5 2 1 3 4 5 6 7 8 9 4 7 6 7 8 9 3 2 2 9 7 6 5 4 5 6 9 9 6 5 9 8 9 3 1 2 3 9 9 8 7 6 5 3 4 5 6 9 9 6 7 6 5 6 7 9 7 9 7 7 9 9 3 2 3 4 9 9 7 4 3 2 1 4 5 6 7 8 9 8 7 6 5 4 2 0 1 2 3 4 6 7 8}, - mkRow!{5 9 8 9 8 5 4 3 1 0 4 5 6 8 9 9 4 3 4 5 6 7 8 9 4 5 9 8 7 6 5 7 8 9 8 7 6 7 9 2 1 0 5 7 8 9 9 9 7 9 4 5 6 7 8 9 5 4 5 4 6 9 8 9 8 6 5 7 8 9 9 4 5 6 9 6 5 4 9 2 3 6 7 9 9 3 9 8 7 6 5 6 2 9 3 4 6 8 8 9}, - mkRow!{4 1 9 8 7 6 4 3 2 1 6 9 7 9 7 4 3 2 5 7 7 8 9 9 8 6 7 9 9 8 6 9 9 3 9 8 9 8 9 3 2 3 4 5 7 8 9 9 9 8 9 6 9 8 9 5 4 3 5 3 5 9 7 6 9 8 4 5 6 7 8 9 6 9 8 9 7 9 8 9 4 7 8 9 3 2 1 9 8 7 6 5 4 8 9 5 6 7 8 9}, - mkRow!{3 0 1 9 8 7 8 9 3 2 7 8 9 7 6 5 5 3 4 5 6 8 9 9 8 7 9 9 9 8 7 8 9 4 5 9 9 9 5 4 3 4 5 6 9 9 9 9 8 7 8 9 8 9 5 4 3 2 1 2 3 4 9 5 4 3 2 3 7 8 9 9 9 8 7 8 9 8 7 8 9 9 9 4 2 1 0 1 9 8 7 6 5 6 7 8 7 8 9 5}, - mkRow!{2 1 2 3 9 8 9 5 4 9 8 9 8 9 8 7 6 8 9 6 7 9 4 3 9 9 8 9 9 9 8 9 6 5 6 9 8 7 6 5 4 5 6 7 8 9 9 8 7 6 7 8 7 8 9 5 9 4 3 4 5 9 8 9 5 4 3 4 8 9 9 9 8 7 6 9 5 5 6 6 7 8 9 4 3 2 1 9 8 9 9 9 8 7 9 9 8 9 6 4}, - mkRow!{4 2 5 7 8 9 8 6 7 8 9 7 7 6 9 8 7 8 9 9 8 9 5 4 9 8 7 8 9 9 9 8 7 8 8 9 9 8 7 6 9 7 7 8 9 9 9 9 6 5 4 5 6 7 8 9 7 5 4 5 9 8 7 8 9 5 4 5 9 9 9 8 7 6 5 4 4 3 4 5 6 9 6 5 4 5 9 8 7 6 9 9 9 9 4 5 9 9 9 5}, - mkRow!{4 3 4 5 9 9 8 7 8 9 7 6 4 5 6 9 8 9 7 9 9 9 6 9 9 7 6 7 8 9 9 9 8 9 9 6 7 9 8 7 9 8 8 9 4 9 8 7 6 4 3 4 9 8 9 9 8 6 9 6 9 7 6 7 8 9 5 6 7 8 9 9 8 7 6 3 1 2 3 6 7 8 9 6 7 9 8 7 6 5 8 9 5 4 3 5 6 7 8 9}, - mkRow!{5 6 5 6 7 9 9 8 9 3 2 1 2 6 9 8 9 7 5 7 7 8 9 8 7 6 5 6 7 8 7 8 9 6 4 5 9 8 9 8 9 9 9 2 3 5 9 8 6 5 4 5 7 9 5 4 9 9 8 9 9 6 5 6 9 8 7 7 8 9 3 4 9 8 7 4 5 6 4 9 8 9 9 8 9 9 9 6 5 4 7 8 9 3 2 3 5 8 8 9}, - mkRow!{6 7 6 7 8 9 9 9 6 5 4 3 5 9 8 7 6 5 4 5 6 9 8 7 6 5 4 4 6 5 6 7 8 9 5 9 8 7 6 9 2 1 0 1 2 4 5 9 8 6 7 8 8 9 4 2 9 8 7 9 8 7 4 6 8 9 9 8 9 3 2 9 8 7 6 5 6 7 8 9 9 1 0 9 5 9 8 7 6 5 6 7 9 2 0 2 3 9 7 9}, - mkRow!{9 8 9 8 9 9 9 8 7 6 7 8 6 9 8 6 5 4 3 2 1 0 9 8 7 6 3 2 3 4 7 8 9 9 9 8 7 6 5 4 3 2 1 2 3 5 6 9 8 7 8 9 9 6 5 9 8 7 6 5 3 2 3 4 9 0 1 9 1 0 1 2 9 8 8 6 7 9 9 5 4 3 2 3 4 5 9 9 7 6 7 8 9 3 4 3 4 5 6 8} - } - } -} diff --git a/src/tests/aoc-2021-09/src/types.pr.rs b/src/tests/aoc-2021-09/src/types.pr.rs deleted file mode 100644 index 8441695..0000000 --- a/src/tests/aoc-2021-09/src/types.pr.rs +++ /dev/null @@ -1,8 +0,0 @@ -/*SPEC* -property unique { - \c <: (Container) -> ((for-all-elems c) \a -> ((unique-count? a) c)) -} - -type Map = {c impl (Mapping) | true} -type Set = {c impl (Container) | (unique c)} - *ENDSPEC*/ diff --git a/src/tests/aoc-2022-08/Cargo.toml b/src/tests/aoc-2022-08/Cargo.toml deleted file mode 100644 index 449bbdb..0000000 --- a/src/tests/aoc-2022-08/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "aoc-2022-08" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = { workspace = true } -primrose-library = { path = "../../crates/library" } - -[dev-dependencies] -criterion = { workspace = true } - -[[bench]] -name = "main" -harness = false diff --git a/src/tests/aoc-2022-08/benches/main.rs b/src/tests/aoc-2022-08/benches/main.rs deleted file mode 100644 index 1949113..0000000 --- a/src/tests/aoc-2022-08/benches/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -use aoc_2022_08::HeightMap; -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; -use rand::{rngs::StdRng, SeedableRng}; - -fn run_benches(c: &mut Criterion) { - let mut rng = StdRng::seed_from_u64(42); - for size in [1000, 2000].iter() { - c.bench_with_input(BenchmarkId::new("aoc-202208-part1", size), size, |b, &n| { - b.iter_batched_ref( - || HeightMap::gen(&mut rng, n), - |map| map.part1(), - BatchSize::SmallInput, - ) - }); - - c.bench_with_input(BenchmarkId::new("aoc-202208-part2", size), size, |b, &n| { - b.iter_batched_ref( - || HeightMap::gen(&mut rng, n), - |map| map.part2(), - BatchSize::SmallInput, - ) - }); - } -} - -criterion_group!( - name = benches; - config = Criterion::default().sample_size(10); - targets = run_benches -); -criterion_main!(benches); diff --git a/src/tests/aoc-2022-08/src/lib.rs b/src/tests/aoc-2022-08/src/lib.rs deleted file mode 100644 index 9f60ac8..0000000 --- a/src/tests/aoc-2022-08/src/lib.rs +++ /dev/null @@ -1,288 +0,0 @@ -#![feature(type_alias_impl_trait)] - -use primrose_library::traits::*; -use rand::{rngs::StdRng, Rng}; - -mod types; -use types::*; - -pub struct HeightMap { - map: Map<(usize, usize), usize>, - cols: usize, - rows: usize, -} - -impl HeightMap { - pub fn new(map: Map<(usize, usize), usize>, cols: usize, rows: usize) -> Self { - Self { map, cols, rows } - } - - pub fn gen(rng: &mut StdRng, n: usize) -> Self { - let mut map = Map::default(); - for x in 0..n { - for y in 0..n { - map.insert((x, y), rng.gen_range(0..10)); - } - } - - Self { - map, - cols: n, - rows: n, - } - } - - pub fn part1(&self) -> usize { - let mut grid = Map::default(); - - (0..self.rows).for_each(|grid_row| { - self.check_vis_along_run( - (0..self.cols).map(move |grid_col| (grid_row, grid_col)), - &mut grid, - ); - self.check_vis_along_run( - (0..self.cols) - .rev() - .map(move |grid_col| (grid_row, grid_col)), - &mut grid, - ) - }); - (0..self.cols).for_each(|grid_col| { - self.check_vis_along_run( - (0..self.rows).map(move |grid_row| (grid_row, grid_col)), - &mut grid, - ); - self.check_vis_along_run( - (0..self.rows) - .rev() - .map(move |grid_row| (grid_row, grid_col)), - &mut grid, - ) - }); - - grid.iter().filter(|(_, v)| **v).count() - } - - pub fn part2(&self) -> usize { - let mut grid = Map::default(); - - (0..self.rows).for_each(|grid_row| { - self.vis_score_along_run( - (0..self.cols).map(move |grid_col| (grid_row, grid_col)), - &mut grid, - ); - self.vis_score_along_run( - (0..self.cols) - .rev() - .map(move |grid_col| (grid_row, grid_col)), - &mut grid, - ) - }); - (0..self.cols).for_each(|grid_col| { - self.vis_score_along_run( - (0..self.rows).map(move |grid_row| (grid_row, grid_col)), - &mut grid, - ); - self.vis_score_along_run( - (0..self.rows) - .rev() - .map(move |grid_row| (grid_row, grid_col)), - &mut grid, - ) - }); - - *grid.iter().map(|(_, score)| score).max().unwrap() - } - - fn check_vis_along_run( - &self, - mut run: impl Iterator, - vis_grid: &mut Map<(usize, usize), bool>, - ) { - let mut curr_height = { - let (row_idx, col_idx) = run.next().unwrap(); - - vis_grid.insert((row_idx, col_idx), true); - - self.map.get(&(row_idx, col_idx)).unwrap() - }; - for (row_idx, col_idx) in run { - let height = self.map.get(&(row_idx, col_idx)).unwrap(); - if height > curr_height { - curr_height = height; - vis_grid.insert((row_idx, col_idx), true); - } - } - } - - fn vis_score_along_run( - &self, - run: impl Iterator, - vis_grid: &mut Map<(usize, usize), usize>, - ) { - let mut next_values = [0; 10]; - for (row_idx, col_idx) in run { - let height = *self.map.get(&(row_idx, col_idx)).unwrap(); - vis_grid.insert( - (row_idx, col_idx), - vis_grid.get(&(row_idx, col_idx)).unwrap_or(&1) * next_values[height as usize], - ); - - for (val, score) in next_values.iter_mut().enumerate() { - *score = if *score == 0 || val > height as usize { - *score + 1 - } else { - 1 - }; - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn parse_input(input: &str) -> HeightMap { - let mut grid: Vec> = input - .lines() - .map(|x| { - x.chars() - .map(|x| x.to_digit(10).unwrap() as usize) - .collect() - }) - .collect(); - - let (cols, rows) = (grid.len(), grid[0].len()); - HeightMap::new( - grid.into_iter() - .enumerate() - .flat_map(|(c, vs)| vs.into_iter().enumerate().map(move |(r, v)| ((r, c), v))) - .collect(), - cols, - rows, - ) - } - - #[test] - fn test_small() { - let map = parse_input(SMALL_INPUT); - - assert_eq!(map.part1(), 21, "part 1"); - assert_eq!(map.part2(), 8, "part 2"); - } - - #[test] - fn test_large() { - let map = parse_input(LARGE_INPUT); - - assert_eq!(map.part1(), 1859, "part 1"); - assert_eq!(map.part2(), 332640, "part 2"); - } - - const SMALL_INPUT: &str = "30373 -25512 -65332 -33549 -35390"; - - const LARGE_INPUT: &str = "100221200032023210231132410224121421011444302143121341425413411104320412140011030313333000220101112 -112202123021003133332142233323404332315445153153433313154424232233100410424422313323031220233011010 -011002203101130221201112041212404433424255343232213155531144333552214422033044404110303133013102011 -121111233130221221224141101130304514242212243115142242515311345141411232002244120020312220212230110 -202100121002031143312404331332151115114223331225243515233534114435141142242331404201300323113201222 -100021031220304112421404010433522123452131415552421124411431352333224213401342034313144213120020201 -021322001301122441210433214253425221315242313124453313231211152111255512555241432402123122313012220 -102112011033320244100140342511211253345112333255454336534252113251451114422242001024234213333302113 -132330330131203301420044434343145455152343343332352256556523331132212421445241301141320302112302033 -023322331300043142101542252542114115526343233433362336426522664522241145133152512411103311030301102 -322330231444114143321233414112534365353654433452553436246452265364531225351151151443033412041221031 -012321024142334102115451552132455663265336555636436352252325655253353135241221433212232340024232223 -221313322104114224452245113321425622464562645423543656226366436236366342211223552335030321004420030 -302122222422424154133544345544642565622466255242453626235542536222223332315231425444102032032122210 -231133324324321454452534322652236666662342666356747472523623223666552524234541221123331342040102130 -210020241002443524243413355654666622264244543546744763764772255422554656666314534534123124422233033 -131014422414243524255521645632356643223334677577673636537354355442655654452624241512525104443021123 -033403033322215332325412643445254652373556346633545346456537636346453566423552515332123444244330202 -113344141003242351252543634555644673346454333353676654553676643646433222324426451413334115040003434 -001230324131334423146345655352634367445777457543465476454557474433574665556354335235344443340423222 -023244011152423313324656433232434376576677545673553663364375673667467762442263336432523122511002314 -332301042252442131435255344627377653437674735733643774776343344336573375563254444441344341324221021 -334402434231342254423323453655434536773776677775884478878536663447374436723326532641314353455441013 -044342001441534222364463342375566346646375448766484784546577575636346474474644262426334344414332232 -244130421523351525564645423735465337565786567845848555466788768336334436366242664256515555351430211 -024000015535214533542634654746473565564746464865758448476545478886463346677543522243553255453421422 -314442345152523644625564463763377468476865877455764845786446587486747367443753366233446432411453102 -403000534214215322266566347455673478488876664657887477647485758778655633543776436463262445335553104 -214212342251136353523565555447738584887668745867475764748577568657667634663643424344644433342131210 -114243351433156335446363677757688866574765658676758768885858567668678654677476636444464535114243322 -042431434431524463423673765353776887875745588995877855658794867476588746757553543264362224534141501 -304145214121645333564636455447886886885877698565995687887577645687776748545456743542356254233125332 -311331441555242635254434657548756467747985795655656986779866797467565645743544356362633255252311252 -031543523352343526446775553558756644695895589667775569668758957957865578854634733662645643413532141 -132341313125236444736663666564678758797867656955877956887969998885558485468743564462266455525122534 -232352541122446346437676338577648848957677569986976865585987699675564746846753677543463556334143154 -131122222556542463647436455856664477857588875699877776998998877775547558467576475473336454313145311 -323351431635225653436555578777465655659599588676899686697589579979794858655753634546556432442445431 -112233531246445655746654878675766685587986697767667968689785797779856485864853546544452346664152533 -441132313625454663535377687586749896896879888977889996877688569867885777667647465574425232431545142 -111111115654356235746577756578775857666766677988789889966967668865796774447665533366756456656544233 -444252452345444655545775744655786859687696799777689978899776989678787767656644764567745346442533321 -243154434235433653434536454678865969596896986887966776669777699889978977488475776367633466352332221 -011224342565624633533747786446558897878876986776988967899998768656967776846856453564345652346143322 -255513254542435577753688664747776969589697768898799988986867978878755798466564874553774433546435555 -531145456554225737775485576687555769699797776897798787876797978897659996788865775465774226546153322 -442533162233465666667386864866899875679896679977778999979877877678659766555575467467575463636255152 -222435446522644555737767458468785999996898997999997899997696787896667589475664463563534454563214511 -114215466262527345675785857555678986776986688778978997878888897668987577564444436473675662336222114 -311512225352354555566787445776557865789678977797999877977997668696567599676867476737435246555451342 -421334156234643445446758455875576958787887988878779897788997898799755999778447566575637255446655255 -125142454452645575467547748465958777796899699889787977799988676968695967468678746455475566543545252 -541132356636257333356646477666678579897866699899788787979798698767778866447456666337455556433533121 -445221446426223553556485485665966685998799898899888979878767787768599876575858773334364454262234144 -525513243446634357764748776668756995869697898999998977878876699967659655845786665456752546565235543 -242413525434333433563775775447556666686688668777988879987769688978675587574767756766775543642424544 -412342456656355557547778657458878557979677769688789988888698966858589758586466663545734543236112142 -032124116534555566453646756448767766598786768796678968666697769566795585867844377364542222543543144 -441552534565633333336768485544889775969797879987999896968699678699996564658774473347764463533212333 -014334316443544233545737775568867776768987678899897898878766665677857876456548645543346266424252231 -325452232353463343766655746785669595566587987667687678677799977887575876564756446554733252464333125 -235313513563466536365543548586589569868987876898987896869998585688675666574767347633723365564532532 -131124335362654376773466855768859778665998766696796869779797998996756554465587764356742455564311133 -404343421445554355553366675767758576985659996766997797776657667759678485655666467335666422541134511 -312435242152464645537634574874657856986757676888867976856999658767747446588655574536622635614544141 -421213311564223563546534557645478659967967597665866686567866969995544678685456636652623544254232541 -132543425342352422657766376447447764765888966699888885566685795585666784565673355564333242524212311 -302331311115224263643775435787778644568655576569775967656567865844846487483657355742644444135343420 -041452122556655345467337433384557668665698956966665778595596897875676866777643767426226256541552542 -001153531411446425663655546568788568547498779978887586997587766584748746467645733632336523244335133 -123051345234564624353634333467884847454768797578698856589577675458586647637643536245652422355524202 -214113222524335633455447435736745665746584587959858876858874857758585653673436654525322545251233013 -021144513155424252656646455733574856574765868885444777566868748678578533774364735645364444331342200 -431211353221243564244634645643745486685475647654778847854578477454755346753436664555663251321120041 -102242514555444466436542457333634684684544446466456474474878867475656557554754542332232132452524043 -200242332413522436266226554463734737646765775855488765445547588777757737677755424453334532353422100 -241403131545213353553445445364457564356667686685588677677558646353463653546344554664534324351240301 -301440432323554425253552526545676357456386755454585758845784455753574633345364523362222213444203344 -400414313234154322364222535473637766337743638757685754757674654744437433364534662421344453452322134 -001422404442155511452332334335755446737463367654664454733735476754666354564255333335224221543430334 -013133011342545224454646324324367366635745635763574765656353733477656734233264226223311131330044444 -022111144023553523455232562425243646553465743577436756535447437664477626354554366335454123020240144 -230102421342115344242436455624362236434554736674746476337464537776466226562546332255133444243414211 -310212333434541233141416642226456363654747545733335637756546635676334542222542352332333111404102411 -030003333221133245434443565522626652624656376645357754463575744634634423652323553532531310030201001 -030023023423212441345154346256652364345653336653654434533772655254643423443531524513545021442402202 -010024230302312531312212123243243535655425464532567572556636535233466523565345454255552242044131211 -130202311443320415524153221422665546664426662533646433452623222644336564221342333223401212213001023 -211130021411240202155121122543663636242422664454425543522663356225322252323355231113031230011332201 -230111130130413041333532222115236464446226463566236266425464353655322253315233224353341443240012002 -001102313010120320313214115143353526263356666453526645336434636323231453123112522432413131410213301 -311322021312344404314245522512231315322442523625223426563542243513444315534543320140204003013302020 -223031222001210200323443112312552151222246552363556365653546423412555511231131443113420044113212123 -111320133131221133413343355424321432514225151443636656325513423253211421224222110014232232113301221 -010321023321033244303433322535144241341415221344311331433254245144245522341332333121010301003132230 -211110020103304321442134112151523315235121445254445414513445335245114524313310001304234213223211022 -111122023302320302411300133103134411221211352515252145115412111545311213404224233340430222022031002 -211120112212331032422141144010135514321521155344453422441443412441135423402430103212201303331211201 -010021021121120020020341010431334133122452331123312352352313123235203300324210330421332333020210112"; -} diff --git a/src/tests/aoc-2022-08/src/types.pr.rs b/src/tests/aoc-2022-08/src/types.pr.rs deleted file mode 100644 index 5e3950c..0000000 --- a/src/tests/aoc-2022-08/src/types.pr.rs +++ /dev/null @@ -1,3 +0,0 @@ -/*SPEC* -type Map = {c impl (Mapping) | true} - *ENDSPEC*/ diff --git a/src/tests/aoc-2022-09/Cargo.toml b/src/tests/aoc-2022-09/Cargo.toml deleted file mode 100644 index f806c9c..0000000 --- a/src/tests/aoc-2022-09/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "aoc-2022-09" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = { workspace = true } -primrose-library = { path = "../../crates/library" } - -[dev-dependencies] -criterion = { workspace = true } - -[[bench]] -name = "main" -harness = false diff --git a/src/tests/aoc-2022-09/benches/main.rs b/src/tests/aoc-2022-09/benches/main.rs deleted file mode 100644 index 6eb13e4..0000000 --- a/src/tests/aoc-2022-09/benches/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -use aoc_2022_09::{gen_moves, part1, part2}; -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; -use rand::{rngs::StdRng, SeedableRng}; - -fn run_benches(c: &mut Criterion) { - let mut rng = StdRng::seed_from_u64(42); - for size in [100, 1000, 2000].iter() { - c.bench_with_input(BenchmarkId::new("aoc-202209-part1", size), size, |b, &n| { - b.iter_batched_ref( - || gen_moves(&mut rng, n).collect::>(), - |moves| part1(moves.iter()), - BatchSize::SmallInput, - ) - }); - - c.bench_with_input(BenchmarkId::new("aoc-202209-part2", size), size, |b, &n| { - b.iter_batched_ref( - || gen_moves(&mut rng, n).collect::>(), - |moves| part2(moves.iter()), - BatchSize::SmallInput, - ) - }); - } -} - -criterion_group!( - name = benches; - config = Criterion::default().sample_size(10); - targets = run_benches -); -criterion_main!(benches); diff --git a/src/tests/aoc-2022-09/src/lib.rs b/src/tests/aoc-2022-09/src/lib.rs deleted file mode 100644 index 9bb7364..0000000 --- a/src/tests/aoc-2022-09/src/lib.rs +++ /dev/null @@ -1,2126 +0,0 @@ -#![feature(type_alias_impl_trait)] - -use primrose_library::traits::*; -use rand::Rng; -use std::cmp::min; - -mod types; -use types::*; - -pub fn part1<'a>(moves: impl Iterator) -> usize { - visited_from_moves::<2>(moves) -} - -pub fn part2<'a>(moves: impl Iterator) -> usize { - visited_from_moves::<10>(moves) -} - -fn visited_from_moves<'a, const N: usize>(moves: impl Iterator) -> usize { - let mut tail_visited = Set::default(); - tail_visited.insert((0, 0)); - let mut knots = [(0, 0); N]; - for mv in moves { - make_move(mv, &mut knots, &mut tail_visited); - } - - tail_visited.len() -} - -fn make_move(mv: &Move, knots: &mut [Pos], tail_visited: &mut Set) { - let (dir, count) = mv; - - for _ in 0..*count { - // Move head of rope - match dir { - Direction::Up => knots[0].1 += 1, - Direction::Down => knots[0].1 -= 1, - Direction::Right => knots[0].0 += 1, - Direction::Left => knots[0].0 -= 1, - }; - - for front_idx in 0..knots.len() - 1 { - let (fx, fy) = knots[front_idx]; - let (bx, by) = &mut knots[front_idx + 1]; - let (dx, dy) = (fx - *bx, fy - *by); - if (dx.abs() == 2 && dy == 0) || (dy.abs() == 2 && dx == 0) || (dy.abs() + dx.abs() > 2) - { - *bx += (dx.signum()) * min(dx.abs(), 1); - *by += (dy.signum()) * min(dy.abs(), 1); - } - } - tail_visited.insert(knots[knots.len() - 1]); - } -} - -pub type Pos = (i32, i32); -pub type Move = (Direction, u8); - -#[derive(Debug, Clone, Copy)] -pub enum Direction { - Up, - Down, - Left, - Right, -} - -pub fn gen_moves(rng: &mut R, n: usize) -> impl Iterator + '_ { - (0..n).map(|_| { - let dir = match rng.gen_range(0..4) { - 0 => Direction::Up, - 1 => Direction::Down, - 2 => Direction::Left, - 3 => Direction::Right, - _ => unreachable!(), - }; - let count = rng.gen(); - - (dir, count) - }) -} - -#[cfg(test)] -mod tests { - use crate::*; - - fn parse_moves(input: &str) -> impl Iterator + '_ { - input.lines().map(|x| { - let (dir, count) = x.split_once(' ').unwrap(); - let count = count.parse().unwrap(); - - ( - match dir { - "L" => Direction::Left, - "R" => Direction::Right, - "U" => Direction::Up, - "D" => Direction::Down, - _ => panic!("invalid direction, {}", dir), - }, - count, - ) - }) - } - - #[test] - fn test_small() { - let moves = parse_moves(SMALL_INPUT).collect::>(); - assert_eq!(part1(moves.iter()), 13, "part 1"); - assert_eq!(part2(moves.iter()), 1, "part 2"); - } - - #[test] - fn test_large() { - let moves = parse_moves(LARGE_INPUT).collect::>(); - assert_eq!(part1(moves.iter()), 6236, "part 1"); - assert_eq!(part2(moves.iter()), 2449, "part 2"); - } - - const SMALL_INPUT: &str = "R 4 -U 4 -L 3 -D 1 -R 4 -D 1 -L 5 -R 2"; - - const LARGE_INPUT: &str = "L 1 -R 1 -U 1 -R 1 -L 1 -U 2 -L 2 -R 1 -U 2 -D 2 -R 2 -D 2 -R 1 -U 1 -R 2 -L 1 -D 1 -L 2 -R 1 -D 1 -R 1 -U 1 -D 1 -R 1 -D 1 -R 1 -D 2 -L 2 -D 1 -R 2 -L 1 -R 2 -U 2 -R 1 -U 1 -D 2 -U 1 -R 1 -D 1 -R 2 -D 1 -L 2 -R 1 -U 1 -L 1 -U 1 -D 1 -U 1 -D 1 -L 1 -D 1 -R 1 -D 2 -L 1 -D 1 -L 1 -D 1 -R 1 -U 1 -D 2 -R 1 -D 1 -L 2 -D 2 -U 1 -L 1 -U 1 -L 1 -R 2 -U 1 -L 1 -D 1 -R 2 -L 2 -U 1 -D 2 -R 1 -U 1 -R 2 -L 2 -U 1 -L 2 -R 2 -D 1 -L 1 -R 1 -D 2 -L 2 -U 1 -L 2 -R 1 -U 2 -D 1 -U 2 -D 2 -L 2 -D 1 -R 1 -L 2 -R 2 -L 2 -R 2 -L 2 -R 2 -L 1 -U 1 -R 2 -U 1 -D 1 -R 2 -D 2 -R 2 -D 2 -L 2 -R 2 -U 3 -R 1 -U 3 -D 3 -U 1 -L 2 -D 2 -R 3 -D 1 -R 3 -U 1 -L 3 -R 3 -L 1 -U 3 -R 3 -U 3 -R 3 -U 2 -L 2 -D 2 -R 3 -U 2 -L 2 -U 3 -L 2 -R 1 -U 3 -R 2 -U 3 -L 2 -R 2 -U 1 -L 3 -R 3 -L 3 -R 2 -L 3 -D 3 -L 2 -D 1 -R 1 -D 3 -U 3 -R 3 -D 2 -L 2 -D 2 -R 1 -D 1 -U 3 -R 1 -U 2 -L 3 -U 3 -L 2 -D 1 -L 3 -R 2 -D 2 -L 2 -D 3 -L 3 -U 1 -D 3 -U 3 -L 3 -R 2 -D 2 -R 3 -D 2 -R 3 -U 2 -R 1 -L 2 -R 2 -L 1 -D 3 -U 2 -L 2 -U 3 -L 1 -D 1 -L 2 -R 3 -L 1 -D 2 -U 1 -D 3 -U 1 -D 3 -L 1 -U 1 -R 3 -L 2 -U 3 -L 3 -U 1 -L 2 -D 1 -R 2 -L 1 -R 2 -L 2 -D 3 -U 2 -D 2 -U 3 -L 4 -D 4 -R 3 -D 4 -R 1 -L 2 -U 2 -R 1 -U 4 -D 4 -U 4 -D 4 -R 4 -L 2 -U 3 -D 1 -R 4 -D 2 -L 2 -D 1 -L 4 -R 3 -U 2 -D 4 -U 3 -R 3 -L 1 -R 1 -L 2 -D 4 -U 2 -R 1 -L 3 -D 3 -R 4 -U 2 -L 1 -D 3 -R 4 -D 2 -U 3 -D 1 -L 2 -D 2 -R 2 -D 3 -R 2 -U 2 -R 1 -L 1 -U 2 -D 2 -U 3 -D 1 -U 3 -D 1 -R 4 -D 2 -U 1 -L 3 -D 4 -R 3 -D 4 -U 2 -D 1 -R 2 -U 3 -L 3 -D 1 -U 2 -L 3 -D 1 -L 3 -D 1 -U 1 -D 4 -R 1 -D 4 -L 2 -R 3 -D 4 -R 2 -L 3 -D 4 -U 3 -L 4 -U 1 -L 3 -R 1 -L 1 -D 2 -L 1 -U 2 -D 3 -L 1 -R 4 -L 1 -D 2 -U 2 -L 3 -U 3 -L 1 -R 4 -U 3 -D 3 -R 1 -L 2 -R 4 -U 2 -L 3 -U 4 -L 2 -R 4 -D 5 -U 1 -R 2 -D 5 -L 5 -R 1 -D 3 -U 3 -L 3 -U 5 -R 1 -D 1 -R 3 -U 3 -D 1 -R 1 -L 4 -R 1 -L 3 -U 4 -L 3 -R 5 -D 3 -R 2 -U 1 -R 2 -D 2 -L 4 -R 2 -U 1 -L 3 -D 4 -R 4 -L 1 -R 3 -U 3 -D 2 -R 3 -D 3 -U 1 -L 5 -U 1 -L 5 -R 5 -D 1 -U 1 -R 5 -D 4 -L 1 -R 4 -L 5 -D 5 -L 2 -D 1 -L 3 -D 5 -L 4 -R 4 -D 1 -U 1 -D 4 -U 1 -R 4 -L 2 -D 4 -U 1 -L 3 -R 3 -L 3 -R 3 -D 2 -R 3 -L 5 -R 1 -L 1 -R 3 -D 5 -U 5 -L 3 -U 3 -L 5 -D 3 -L 2 -U 5 -D 5 -U 5 -D 4 -U 4 -R 5 -U 3 -D 5 -R 1 -L 4 -U 1 -L 4 -R 2 -D 1 -U 4 -L 5 -D 2 -R 1 -U 1 -R 3 -U 1 -R 4 -U 4 -L 1 -R 2 -U 5 -D 2 -L 5 -U 4 -D 2 -R 1 -D 1 -U 6 -D 5 -L 4 -U 5 -R 1 -L 3 -D 2 -R 3 -U 6 -L 2 -R 6 -D 1 -R 5 -D 1 -L 1 -R 2 -L 4 -R 3 -L 4 -D 6 -R 5 -U 1 -L 4 -D 2 -L 2 -D 3 -L 2 -D 5 -R 4 -D 3 -L 2 -D 4 -R 1 -U 5 -L 5 -U 5 -D 2 -L 3 -D 4 -L 3 -U 4 -L 4 -U 6 -D 6 -U 4 -R 2 -D 3 -U 1 -R 4 -D 3 -R 1 -D 2 -R 3 -L 2 -D 2 -L 4 -D 5 -L 5 -R 2 -L 1 -R 2 -D 2 -R 4 -U 4 -R 5 -L 4 -D 1 -L 6 -R 4 -D 2 -R 6 -L 6 -D 3 -R 2 -D 2 -U 4 -R 2 -U 2 -L 2 -R 5 -D 5 -U 6 -D 6 -L 5 -R 1 -U 3 -L 1 -D 1 -U 2 -R 5 -L 2 -D 2 -U 4 -R 2 -D 2 -U 1 -D 2 -R 3 -L 6 -U 1 -D 6 -R 3 -D 6 -R 1 -D 7 -R 7 -L 4 -R 4 -D 5 -U 6 -R 2 -L 3 -R 5 -L 5 -U 6 -D 3 -U 5 -D 3 -U 5 -R 7 -L 5 -U 7 -L 6 -U 5 -D 1 -L 7 -U 6 -L 3 -D 1 -L 6 -U 4 -D 1 -U 1 -R 1 -L 3 -D 6 -L 6 -R 3 -D 3 -U 2 -R 1 -D 6 -U 7 -R 6 -L 4 -R 4 -D 7 -R 1 -D 5 -U 6 -D 4 -R 6 -L 2 -U 4 -D 7 -R 5 -D 6 -U 7 -R 6 -D 6 -U 1 -D 4 -L 2 -U 2 -R 7 -U 1 -L 1 -U 1 -L 7 -D 3 -U 5 -D 5 -L 1 -D 4 -L 3 -U 7 -L 6 -R 7 -U 6 -R 1 -L 3 -R 1 -D 3 -L 7 -R 4 -L 3 -D 2 -L 7 -D 2 -R 5 -L 7 -D 6 -L 6 -D 3 -L 3 -D 5 -U 3 -L 5 -R 6 -L 1 -U 5 -R 4 -U 2 -D 3 -R 5 -L 4 -U 5 -D 7 -R 1 -L 3 -U 5 -D 3 -L 6 -R 2 -L 2 -U 6 -R 3 -U 7 -R 3 -D 1 -L 2 -U 7 -L 6 -D 3 -L 8 -R 6 -D 3 -L 5 -R 5 -U 5 -R 8 -D 7 -R 7 -U 8 -L 5 -D 6 -R 6 -L 6 -D 8 -U 1 -R 4 -L 3 -R 6 -L 6 -D 5 -R 4 -D 8 -L 4 -R 4 -D 3 -L 2 -U 6 -L 8 -R 1 -U 5 -L 4 -D 8 -R 6 -D 5 -U 6 -L 5 -R 1 -L 8 -U 7 -R 6 -D 4 -U 2 -D 8 -U 3 -D 7 -R 6 -D 8 -R 8 -U 8 -D 7 -L 3 -D 4 -L 1 -U 4 -R 4 -U 2 -D 6 -R 1 -D 8 -R 2 -D 4 -R 5 -L 1 -R 7 -L 3 -D 1 -U 1 -R 7 -U 5 -D 1 -L 2 -R 8 -D 8 -L 5 -U 8 -D 4 -L 5 -D 3 -U 2 -L 7 -R 2 -L 5 -U 3 -R 3 -U 6 -R 6 -D 4 -R 3 -U 4 -D 5 -U 6 -R 3 -L 4 -R 5 -L 4 -R 8 -U 6 -L 6 -U 1 -L 5 -R 3 -U 1 -D 5 -U 8 -R 1 -L 2 -R 3 -L 8 -U 6 -L 4 -R 3 -L 3 -R 7 -L 9 -D 5 -R 8 -L 5 -U 7 -D 7 -R 6 -L 8 -U 4 -D 5 -R 8 -L 4 -R 8 -U 9 -R 9 -L 8 -D 9 -L 9 -D 6 -R 1 -L 8 -U 4 -L 6 -U 5 -R 9 -L 5 -D 6 -R 9 -D 9 -U 6 -L 1 -U 8 -L 7 -R 9 -U 4 -R 6 -U 1 -R 5 -U 5 -L 4 -R 4 -D 7 -L 6 -U 3 -R 9 -U 1 -L 6 -U 5 -L 5 -U 2 -L 3 -U 2 -D 6 -R 8 -L 5 -U 4 -D 4 -R 4 -D 6 -L 8 -U 9 -R 4 -L 3 -D 1 -U 2 -D 5 -U 3 -D 3 -L 2 -D 3 -L 4 -D 5 -L 9 -D 9 -U 2 -D 8 -R 4 -L 8 -R 9 -D 7 -L 3 -D 2 -R 2 -L 4 -D 7 -R 6 -D 8 -R 9 -L 3 -D 5 -U 1 -L 8 -D 6 -R 9 -U 6 -R 9 -D 6 -L 9 -U 5 -D 10 -L 4 -U 10 -R 3 -U 7 -D 4 -L 3 -R 8 -L 4 -U 10 -R 8 -L 10 -U 8 -R 5 -L 8 -U 6 -L 5 -D 7 -L 6 -U 6 -L 9 -R 8 -U 6 -D 7 -L 10 -R 2 -D 7 -L 8 -U 5 -L 2 -D 2 -U 7 -D 6 -R 7 -D 2 -U 3 -R 10 -D 2 -U 6 -D 6 -L 8 -D 2 -L 2 -D 10 -L 2 -D 1 -L 10 -D 6 -R 6 -L 7 -D 9 -R 2 -D 5 -U 2 -R 4 -L 4 -D 1 -L 3 -R 10 -U 9 -L 4 -D 10 -L 10 -D 4 -U 2 -R 1 -L 4 -D 6 -U 2 -L 6 -R 4 -U 1 -L 9 -R 7 -L 8 -U 5 -R 1 -D 6 -L 4 -U 9 -D 1 -L 5 -R 10 -D 4 -L 6 -U 8 -R 4 -L 5 -D 10 -R 8 -D 8 -R 4 -D 5 -R 7 -L 10 -D 3 -R 1 -L 4 -R 8 -L 10 -D 2 -L 3 -D 6 -L 8 -R 10 -L 2 -D 8 -R 5 -L 8 -D 1 -U 6 -D 11 -U 7 -L 1 -U 6 -R 9 -L 8 -R 5 -U 9 -D 5 -L 10 -U 6 -L 3 -D 4 -U 6 -D 10 -L 2 -D 9 -L 5 -R 8 -D 1 -R 1 -U 1 -D 4 -R 4 -U 6 -L 9 -U 7 -R 11 -L 8 -D 3 -R 9 -L 11 -U 9 -L 4 -D 10 -U 9 -L 7 -R 9 -U 1 -R 8 -U 4 -L 3 -U 2 -D 7 -R 6 -U 1 -D 10 -U 9 -R 6 -L 6 -D 4 -U 3 -L 10 -R 10 -U 6 -R 8 -L 9 -R 2 -D 7 -R 4 -U 6 -R 2 -L 4 -D 1 -L 10 -U 9 -R 11 -U 11 -R 1 -D 5 -L 8 -U 3 -R 1 -U 4 -D 10 -U 6 -L 8 -R 4 -L 7 -R 8 -D 3 -L 9 -U 4 -L 6 -R 2 -D 2 -U 9 -D 6 -R 8 -L 2 -U 7 -L 2 -R 8 -L 7 -D 5 -R 10 -U 5 -L 10 -U 6 -R 8 -U 9 -L 7 -D 11 -U 10 -L 4 -D 5 -R 4 -L 7 -U 5 -D 8 -R 6 -D 9 -L 4 -U 9 -R 6 -D 1 -U 6 -R 8 -U 10 -D 6 -U 10 -L 3 -D 1 -L 1 -R 9 -D 10 -L 10 -U 12 -D 3 -L 2 -U 6 -L 9 -U 2 -R 6 -D 8 -R 11 -L 1 -U 3 -R 1 -U 9 -R 12 -U 3 -D 11 -U 3 -D 10 -U 12 -L 11 -R 9 -U 9 -D 11 -L 8 -D 4 -R 4 -U 4 -D 1 -L 7 -R 10 -L 4 -R 4 -U 11 -D 3 -L 6 -R 10 -L 9 -R 11 -U 6 -D 2 -U 2 -L 3 -D 11 -U 6 -D 12 -L 5 -R 5 -D 6 -R 5 -U 2 -R 8 -L 7 -D 7 -R 3 -D 8 -U 6 -D 1 -U 1 -D 4 -L 3 -D 12 -L 8 -D 8 -U 7 -R 1 -D 10 -L 5 -D 7 -L 1 -U 4 -R 12 -L 8 -U 2 -L 2 -U 1 -L 8 -U 3 -L 12 -R 3 -D 11 -R 1 -U 4 -D 12 -L 3 -U 2 -R 5 -U 2 -R 7 -U 8 -L 5 -R 1 -D 5 -R 12 -D 8 -R 9 -D 7 -L 2 -R 2 -U 9 -D 6 -U 6 -R 2 -D 2 -R 9 -D 4 -R 12 -D 13 -R 9 -L 3 -D 8 -L 13 -U 2 -R 10 -U 12 -D 12 -U 3 -L 6 -D 8 -U 1 -L 12 -D 9 -L 7 -R 2 -D 4 -R 5 -L 7 -R 12 -U 4 -L 7 -D 4 -U 10 -L 2 -D 1 -U 5 -R 5 -U 2 -L 9 -D 10 -L 1 -R 7 -L 6 -D 1 -L 12 -R 6 -U 10 -R 2 -D 10 -R 5 -L 3 -R 8 -D 1 -R 12 -L 7 -U 5 -L 11 -D 4 -U 11 -D 1 -U 11 -L 1 -D 11 -U 11 -D 4 -U 8 -R 5 -D 6 -L 12 -R 5 -D 10 -L 2 -D 5 -R 10 -U 6 -D 6 -R 4 -D 7 -L 2 -D 5 -U 2 -R 9 -L 11 -U 13 -D 9 -L 11 -D 8 -L 2 -D 4 -R 13 -L 5 -U 12 -R 11 -U 5 -L 8 -U 5 -D 7 -U 1 -R 9 -D 4 -U 3 -R 9 -L 3 -D 7 -R 8 -D 7 -L 2 -U 4 -L 12 -U 13 -L 12 -R 8 -L 3 -R 12 -L 4 -U 12 -R 13 -D 10 -L 8 -U 12 -R 5 -L 1 -U 2 -L 3 -U 2 -D 12 -L 12 -U 11 -L 2 -R 6 -U 3 -L 2 -R 7 -U 7 -L 3 -R 8 -L 11 -D 2 -U 1 -R 12 -D 1 -R 4 -L 13 -U 14 -R 14 -D 12 -R 12 -D 11 -L 11 -U 2 -L 6 -D 8 -L 5 -D 7 -R 2 -L 14 -U 12 -R 13 -L 7 -D 2 -U 4 -D 5 -R 5 -L 7 -R 7 -U 1 -R 10 -D 11 -L 7 -U 2 -R 5 -L 11 -U 11 -R 9 -U 9 -R 12 -D 14 -R 5 -L 9 -U 2 -D 12 -L 6 -U 7 -R 5 -L 10 -D 10 -U 4 -D 13 -L 13 -D 3 -R 8 -D 10 -U 12 -L 14 -U 7 -D 6 -R 4 -U 11 -R 2 -L 5 -D 12 -R 4 -L 4 -D 5 -L 12 -U 3 -L 3 -U 7 -R 4 -L 2 -R 7 -L 5 -D 5 -R 9 -L 5 -D 12 -R 3 -U 1 -D 6 -U 2 -R 10 -L 4 -U 12 -R 15 -L 2 -R 3 -D 8 -L 13 -D 3 -R 5 -D 5 -L 5 -U 7 -L 4 -R 10 -D 11 -L 3 -R 1 -U 4 -D 15 -L 8 -U 10 -L 5 -D 1 -R 5 -D 15 -R 3 -U 9 -R 4 -D 3 -L 15 -U 6 -D 10 -U 2 -R 6 -U 10 -L 12 -R 8 -D 12 -R 14 -U 10 -D 1 -L 1 -D 8 -U 3 -R 11 -D 7 -L 5 -D 14 -R 1 -D 8 -R 6 -U 6 -D 1 -U 14 -R 12 -L 5 -U 5 -L 14 -U 1 -D 3 -R 6 -U 4 -R 9 -L 13 -R 2 -U 10 -R 11 -U 7 -D 8 -U 14 -L 4 -R 3 -U 6 -R 2 -D 14 -U 10 -D 13 -U 8 -R 12 -L 12 -U 6 -L 4 -U 5 -D 6 -U 8 -L 12 -D 1 -L 3 -R 4 -L 11 -R 5 -D 3 -U 6 -D 15 -R 14 -U 8 -R 10 -U 15 -R 13 -L 13 -U 4 -D 3 -U 4 -D 1 -U 5 -R 5 -D 4 -R 2 -D 13 -R 7 -D 10 -U 3 -R 15 -D 3 -U 13 -R 16 -U 2 -D 6 -L 13 -R 8 -L 5 -R 1 -U 7 -R 6 -U 6 -R 10 -U 5 -L 14 -R 12 -U 8 -R 13 -U 4 -L 10 -R 16 -L 15 -D 7 -R 14 -D 8 -U 8 -L 15 -R 2 -U 11 -L 6 -R 6 -D 2 -U 9 -D 12 -L 10 -U 7 -R 8 -L 4 -D 5 -R 13 -L 9 -U 15 -D 11 -R 11 -D 8 -L 10 -R 14 -D 3 -R 10 -U 1 -R 11 -L 16 -R 12 -D 15 -L 13 -U 2 -L 11 -U 15 -D 9 -R 1 -D 13 -L 16 -U 9 -D 2 -R 5 -U 9 -R 11 -L 16 -U 5 -R 11 -U 8 -L 15 -U 1 -L 11 -U 3 -L 4 -U 9 -L 5 -U 11 -D 9 -U 4 -L 14 -U 8 -L 16 -D 9 -U 5 -L 14 -R 13 -U 8 -L 4 -R 9 -L 4 -R 7 -D 15 -U 14 -D 8 -U 6 -R 11 -L 15 -D 10 -R 2 -L 12 -R 11 -D 7 -R 11 -L 4 -R 4 -D 4 -R 3 -U 15 -L 6 -R 8 -L 5 -U 13 -D 6 -R 1 -D 15 -L 9 -U 2 -L 13 -R 10 -U 8 -R 15 -D 16 -L 13 -U 13 -L 12 -R 10 -U 16 -L 10 -R 14 -D 17 -R 4 -D 16 -U 17 -R 8 -D 10 -R 11 -L 10 -U 17 -L 11 -U 3 -L 4 -U 2 -D 10 -R 15 -U 1 -R 5 -L 12 -D 4 -R 1 -U 15 -R 13 -L 17 -R 15 -D 4 -L 14 -R 3 -D 1 -U 14 -R 11 -D 12 -L 7 -D 11 -R 12 -U 1 -R 5 -L 11 -D 9 -U 8 -R 1 -U 4 -L 15 -R 12 -U 17 -R 4 -U 14 -L 4 -D 16 -R 9 -U 9 -D 11 -L 7 -D 16 -R 10 -L 10 -R 15 -U 10 -R 6 -L 4 -R 6 -L 12 -U 9 -R 15 -D 12 -L 14 -U 14 -D 6 -U 4 -R 17 -U 2 -L 5 -R 13 -D 15 -U 13 -L 5 -D 3 -L 7 -U 12 -R 13 -D 15 -U 15 -L 17 -U 17 -L 6 -R 2 -U 17 -R 7 -L 15 -U 17 -R 11 -L 2 -U 1 -D 4 -U 2 -R 10 -L 9 -D 18 -U 5 -D 7 -R 18 -L 11 -D 2 -U 13 -D 12 -R 10 -D 2 -R 9 -L 3 -D 9 -R 9 -L 17 -R 4 -L 7 -D 16 -L 5 -R 3 -L 8 -U 7 -R 8 -L 1 -D 12 -U 13 -R 8 -D 18 -U 7 -R 6 -D 7 -L 7 -D 8 -R 16 -L 13 -R 6 -U 1 -L 9 -U 9 -L 12 -D 13 -R 18 -L 7 -D 18 -U 17 -R 18 -D 11 -R 1 -D 4 -U 3 -L 7 -D 17 -R 8 -U 11 -D 7 -L 4 -R 12 -U 10 -L 15 -R 14 -U 16 -D 4 -L 10 -U 6 -D 18 -R 7 -U 13 -R 11 -D 14 -L 5 -U 5 -L 7 -R 15 -L 16 -U 6 -D 9 -L 17 -R 4 -L 16 -D 10 -U 16 -D 17 -R 7 -L 16 -U 6 -L 15 -R 13 -U 8 -L 14 -R 12 -U 5 -D 17 -R 13 -D 12 -U 12 -L 16 -R 8 -U 4 -D 6 -U 10 -D 14 -R 18 -L 17 -U 15 -L 5 -U 7 -D 15 -U 10 -R 18 -L 11 -D 10 -R 12 -U 15 -D 11 -U 7 -D 3 -R 2 -U 5 -R 12 -U 15 -R 12 -U 19 -L 6 -U 18 -D 8 -L 7 -D 2 -R 1 -L 16 -D 5 -L 9 -U 11 -L 6 -U 7 -L 2 -D 18 -L 1 -U 19 -D 15 -U 8 -R 5 -U 13 -L 7 -R 14 -U 2 -D 10 -U 16 -D 3 -R 8 -L 10 -D 17 -U 16 -D 6 -R 18 -D 5 -L 5 -D 4 -L 6 -U 17 -D 7 -R 15 -D 5 -R 18 -L 6 -U 15 -L 3 -U 13 -L 15 -R 5 -D 9 -R 11 -U 15 -L 19 -D 11 -L 8 -D 14 -R 7 -L 16 -D 5 -R 13 -D 5 -L 9 -D 3 -L 3 -R 12 -U 17 -R 8 -L 11 -U 2 -R 9 -L 3 -D 6 -L 9 -U 11 -R 6 -U 19 -R 6 -L 12 -U 5 -R 4 -U 4 -L 16 -R 17 -D 12 -U 11 -R 4 -D 11 -U 4 -R 8 -U 9 -R 12 -U 13 -L 2 -D 9 -L 2"; -} diff --git a/src/tests/aoc-2022-09/src/types.pr.rs b/src/tests/aoc-2022-09/src/types.pr.rs deleted file mode 100644 index d4225a9..0000000 --- a/src/tests/aoc-2022-09/src/types.pr.rs +++ /dev/null @@ -1,7 +0,0 @@ -/*SPEC* -property unique { - \c <: (Container) -> ((for-all-elems c) \a -> ((unique-count? a) c)) -} - -type Set = {c impl (Container) | (unique c)} - *ENDSPEC*/ diff --git a/src/tests/aoc-2022-14/Cargo.toml b/src/tests/aoc-2022-14/Cargo.toml deleted file mode 100644 index b8c00f5..0000000 --- a/src/tests/aoc-2022-14/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "aoc-2022-14" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -rand = { workspace = true } -primrose-library = { path = "../../crates/library" } - -[dev-dependencies] -criterion = { workspace = true } - -[[bench]] -name = "main" -harness = false diff --git a/src/tests/aoc-2022-14/benches/main.rs b/src/tests/aoc-2022-14/benches/main.rs deleted file mode 100644 index 8ca2664..0000000 --- a/src/tests/aoc-2022-14/benches/main.rs +++ /dev/null @@ -1,34 +0,0 @@ -use aoc_2022_14::tests::*; -use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; -use rand::{rngs::StdRng, SeedableRng}; - -fn run_benches(c: &mut Criterion) { - c.bench_with_input( - BenchmarkId::new("aoc-202214-part1", "small"), - &SMALL_INPUT, - |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part1(), BatchSize::SmallInput), - ); - c.bench_with_input( - BenchmarkId::new("aoc-202214-part1", "large"), - &LARGE_INPUT, - |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part1(), BatchSize::SmallInput), - ); - - c.bench_with_input( - BenchmarkId::new("aoc-202214-part2", "small"), - &SMALL_INPUT, - |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part2(), BatchSize::SmallInput), - ); - c.bench_with_input( - BenchmarkId::new("aoc-202214-part2", "large"), - &LARGE_INPUT, - |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part2(), BatchSize::SmallInput), - ); -} - -criterion_group!( - name = benches; - config = Criterion::default().sample_size(10); - targets = run_benches -); -criterion_main!(benches); diff --git a/src/tests/aoc-2022-14/src/lib.rs b/src/tests/aoc-2022-14/src/lib.rs deleted file mode 100644 index 3494e2e..0000000 --- a/src/tests/aoc-2022-14/src/lib.rs +++ /dev/null @@ -1,170 +0,0 @@ -#![feature(type_alias_impl_trait)] - -use primrose_library::traits::*; -use std::{ - cmp::{max, min}, - ops::Add, -}; - -mod types; -use types::*; - -pub struct World { - structures: Vec, - sand_grains: Set, - floor_y: isize, -} - -impl World { - pub fn new(structures: Vec) -> Self { - let floor_y = structures - .iter() - .map(|s| s.points.iter().map(|p| p.1).max().unwrap()) - .max() - .unwrap() - + 2; - - Self { - structures, - floor_y, - sand_grains: Default::default(), - } - } - - pub fn part1(&mut self) -> usize { - (0..).take_while(|_| !self.step()).count() - } - - pub fn part2(&mut self) -> usize { - self.structures.push(Structure::new({ - let mut l: List = Default::default(); - l.insert(Pos(isize::MIN, self.floor_y)); - l.insert(Pos(isize::MAX, self.floor_y)); - l - })); - (0..).take_while(|_| !self.step()).count() - } - - fn step(&mut self) -> bool { - let mut pos = Pos(500, 0); - if self.sand_grains.contains(&pos) { - return true; - } - loop { - if pos.1 > self.floor_y { - return true; - } - pos = if !self.inhabited(pos + Pos(0, 1)) { - pos + Pos(0, 1) - } else if !self.inhabited(pos + Pos(-1, 1)) { - pos + Pos(-1, 1) - } else if !self.inhabited(pos + Pos(1, 1)) { - pos + Pos(1, 1) - } else { - self.sand_grains.insert(pos); - return false; - }; - } - } - - fn inhabited(&self, pos: Pos) -> bool { - self.structures.iter().any(|s| s.contains(pos)) || self.sand_grains.contains(&pos) - } -} - -pub struct Structure { - points: List, - bbox_min: Pos, - bbox_max: Pos, -} - -impl Structure { - pub fn new(points: List) -> Self { - let bbox_min = points.iter().fold(Pos(isize::MAX, isize::MAX), |acc, pos| { - Pos(min(acc.0, pos.0), min(acc.1, pos.1)) - }); - let bbox_max = points.iter().fold(Pos(isize::MAX, isize::MAX), |acc, pos| { - Pos(max(acc.0, pos.0), max(acc.1, pos.1)) - }); - - Structure { - points, - bbox_max, - bbox_min, - } - } - - fn contains(&self, pos: Pos) -> bool { - if pos.0 < self.bbox_min.0 - || pos.0 > self.bbox_max.0 - || pos.1 < self.bbox_min.1 - || pos.1 > self.bbox_max.1 - { - return false; - } - for (a, b) in self.points.iter().zip(self.points.iter().skip(1)) { - if a.0 == b.0 { - if pos.0 == a.0 && pos.1 >= min(a.1, b.1) && pos.1 <= max(a.1, b.1) { - return true; - } - } else { - // a.1 == b.1 - if pos.1 == a.1 && pos.0 >= min(a.0, b.0) && pos.0 <= max(a.0, b.0) { - return true; - } - } - } - return false; - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Pos(isize, isize); - -impl Add for Pos { - type Output = Pos; - - fn add(self, rhs: Self) -> Self::Output { - Pos(self.0 + rhs.0, self.1 + rhs.1) - } -} - -pub mod tests { - use super::*; - - pub fn parse_input(input: &str) -> World { - World::new(input.lines().map(parse_structure).collect()) - } - - pub fn parse_structure(l: &str) -> Structure { - Structure::new(l.split(" -> ").map(|s| parse_pos(s)).collect()) - } - - pub fn parse_pos(s: &str) -> Pos { - let (x, y) = s.split_once(',').unwrap(); - Pos(x.parse().unwrap(), y.parse().unwrap()) - } - - #[test] - fn small() { - assert_eq!(parse_input(SMALL_INPUT).part1(), 24, "part 1"); - assert_eq!(parse_input(SMALL_INPUT).part2(), 93, "part 2"); - } - - #[test] - fn large() { - assert_eq!(parse_input(LARGE_INPUT).part1(), 0, "part 1"); - assert_eq!(parse_input(LARGE_INPUT).part2(), 26360, "part 2"); - } - - pub const SMALL_INPUT: &str = "498,4 -> 498,6 -> 496,6 -503,4 -> 502,4 -> 502,9 -> 494,9"; - - pub const LARGE_INPUT: &str = "515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60 -515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60 -502,32 -> 507,32 -522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47 -516,32 -> 521,32 -501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161 -512,30 -> 517,30"; -} diff --git a/src/tests/aoc-2022-14/src/types.pr.rs b/src/tests/aoc-2022-14/src/types.pr.rs deleted file mode 100644 index 9d36060..0000000 --- a/src/tests/aoc-2022-14/src/types.pr.rs +++ /dev/null @@ -1,12 +0,0 @@ -/*SPEC* -property order-preserved { - \c <: (Container, Indexable) -> (forall \x -> ((equal? (op-last ((op-insert c) x))) x)) -} - -property unique { - \c <: (Container) -> ((for-all-elems c) \a -> ((unique-count? a) c)) -} - -type List = {c impl (Container, Indexable) | (order-preserved c)} -type Set = {c impl (Container) | (unique c)} - *ENDSPEC*/ diff --git a/src/tests/aoc_2021_09/Cargo.toml b/src/tests/aoc_2021_09/Cargo.toml new file mode 100644 index 0000000..49da8bb --- /dev/null +++ b/src/tests/aoc_2021_09/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aoc-2021-09" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = { workspace = true } +primrose-library = { path = "../../crates/library" } + +[dev-dependencies] +criterion = { workspace = true } + +[[bench]] +name = "main" +harness = false diff --git a/src/tests/aoc_2021_09/benches/main.rs b/src/tests/aoc_2021_09/benches/main.rs new file mode 100644 index 0000000..cc9b460 --- /dev/null +++ b/src/tests/aoc_2021_09/benches/main.rs @@ -0,0 +1,39 @@ +use aoc_2021_09::HeightMap; +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use rand::{rngs::StdRng, SeedableRng}; + +fn run_benches(c: &mut Criterion) { + let mut rng = StdRng::seed_from_u64(42); + for size in [100].iter() { + c.bench_with_input( + BenchmarkId::new("aoc_2021_09-part1", size), + size, + |b, &n| { + b.iter_batched_ref( + || HeightMap::gen(&mut rng, n), + |map| map.part1(), + BatchSize::SmallInput, + ) + }, + ); + + c.bench_with_input( + BenchmarkId::new("aoc_2021_09-part2", size), + size, + |b, &n| { + b.iter_batched_ref( + || HeightMap::gen(&mut rng, n), + |map| map.part2(), + BatchSize::SmallInput, + ) + }, + ); + } +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = run_benches +); +criterion_main!(benches); diff --git a/src/tests/aoc_2021_09/src/lib.rs b/src/tests/aoc_2021_09/src/lib.rs new file mode 100644 index 0000000..9ada752 --- /dev/null +++ b/src/tests/aoc_2021_09/src/lib.rs @@ -0,0 +1,270 @@ +#![feature(type_alias_impl_trait)] + +use primrose_library::traits::*; +use rand::{rngs::StdRng, Rng}; +use std::collections::VecDeque; + +mod types; +use types::*; + +type Queue = VecDeque; // TODO: would be nice for this to be in primrose + +pub struct HeightMap { + map: Map<(usize, usize), usize>, + cols: usize, + rows: usize, +} + +impl HeightMap { + pub fn new(map: Map<(usize, usize), usize>, cols: usize, rows: usize) -> Self { + Self { map, cols, rows } + } + + pub fn gen(rng: &mut StdRng, n: usize) -> Self { + let mut map = Map::default(); + for x in 0..n { + for y in 0..n { + map.insert((x, y), rng.gen()); + } + } + + Self { + map, + cols: n, + rows: n, + } + } + + fn is_low_point(&self, x: usize, y: usize) -> bool { + [ + self.map.get(&(x + 1, y)), + self.map.get(&(x.overflowing_sub(1).0, y)), + self.map.get(&(x, y + 1)), + self.map.get(&(x, y.overflowing_sub(1).0)), + ] + .into_iter() + .flatten() + .all(|v| v > self.map.get(&(x, y)).unwrap()) + } + + fn risk_level(&self, x: usize, y: usize) -> usize { + self.map.get(&(x, y)).unwrap() + 1 + } + + pub fn part1(&self) -> usize { + let coords = (0..self.cols).flat_map(|x| (0..self.rows).map(move |y| (x, y))); + + coords + .filter(|(x, y)| self.is_low_point(*x, *y)) + .map(|(x, y)| self.risk_level(x, y)) + .sum::() + } + + fn basin_size(&self, x: usize, y: usize) -> usize { + let mut visited = Set::default(); + let mut queue = Queue::default(); + queue.push_back((x, y)); + + let mut size = 0; + while let Some((x, y)) = queue.pop_front() { + if !(0..self.cols).contains(&x) + || !(0..self.rows).contains(&y) + || visited.contains(&(x, y)) + { + continue; + } + + let val = self.map.get(&(x, y)).unwrap(); + if *val == 9 { + continue; + } + + size += 1; + visited.insert((x, y)); + for coord in [ + (x + 1, y), + (x.overflowing_sub(1).0, y), + (x, y + 1), + (x, y.overflowing_sub(1).0), + ] { + queue.push_back(coord) + } + } + + size + } + + pub fn part2(&self) -> usize { + let mut basins = (0..self.cols) + .flat_map(|x| (0..self.rows).map(move |y| (x, y))) + .filter(|(x, y)| self.is_low_point(*x, *y)) + .map(|(x, y)| self.basin_size(x, y)) + .collect::>(); + + basins.sort(); + basins.reverse(); + basins.iter().take(3).product() + } +} + +#[cfg(test)] +mod tests { + use crate::HeightMap; + + macro_rules! mkRow { + ($($v:expr) *) => {{ + let mut c = Vec::default(); + $(c.push($v);)* + c + }} + } + macro_rules! mkMap { + ($rows:expr, $cols:expr, $($r:expr),*) => {{ + let mut c = Vec::default(); + $( + let r = $r; + assert_eq!(r.len(), $cols); + c.push($r); + )* + assert_eq!(c.len(), $rows); + HeightMap::new( + c.into_iter().enumerate().flat_map(|(y, xs)| xs.into_iter().enumerate().map(move |(x, v)| ((x, y), v))).collect(), + $cols, + $rows + ) + }} + } + + #[test] + fn test_small() { + let map = small_input(); + + assert_eq!(map.part1(), 15); + assert_eq!(map.part2(), 1134); + } + + #[test] + fn test_large() { + let map = large_input(); + + assert_eq!(map.part1(), 560); + assert_eq!(map.part2(), 959136); + } + + fn small_input() -> HeightMap { + mkMap! { + 5, 10, + mkRow!{2 1 9 9 9 4 3 2 1 0}, + mkRow!{3 9 8 7 8 9 4 9 2 1}, + mkRow!{9 8 5 6 7 8 9 8 9 2}, + mkRow!{8 7 6 7 8 9 6 7 8 9}, + mkRow!{9 8 9 9 9 6 5 6 7 8} + } + } + + fn large_input() -> HeightMap { + mkMap! { + 100, 100, + mkRow!{9 7 5 6 7 8 9 5 4 5 9 8 7 6 5 2 3 4 5 8 9 1 0 1 2 3 6 7 8 9 9 9 8 9 9 9 1 3 5 9 9 9 9 8 6 6 4 3 5 9 7 4 3 2 1 9 2 1 2 3 4 9 8 9 9 9 4 3 4 6 6 7 9 8 9 8 7 9 9 9 9 8 7 6 5 4 9 8 7 6 5 4 3 5 6 9 7 6 5 4}, + mkRow!{6 5 4 5 8 9 8 9 5 9 8 7 6 5 4 1 2 3 6 7 8 9 2 4 5 4 5 8 9 8 9 8 7 8 9 8 9 4 9 8 9 8 7 6 5 4 3 2 3 9 6 5 6 3 9 8 9 2 9 4 9 8 7 8 9 8 9 1 3 4 5 6 9 6 5 6 6 7 8 9 9 7 6 5 4 3 4 9 9 7 9 8 5 6 7 8 9 5 4 3}, + mkRow!{5 4 3 4 5 6 7 8 9 9 7 6 5 4 3 0 4 4 5 6 7 8 9 9 7 9 6 9 8 7 6 5 6 9 8 7 8 9 8 7 6 9 9 5 4 3 2 1 9 8 9 6 7 9 8 7 8 9 8 9 4 3 6 5 6 7 8 9 4 5 6 9 8 7 4 4 5 6 7 9 9 8 7 6 5 1 3 4 5 9 8 7 6 7 8 9 9 4 3 2}, + mkRow!{6 5 4 5 6 7 8 9 3 2 9 8 4 3 2 1 2 6 7 7 8 9 7 8 9 8 9 1 9 9 7 6 7 8 9 6 7 8 9 6 5 9 8 7 5 9 9 0 9 7 8 9 9 8 7 6 7 6 7 8 9 2 3 4 7 8 9 6 5 9 9 8 7 6 3 2 4 5 6 7 8 9 6 5 4 3 5 6 7 8 9 8 7 8 9 7 8 9 2 1}, + mkRow!{7 6 5 7 7 8 9 7 9 3 9 6 5 4 3 2 4 5 7 8 9 4 6 9 8 7 9 0 1 9 8 9 8 9 4 5 6 7 8 9 4 7 9 8 9 8 8 9 8 6 6 7 8 9 6 5 5 5 6 7 8 9 4 5 6 7 8 9 7 8 9 9 7 5 4 3 8 6 7 8 9 8 7 8 5 4 6 7 8 9 3 9 8 9 5 6 7 8 9 2}, + mkRow!{9 8 6 9 8 9 5 6 7 9 8 7 6 5 6 6 5 6 8 9 2 3 9 8 7 6 8 9 2 4 9 9 9 2 3 6 5 8 9 2 3 5 7 9 8 7 6 7 6 5 5 7 8 9 9 4 3 4 5 6 7 8 9 6 9 8 9 9 8 9 9 8 7 6 5 6 7 8 9 9 3 9 9 9 6 5 7 9 9 3 2 1 9 3 4 5 6 9 4 3}, + mkRow!{4 9 8 9 9 5 4 2 3 4 9 8 9 8 7 8 6 7 9 0 1 9 8 7 6 5 7 8 9 9 8 9 9 1 2 3 4 5 9 5 4 5 6 7 9 6 5 4 3 4 3 4 6 7 8 9 2 3 6 7 8 9 9 9 8 9 8 7 9 9 9 9 8 7 8 9 8 9 9 1 2 3 9 8 7 9 8 9 5 2 1 0 1 2 3 9 7 8 9 4}, + mkRow!{3 4 9 6 5 4 3 1 2 9 9 9 8 9 8 8 7 8 9 3 2 9 8 7 6 4 3 9 9 7 7 7 8 9 3 4 5 7 8 9 5 9 7 9 8 7 6 3 2 1 2 9 7 8 9 2 1 2 3 4 9 9 9 8 7 8 9 6 9 8 9 8 9 8 9 7 9 7 8 9 9 4 5 9 8 9 9 5 4 3 2 4 2 6 7 8 9 9 6 5}, + mkRow!{2 1 2 9 6 9 2 0 9 8 9 8 7 5 9 9 9 9 8 9 9 8 7 6 5 3 2 9 8 6 5 6 7 8 9 6 8 9 9 7 6 7 8 9 9 8 5 4 9 0 9 8 9 9 4 3 2 3 5 6 7 9 8 7 6 7 8 9 8 7 6 7 8 9 7 6 6 6 5 9 8 9 6 8 9 8 7 6 5 4 3 5 3 4 9 9 9 8 7 6}, + mkRow!{3 0 9 8 9 8 9 9 8 7 5 9 5 4 3 4 5 6 7 8 9 9 8 7 6 4 3 4 9 7 4 5 6 7 8 9 9 3 9 8 7 8 9 9 8 7 6 9 8 9 8 7 8 9 6 4 3 4 9 8 9 8 9 6 5 5 7 9 9 6 5 6 7 8 9 5 4 3 4 8 7 8 9 9 9 9 8 7 8 5 4 5 4 5 6 7 8 9 9 8}, + mkRow!{5 9 8 7 6 7 8 9 7 6 4 3 4 3 2 3 5 6 8 9 6 7 9 8 6 5 4 9 8 6 5 6 7 8 9 4 3 2 3 9 8 9 2 0 9 8 9 8 7 6 7 6 9 8 7 9 7 6 8 9 8 7 6 5 3 4 6 7 9 9 6 7 8 9 9 4 3 2 3 4 6 9 4 3 9 9 9 8 9 6 6 6 5 6 7 9 9 1 0 9}, + mkRow!{9 8 7 6 5 6 7 8 9 7 3 2 1 0 1 2 6 7 8 9 5 7 7 9 7 6 5 6 9 7 6 8 9 9 6 5 5 3 9 9 9 8 9 9 9 9 8 7 6 5 4 5 8 9 8 9 8 7 9 7 9 9 4 3 2 3 5 6 7 8 9 8 9 9 8 6 5 5 4 5 6 8 9 9 8 9 9 9 9 8 7 7 6 7 9 8 8 9 1 2}, + mkRow!{9 9 6 5 4 7 8 9 8 9 4 3 2 3 2 4 5 8 9 3 4 5 6 9 8 8 9 8 9 8 9 9 3 8 9 6 6 9 8 9 9 7 8 8 9 9 9 8 9 6 5 6 7 8 9 3 9 9 8 6 5 4 3 2 1 3 3 7 8 8 9 9 3 2 9 7 6 7 6 6 8 9 9 8 7 8 9 4 3 9 8 9 7 9 8 7 7 8 9 4}, + mkRow!{9 8 5 4 3 6 5 6 7 9 6 4 5 4 6 5 6 7 8 9 5 6 7 8 9 9 9 9 9 9 0 1 2 7 8 9 9 8 7 9 8 6 7 7 8 9 1 9 9 9 8 7 8 9 1 2 4 5 9 9 8 9 4 3 0 1 2 4 5 6 7 8 9 1 9 8 7 8 7 9 9 8 6 5 6 7 8 9 2 3 9 9 9 8 6 5 6 7 8 9}, + mkRow!{8 7 4 3 2 3 4 5 6 8 9 5 6 9 7 7 8 9 9 7 6 7 9 9 8 7 8 8 9 5 4 3 5 6 9 9 8 7 6 5 9 4 5 6 9 1 0 1 9 9 9 8 9 4 3 3 5 6 9 8 7 8 7 5 1 2 3 8 6 9 8 9 1 0 1 9 8 9 9 8 7 6 5 4 5 6 7 8 9 4 5 9 8 7 5 4 5 6 8 9}, + mkRow!{7 6 5 4 5 6 5 6 9 9 9 6 7 9 8 9 9 9 8 9 7 8 9 8 7 6 8 7 8 9 5 9 6 8 9 9 8 9 5 4 3 2 3 9 8 9 1 9 8 7 8 9 6 5 9 7 6 7 9 9 6 5 4 3 2 3 4 7 8 9 9 9 9 9 9 9 9 3 9 8 6 7 6 3 4 5 6 9 9 9 9 8 7 6 4 3 4 7 9 9}, + mkRow!{8 7 6 5 7 7 6 7 8 9 8 7 8 9 9 8 7 6 7 9 9 9 0 9 6 5 5 6 9 9 9 8 9 9 9 8 7 6 4 3 2 1 9 8 7 8 9 8 7 6 9 8 7 9 8 9 9 9 8 9 8 8 6 5 3 4 5 6 7 9 9 8 7 8 8 9 1 2 9 9 5 4 3 2 3 4 5 6 7 8 9 9 8 7 5 4 5 9 8 9}, + mkRow!{9 8 7 8 9 8 7 8 9 5 9 8 9 9 8 7 6 5 6 7 8 9 1 9 5 3 4 8 9 8 6 7 8 9 3 9 8 7 6 4 3 2 9 7 6 7 9 7 6 5 4 9 9 8 7 8 7 6 7 9 9 8 7 6 4 5 6 7 8 9 9 9 6 6 7 8 9 9 8 7 6 5 4 3 4 6 6 7 8 9 6 9 8 7 6 5 9 9 7 8}, + mkRow!{4 9 8 9 2 9 8 9 3 4 5 9 9 9 9 9 7 3 2 6 7 8 9 8 9 1 9 9 8 7 5 9 9 5 4 9 9 8 7 5 4 9 8 6 5 6 8 9 6 5 3 9 8 7 6 5 4 5 6 8 9 9 9 8 7 6 7 9 9 9 9 5 4 5 6 7 8 9 9 8 7 8 5 4 5 7 8 9 9 4 5 6 9 9 7 9 8 7 6 7}, + mkRow!{3 4 9 4 3 4 9 2 1 0 2 9 8 7 9 7 6 5 3 5 6 7 9 6 7 9 8 8 9 5 4 8 9 6 9 8 9 9 7 6 9 8 7 6 4 5 6 8 9 3 2 1 9 8 7 4 3 6 5 7 8 9 9 9 8 9 8 9 9 9 8 9 3 4 5 6 8 9 9 9 8 9 8 7 6 8 9 3 4 3 4 9 2 3 9 8 9 8 5 6}, + mkRow!{4 5 9 9 9 5 9 9 2 1 2 9 8 5 9 8 7 8 7 6 7 9 4 5 9 9 7 6 5 4 3 7 8 9 9 7 8 9 9 9 8 7 6 4 3 4 5 8 9 2 1 0 9 7 6 5 2 3 4 5 9 8 9 9 9 9 9 9 7 6 7 4 2 3 4 7 9 7 8 9 9 2 9 8 7 9 4 2 1 2 9 8 9 9 8 7 6 4 3 2}, + mkRow!{5 9 8 7 8 9 7 8 9 3 9 8 7 3 2 9 8 9 8 7 9 6 5 6 7 9 8 7 6 6 5 6 7 9 5 6 7 9 9 9 6 5 4 3 2 3 5 6 8 9 2 9 8 9 7 7 3 5 5 9 8 7 8 9 9 9 8 7 6 5 4 3 1 2 3 4 5 6 7 8 9 3 9 9 9 8 9 1 0 9 8 7 8 9 7 6 5 4 2 1}, + mkRow!{9 9 9 6 4 5 6 7 8 9 8 7 6 5 3 4 9 9 9 8 9 7 6 9 8 9 9 8 9 8 7 7 8 9 4 5 9 8 9 8 7 2 1 0 1 2 4 7 8 9 9 8 7 8 9 8 9 6 6 9 8 6 7 8 9 9 9 9 7 6 2 1 0 1 2 3 4 5 6 9 9 9 8 9 8 7 8 9 9 9 7 6 5 9 8 7 5 4 3 2}, + mkRow!{8 9 6 5 3 4 7 8 9 9 9 8 9 6 7 6 7 9 9 9 9 8 9 9 9 2 3 9 8 9 8 8 9 1 2 9 8 7 6 5 4 3 2 1 5 3 4 5 9 9 8 7 6 7 8 9 8 7 9 6 6 5 3 9 9 8 7 8 9 4 3 2 3 2 3 4 5 6 7 8 9 6 7 8 9 6 7 9 8 9 8 5 4 5 9 8 7 6 4 4}, + mkRow!{7 9 9 6 7 5 6 7 8 9 4 9 9 8 9 7 9 8 9 9 8 9 9 8 7 5 4 6 7 8 9 9 2 0 9 8 9 8 7 8 5 4 3 2 6 4 5 6 7 8 9 6 5 6 9 9 9 9 8 5 4 3 2 4 4 5 6 7 8 9 5 3 4 3 4 5 6 7 8 9 6 5 3 9 4 5 9 8 7 6 5 4 3 4 6 9 8 7 5 6}, + mkRow!{6 7 8 9 7 6 7 8 9 2 3 4 9 9 8 9 8 7 8 9 7 5 5 9 9 7 6 7 8 9 6 4 3 9 8 7 6 9 8 9 7 6 5 3 4 5 6 8 8 9 2 3 4 7 8 9 9 9 7 8 4 2 1 3 3 4 5 6 7 8 9 4 6 4 5 6 7 9 9 8 7 6 2 1 3 4 5 9 8 7 6 7 2 3 4 5 9 8 8 7}, + mkRow!{5 6 7 8 9 7 8 9 2 1 2 9 8 9 7 6 5 6 7 8 9 4 4 0 9 8 9 8 9 8 9 5 9 8 7 6 5 6 9 9 9 8 7 6 5 6 7 8 9 2 1 2 5 9 9 9 8 7 6 5 2 1 0 1 2 3 4 7 8 9 9 8 7 5 6 7 8 9 9 7 6 4 3 0 2 3 9 8 7 8 5 4 1 2 3 4 5 9 9 8}, + mkRow!{4 4 4 9 8 9 9 9 1 0 9 8 7 6 6 5 4 5 6 7 9 3 2 1 9 9 7 9 8 7 8 9 9 7 9 5 4 5 6 9 9 9 8 9 8 7 8 9 7 4 2 3 6 8 9 9 9 8 5 4 3 2 1 2 3 4 5 8 9 6 5 9 9 8 7 8 9 9 9 5 4 3 2 1 3 9 8 7 6 5 4 3 2 4 4 5 6 7 8 9}, + mkRow!{3 2 3 9 7 8 9 8 9 9 8 7 6 5 3 4 3 6 7 8 9 4 9 9 8 7 6 4 7 6 9 8 8 6 7 4 3 4 6 7 8 9 9 4 9 8 9 8 6 5 6 4 7 9 9 9 8 7 6 5 6 4 2 3 4 5 6 7 8 9 4 4 5 9 8 9 3 9 8 7 6 5 4 5 4 9 9 9 7 8 5 4 5 7 5 6 7 8 9 9}, + mkRow!{4 5 9 8 5 6 6 7 9 8 9 5 4 3 2 1 2 5 6 7 8 9 8 6 9 8 4 3 4 5 9 7 6 5 4 3 2 3 5 6 9 7 4 3 2 9 2 9 9 8 7 5 6 7 8 9 9 8 7 6 7 6 3 4 5 6 7 9 9 5 2 3 4 7 9 9 2 0 9 8 7 6 5 7 9 8 7 9 8 7 6 5 6 9 6 7 8 9 9 8}, + mkRow!{5 9 8 6 4 5 4 6 7 7 8 9 4 3 1 0 3 4 5 8 9 8 9 5 4 9 9 4 5 6 9 8 7 4 3 2 1 6 7 8 9 6 5 4 1 0 1 2 3 9 8 6 7 8 9 4 6 9 8 7 8 7 4 7 6 7 9 6 5 4 3 4 5 6 7 8 9 9 9 9 9 7 6 7 9 8 6 5 9 8 7 6 8 9 7 8 9 8 7 7}, + mkRow!{6 7 9 7 3 2 3 4 7 6 9 8 9 3 2 1 2 3 8 9 9 7 8 9 9 9 8 9 6 8 9 9 8 7 4 3 4 5 8 9 6 5 4 3 2 1 2 4 4 5 9 7 8 9 3 3 4 2 9 8 9 6 5 6 7 8 9 7 6 5 4 6 7 8 8 9 9 8 9 9 9 8 9 8 9 9 9 6 8 9 8 9 9 9 8 9 8 7 5 6}, + mkRow!{8 9 8 3 2 1 2 3 4 5 6 7 8 9 3 2 3 4 6 9 8 6 9 9 7 8 7 9 9 9 9 8 7 6 5 6 5 6 9 8 7 6 5 4 3 4 4 5 6 7 9 8 9 3 2 1 0 1 2 9 8 9 7 7 8 9 9 8 7 6 9 8 8 9 9 9 8 7 8 9 9 9 9 9 3 9 8 7 9 1 9 9 9 9 9 5 9 8 4 3}, + mkRow!{9 9 7 5 9 0 3 5 5 9 7 8 9 9 9 4 5 6 9 9 7 5 9 8 6 5 6 7 8 9 6 9 8 7 6 7 7 8 9 9 8 7 6 5 4 5 5 8 7 8 9 9 6 5 3 2 1 4 3 9 7 9 8 9 9 8 9 9 8 9 8 9 9 0 1 9 7 6 7 8 9 8 9 1 2 3 9 8 9 0 9 8 9 8 9 4 3 2 3 2}, + mkRow!{4 5 9 9 8 9 9 6 7 8 9 9 9 9 8 9 7 9 8 7 5 4 5 7 8 4 5 6 9 5 5 6 9 8 9 8 8 9 2 3 9 9 7 6 5 8 6 9 8 9 9 8 7 9 4 3 2 9 9 7 6 5 9 5 6 7 8 9 9 8 7 8 9 1 2 9 6 5 4 5 6 7 8 9 3 4 5 9 9 9 8 7 6 7 8 9 2 1 0 1}, + mkRow!{5 9 8 7 7 8 8 9 8 9 9 9 9 8 7 8 9 9 8 5 4 3 4 6 2 3 4 9 5 4 3 4 5 9 8 9 9 0 1 9 8 9 8 7 7 9 7 8 9 9 8 9 9 8 9 4 9 8 7 6 5 4 3 4 5 6 9 9 8 7 6 7 9 3 9 8 7 4 3 9 7 9 9 9 9 7 6 7 8 9 7 6 5 5 5 8 9 3 1 2}, + mkRow!{9 8 7 6 5 6 7 8 9 9 8 9 8 7 6 7 9 8 7 6 6 2 1 0 1 2 6 8 9 4 2 3 9 8 7 8 9 2 9 8 6 2 9 9 8 9 8 9 9 8 7 7 5 6 8 9 9 8 7 5 5 3 2 3 4 9 8 6 5 6 5 6 8 9 9 9 9 9 9 8 9 0 1 9 8 9 7 8 9 9 8 5 4 3 4 7 8 9 2 3}, + mkRow!{9 8 9 5 4 5 6 7 9 8 7 8 6 5 4 5 6 9 8 7 7 8 2 3 2 3 5 8 9 3 1 9 8 7 6 9 9 4 9 7 5 4 5 6 9 9 9 9 9 8 6 5 4 5 6 9 7 7 6 4 4 2 1 2 9 8 7 5 4 5 4 5 7 8 8 9 8 7 8 7 8 9 9 8 7 8 9 9 9 8 7 6 3 2 7 6 7 8 9 4}, + mkRow!{8 7 5 4 2 3 4 5 9 6 5 6 5 4 3 4 7 9 7 6 5 4 3 4 5 6 6 7 8 9 9 8 7 6 5 6 8 9 8 7 6 7 6 7 8 9 9 8 8 7 8 4 3 4 5 9 6 5 4 3 2 1 0 9 8 7 6 5 3 2 3 4 5 6 7 8 9 6 5 6 7 8 9 7 6 7 8 9 8 7 6 5 2 1 2 5 6 7 8 9}, + mkRow!{9 7 6 4 3 4 5 7 8 9 4 3 2 1 2 3 4 5 9 7 6 5 4 5 6 7 7 9 9 9 9 8 7 5 4 5 7 8 9 8 7 8 9 9 9 9 8 7 9 6 5 1 2 9 9 8 7 9 6 4 5 2 1 3 9 8 9 9 2 1 2 3 7 8 9 9 2 3 4 5 6 9 8 9 5 7 8 9 7 6 5 4 3 0 1 3 8 8 9 4}, + mkRow!{9 8 6 5 7 5 6 8 9 6 5 4 3 0 1 6 5 6 9 8 7 6 7 6 7 8 9 3 4 9 8 7 6 6 3 4 6 7 8 9 8 9 4 3 4 5 9 6 5 4 3 2 9 8 9 9 9 8 7 5 9 3 2 4 5 9 9 8 2 0 1 2 6 9 2 1 0 1 2 3 7 9 7 8 4 6 9 8 6 5 4 3 2 1 2 3 9 9 9 5}, + mkRow!{2 9 7 6 7 8 7 9 9 8 6 5 2 1 2 7 6 7 8 9 8 8 8 7 8 9 3 2 3 9 8 7 5 4 2 3 7 8 9 9 9 5 3 2 3 9 8 7 6 5 4 4 9 7 9 3 2 9 8 7 8 4 3 5 7 9 8 7 6 2 2 4 5 9 3 3 1 2 6 4 9 8 6 5 3 7 8 9 7 8 5 4 3 4 3 4 6 7 8 9}, + mkRow!{1 2 9 7 8 9 8 9 9 9 7 6 3 3 4 6 7 8 9 3 9 9 9 8 9 9 0 1 2 4 9 8 3 2 1 2 6 9 8 9 7 6 2 1 2 3 9 8 7 9 5 9 8 6 8 9 1 0 9 8 7 6 5 6 7 8 9 9 5 4 3 4 9 8 9 4 5 9 8 9 8 9 7 6 2 2 3 9 8 9 6 5 6 5 6 5 6 9 9 4}, + mkRow!{0 1 2 9 9 6 9 8 9 9 8 7 4 5 5 7 8 9 5 2 1 2 9 9 9 8 9 9 4 9 8 7 4 4 3 3 5 6 7 8 9 2 1 0 1 4 5 9 9 8 9 8 9 5 7 8 9 1 2 9 8 7 6 7 9 9 8 7 6 6 4 9 8 7 8 9 6 7 9 8 7 6 5 1 0 1 4 7 9 9 7 6 7 7 8 7 8 9 2 3}, + mkRow!{1 9 9 8 6 5 4 6 9 8 9 8 6 6 6 7 8 9 4 3 2 9 8 9 6 7 8 8 9 8 7 6 5 6 5 6 7 8 9 9 4 3 2 3 4 5 6 9 8 7 6 7 5 4 5 7 9 2 9 9 9 8 7 8 9 8 9 8 7 8 9 8 7 6 9 8 9 8 9 9 8 9 3 2 4 2 3 5 6 9 8 9 8 8 9 8 9 2 1 2}, + mkRow!{9 8 8 7 6 4 3 5 6 7 8 9 8 9 8 9 9 6 5 5 9 8 7 6 5 6 7 7 5 9 8 7 6 7 7 7 9 9 8 8 9 4 3 4 5 6 7 9 6 6 5 3 4 3 8 6 8 9 8 7 9 9 8 9 6 7 8 9 8 9 8 7 6 5 6 7 8 9 1 0 9 8 9 4 5 3 5 6 7 8 9 7 9 9 9 9 9 9 0 9}, + mkRow!{8 7 9 8 4 3 2 3 4 5 9 9 9 2 9 8 9 7 8 9 8 7 6 5 4 3 5 6 4 5 9 8 7 8 9 8 9 7 6 7 8 9 4 6 7 7 9 8 5 4 3 2 1 2 3 5 7 8 9 6 8 9 9 4 5 6 8 9 9 8 7 9 7 4 5 6 9 9 2 9 8 7 8 9 7 4 5 9 8 9 5 6 7 8 9 9 9 8 9 8}, + mkRow!{9 6 5 4 3 2 1 4 5 6 8 9 0 1 9 7 8 9 9 0 9 7 5 6 3 2 3 4 3 4 6 9 8 9 9 9 5 4 5 6 7 9 5 9 8 9 8 7 7 3 2 1 0 1 7 6 7 9 3 5 6 7 9 5 6 7 9 9 9 9 6 5 6 3 5 6 7 8 9 8 7 6 7 8 9 5 6 7 9 5 4 5 6 7 8 9 8 7 6 7}, + mkRow!{8 7 6 5 4 3 0 1 2 7 7 8 9 9 8 6 7 9 2 1 9 8 4 3 2 1 0 1 2 4 5 6 9 9 8 7 6 3 4 5 8 9 9 8 9 8 7 6 5 4 3 2 1 2 8 7 9 3 2 4 5 7 8 9 9 8 9 9 8 7 9 4 3 2 3 7 9 9 8 7 6 5 6 9 8 9 7 8 9 9 3 4 9 8 9 8 7 5 4 5}, + mkRow!{9 8 7 6 5 4 1 2 3 5 6 9 9 9 7 5 6 7 9 2 3 9 9 8 3 4 3 2 3 6 7 8 9 8 7 6 5 4 5 6 9 8 7 6 5 9 8 7 6 5 4 3 2 3 4 8 9 2 1 2 5 9 8 9 9 9 9 9 8 6 5 4 2 1 2 6 7 8 9 6 5 4 5 6 7 8 9 9 6 8 9 9 9 9 8 9 6 5 3 6}, + mkRow!{2 9 8 7 6 7 8 3 4 6 9 8 8 8 5 4 5 6 8 9 4 9 8 7 6 5 4 3 4 7 8 9 4 9 8 7 6 5 9 7 9 9 8 7 6 7 9 8 7 6 5 4 3 5 6 9 4 3 0 1 4 5 7 9 9 8 9 8 7 6 5 3 1 0 4 5 8 9 7 5 4 3 4 5 6 9 1 2 5 6 7 8 9 8 7 8 9 7 4 7}, + mkRow!{1 2 9 8 8 9 8 7 6 9 8 7 6 7 4 3 4 5 7 8 9 9 9 8 7 6 5 4 5 7 9 1 3 4 9 8 7 6 7 8 9 3 9 8 9 8 9 9 8 7 6 5 4 6 7 8 9 7 1 2 3 4 6 8 9 6 7 9 8 7 4 3 2 2 3 6 9 8 6 4 2 1 2 5 7 8 9 3 4 7 8 9 6 7 6 7 8 9 5 8}, + mkRow!{0 1 9 9 9 5 9 8 9 9 7 6 5 3 2 2 3 4 6 7 8 9 7 9 9 8 6 7 8 9 8 9 9 5 9 9 9 7 8 9 0 2 3 9 9 9 9 9 9 8 8 7 6 7 8 9 9 5 4 3 4 6 7 9 6 5 6 7 9 8 5 4 3 9 8 7 8 9 5 4 3 2 3 4 8 9 9 4 5 8 9 6 5 6 5 6 9 8 9 9}, + mkRow!{9 9 8 6 5 4 5 9 9 8 7 5 4 3 0 1 2 5 8 8 9 7 6 5 8 9 7 8 9 5 6 7 8 9 8 7 9 8 9 5 2 3 5 6 9 9 9 8 8 9 9 8 7 8 9 9 8 7 5 5 6 9 8 9 7 6 9 8 9 9 8 6 4 5 9 8 9 7 6 5 5 3 6 5 6 7 8 9 6 9 6 5 4 5 4 5 6 7 8 9}, + mkRow!{8 7 6 5 4 3 4 4 5 9 6 4 3 2 1 3 4 7 8 9 7 6 5 4 6 9 8 9 3 4 5 6 7 8 9 6 7 9 9 4 3 4 5 7 8 9 7 6 7 8 9 9 8 9 6 8 9 8 6 7 8 9 9 9 8 9 8 9 8 9 7 6 5 8 9 9 9 8 7 6 9 8 7 6 7 8 9 8 7 8 9 4 3 4 3 4 5 8 9 8}, + mkRow!{9 8 7 6 3 2 1 3 9 8 9 5 4 3 4 4 5 6 9 9 8 7 6 9 7 9 9 1 2 3 6 7 8 9 4 5 6 9 8 7 6 5 6 7 9 9 8 5 6 7 8 9 9 5 4 7 7 9 7 8 9 7 6 8 9 9 7 6 7 9 8 7 6 7 8 9 2 9 8 7 8 9 8 7 8 9 9 9 8 9 9 3 2 1 2 3 4 9 8 7}, + mkRow!{2 9 9 5 4 5 6 9 8 7 8 9 6 4 7 6 7 7 8 9 9 8 9 8 9 7 5 4 3 4 7 8 9 4 3 1 2 3 9 8 7 6 8 9 8 7 5 4 5 8 7 8 9 2 3 5 6 9 8 9 6 6 5 9 8 7 6 5 4 5 9 9 7 8 9 4 3 4 9 9 9 6 9 8 9 9 9 9 9 9 8 9 3 9 3 5 9 8 7 6}, + mkRow!{1 9 8 7 5 6 9 8 7 6 7 8 9 5 6 9 8 9 9 2 4 9 8 7 8 9 6 5 4 5 6 9 6 5 3 2 3 4 6 9 8 7 9 8 7 6 5 3 4 5 6 9 0 1 2 3 4 5 9 6 4 3 4 5 9 8 7 4 3 2 1 9 8 9 8 9 4 9 8 7 6 5 6 9 9 9 8 9 9 8 7 8 9 8 9 6 7 9 6 5}, + mkRow!{0 1 9 8 6 7 8 9 7 5 6 7 9 9 7 8 9 5 4 3 9 9 8 6 7 8 9 6 5 6 7 8 9 9 4 3 4 5 9 9 9 8 9 9 8 7 5 4 5 6 7 9 9 2 3 4 6 9 8 7 6 2 3 9 7 6 4 3 2 1 0 1 9 6 7 8 9 8 7 6 5 4 5 6 9 9 7 9 5 4 6 7 5 7 7 9 9 6 5 4}, + mkRow!{3 2 3 9 9 8 9 7 6 4 5 6 7 8 9 9 9 6 7 9 7 6 5 5 6 8 9 9 7 7 8 9 7 8 9 4 9 9 7 8 9 9 3 0 9 8 6 5 6 8 9 7 8 9 6 5 9 8 7 5 4 3 4 9 9 8 9 4 3 3 1 2 4 5 9 9 9 9 8 7 6 5 7 9 8 7 6 7 6 3 2 3 4 5 6 7 8 9 4 3}, + mkRow!{4 5 9 9 8 9 9 8 6 5 6 9 8 9 9 9 8 7 9 8 6 5 4 4 5 7 9 8 9 8 9 7 6 7 8 9 8 7 6 7 8 9 2 1 2 9 7 8 9 9 7 6 7 8 9 6 7 9 8 7 5 6 9 8 9 9 8 7 6 5 3 5 5 6 7 8 9 9 9 8 7 9 9 8 7 6 5 4 3 4 1 2 9 6 7 9 9 4 3 2}, + mkRow!{5 9 8 8 7 6 7 9 7 8 9 6 9 7 8 9 9 9 8 7 6 5 3 3 4 5 6 7 8 9 3 4 5 8 9 8 9 6 5 6 7 8 9 3 9 9 8 9 9 7 6 5 6 7 8 9 8 9 9 9 6 9 8 7 6 5 9 8 8 9 4 6 7 7 8 9 8 9 9 9 9 8 9 9 8 7 9 3 2 1 0 9 8 9 9 8 9 9 4 9}, + mkRow!{9 8 7 6 5 4 3 9 8 9 6 5 6 6 7 8 9 8 7 6 5 4 1 2 5 6 7 8 9 4 2 3 4 9 8 7 6 5 4 5 6 7 9 9 8 9 9 9 8 9 7 6 7 8 9 6 9 9 9 9 9 8 7 6 5 4 6 9 9 6 5 7 8 9 9 6 7 9 9 9 8 7 9 9 9 9 8 9 3 4 9 8 7 8 5 6 7 8 9 8}, + mkRow!{6 5 6 5 4 3 2 3 9 1 2 3 4 5 6 9 9 9 8 5 4 3 2 7 6 8 8 9 5 4 3 4 5 6 9 8 5 4 3 1 0 9 8 8 7 6 7 6 7 8 9 7 8 9 9 5 9 8 7 9 9 9 8 8 6 3 2 9 8 7 6 8 9 5 4 5 6 7 8 9 5 6 8 9 9 8 7 8 9 9 8 7 6 7 4 7 9 9 6 7}, + mkRow!{5 4 3 2 1 0 1 2 3 9 3 4 5 8 9 9 9 9 8 6 6 7 9 8 9 9 9 7 6 7 5 6 6 9 8 7 6 5 4 5 9 8 7 8 5 4 3 5 6 7 8 9 9 6 8 9 8 7 6 8 9 9 9 9 9 9 1 9 9 8 7 9 5 4 3 5 7 8 9 4 4 5 6 9 8 7 6 7 9 9 9 8 4 3 2 3 4 5 5 6}, + mkRow!{8 5 5 6 2 1 4 3 9 8 9 9 6 7 9 9 8 9 8 7 7 8 9 9 9 9 9 8 7 8 7 8 9 9 9 8 7 6 5 9 8 7 6 5 4 3 2 4 8 8 9 5 4 5 9 8 7 6 5 7 8 9 9 9 8 8 9 8 9 9 8 9 9 5 5 6 8 9 5 3 3 4 9 8 9 6 5 6 7 8 9 6 5 4 0 1 2 3 4 5}, + mkRow!{7 6 7 9 3 4 5 9 8 7 8 8 9 9 8 8 7 5 9 9 8 9 9 7 8 8 9 9 8 9 8 9 9 9 9 9 9 8 7 8 9 9 7 6 5 2 1 0 1 9 7 9 3 9 8 7 6 5 4 5 6 7 9 8 7 6 6 7 8 9 9 9 8 7 8 7 9 5 4 1 2 9 8 7 6 5 4 5 6 9 9 9 6 4 1 4 4 5 6 9}, + mkRow!{8 7 9 8 9 5 6 9 8 6 6 7 9 8 7 6 5 4 3 5 9 8 7 6 7 6 9 8 9 9 9 9 9 8 8 8 9 9 8 9 0 1 9 6 5 4 2 1 4 5 6 8 9 9 8 6 5 4 3 3 4 9 8 9 6 5 5 6 7 9 2 1 9 8 9 9 5 4 3 0 1 2 9 6 5 4 3 4 7 5 9 8 9 3 2 3 4 5 7 8}, + mkRow!{9 9 8 7 8 9 9 7 6 5 4 9 8 7 6 5 4 3 2 4 8 9 6 5 6 5 9 7 8 9 9 9 8 7 6 7 9 9 9 3 1 9 8 7 8 4 3 2 3 6 7 9 8 7 6 5 4 3 1 2 9 8 7 6 5 4 4 5 9 8 9 2 3 9 6 5 4 3 2 1 2 9 8 7 7 5 2 1 2 3 8 7 8 9 3 4 5 6 7 9}, + mkRow!{9 7 6 5 9 7 8 9 6 4 3 4 9 8 7 6 4 2 1 2 7 8 9 4 5 4 5 6 7 9 9 8 7 6 5 6 8 9 4 3 2 3 9 8 7 5 6 3 4 7 8 9 9 8 8 6 5 1 0 1 2 9 8 7 6 2 3 4 6 7 8 9 9 9 8 7 6 5 3 2 3 5 9 9 9 4 3 0 1 4 5 6 7 8 9 6 8 7 8 9}, + mkRow!{8 9 6 4 5 6 8 9 9 1 2 5 6 9 9 5 4 3 2 3 5 9 9 3 2 3 4 5 6 7 9 9 8 7 4 5 9 8 5 5 9 4 5 9 8 7 8 4 5 8 9 9 9 9 7 7 6 2 1 2 9 8 7 5 4 3 4 5 6 8 9 7 8 9 9 8 8 6 4 3 5 6 9 8 6 5 4 3 2 3 6 8 9 9 8 7 9 8 9 7}, + mkRow!{7 8 4 3 4 5 6 9 8 9 3 4 6 9 8 6 5 4 8 7 6 7 8 9 1 2 3 4 8 7 8 9 9 6 5 9 8 7 6 9 8 9 6 8 9 8 9 5 6 9 9 9 8 7 6 5 4 3 4 3 4 9 8 6 6 4 5 7 7 9 7 6 7 8 7 9 9 8 5 4 6 7 8 9 7 8 5 6 5 4 5 9 9 9 9 8 9 9 8 6}, + mkRow!{6 5 3 2 3 4 5 6 7 8 9 6 7 9 8 7 6 6 9 8 7 8 9 1 0 1 2 3 5 6 7 8 9 7 6 7 9 8 9 8 7 8 9 9 9 9 7 6 7 8 9 9 9 9 7 6 5 5 6 4 5 6 9 8 7 5 6 8 9 8 6 5 8 7 6 9 8 7 6 7 7 8 9 9 8 9 8 7 6 5 6 7 8 9 9 9 7 6 7 5}, + mkRow!{4 3 2 1 2 3 4 7 8 9 8 7 9 2 9 9 8 7 9 9 8 9 8 9 2 3 4 4 5 7 9 9 9 9 9 9 9 9 8 7 6 8 9 9 8 9 9 9 8 9 9 9 8 9 8 9 6 6 7 5 8 7 8 9 8 6 7 9 8 7 8 4 5 4 5 9 9 8 9 8 9 9 8 9 9 1 9 9 7 8 7 8 9 9 8 9 6 5 4 3}, + mkRow!{3 2 1 0 3 4 5 8 9 7 9 8 9 1 2 9 9 9 7 9 9 8 7 8 9 4 5 6 6 8 9 9 8 8 8 7 8 9 9 6 5 6 9 8 7 9 3 2 9 9 9 8 7 8 9 8 9 7 9 6 9 8 9 5 9 7 8 9 7 6 4 3 2 3 4 8 9 9 4 9 6 6 7 9 9 0 1 9 8 9 9 9 7 8 7 9 5 4 3 2}, + mkRow!{4 3 2 1 2 9 6 8 9 6 5 9 1 0 9 7 8 5 6 8 9 7 6 7 8 9 6 7 7 8 9 8 7 6 5 6 9 8 9 5 4 5 4 7 6 8 9 1 0 9 8 7 6 5 6 7 9 9 8 9 2 9 2 4 9 8 9 9 8 6 5 2 1 4 6 7 8 9 3 2 4 5 6 7 8 9 2 9 9 5 6 9 6 5 6 7 9 3 2 1}, + mkRow!{6 5 4 2 3 8 9 9 8 9 4 3 2 9 7 6 5 4 5 7 3 4 5 7 7 8 9 9 8 9 3 9 8 5 4 9 8 7 6 4 3 4 3 4 5 6 8 9 1 2 9 8 5 4 5 6 9 8 7 9 1 0 1 2 5 9 7 8 9 5 4 3 0 3 4 9 9 6 4 3 4 6 7 9 9 9 9 8 7 6 7 8 9 4 5 7 8 9 1 0}, + mkRow!{9 5 4 3 5 7 8 9 7 8 9 4 9 8 6 5 4 3 4 8 2 3 4 5 6 7 8 9 9 3 2 9 8 7 6 7 9 8 6 3 2 1 2 3 4 7 8 9 2 9 9 9 9 3 5 7 9 7 6 8 9 1 3 3 4 5 6 7 8 9 4 2 1 2 5 8 9 7 5 9 5 9 8 9 9 9 8 9 8 7 8 9 4 3 4 6 7 8 9 1}, + mkRow!{8 7 5 4 6 9 9 5 6 7 8 9 9 8 7 6 3 2 1 0 1 2 5 6 7 8 9 3 2 0 1 2 9 8 7 8 9 7 5 6 1 0 1 3 5 6 7 8 9 8 9 9 8 9 6 9 8 6 5 7 8 9 9 4 5 6 7 8 9 9 5 3 2 3 6 7 9 7 6 7 7 8 9 8 7 9 7 5 9 9 9 8 9 2 3 4 8 9 8 9}, + mkRow!{8 7 6 7 9 7 6 4 5 6 9 1 2 9 8 6 5 4 2 1 5 3 4 5 7 9 5 4 3 1 4 3 4 9 8 9 7 5 4 3 2 1 2 4 6 7 8 9 6 7 9 8 7 8 9 8 7 6 4 5 9 7 8 9 6 8 8 9 9 8 9 4 3 4 8 9 9 9 7 8 8 9 6 7 6 8 9 9 9 7 6 7 9 0 1 9 9 8 7 8}, + mkRow!{9 8 9 8 9 9 5 3 4 5 8 9 3 4 9 8 5 4 3 4 6 4 7 6 8 9 6 5 3 2 6 4 5 6 9 9 9 6 5 6 3 5 3 4 7 8 9 4 5 9 8 7 6 7 8 9 5 4 3 4 5 6 7 8 9 9 9 9 8 7 8 9 4 5 9 8 7 8 9 9 9 6 5 4 5 9 9 8 7 6 5 8 9 1 9 8 9 7 6 7}, + mkRow!{3 9 1 9 8 9 4 2 3 6 7 8 9 9 8 7 6 5 5 5 7 5 8 8 9 8 7 6 5 3 9 5 6 7 8 9 8 7 6 7 7 6 4 5 8 9 4 3 9 8 7 6 5 6 9 8 9 5 2 3 4 5 8 9 9 9 8 7 7 6 7 8 9 6 7 9 5 6 5 8 9 9 8 7 6 9 8 9 8 7 6 7 9 9 8 7 5 6 5 6}, + mkRow!{2 1 0 9 7 8 9 1 2 9 8 9 4 2 9 8 9 6 7 9 8 9 9 9 9 9 8 9 7 9 8 9 7 8 9 9 9 9 7 8 8 7 9 7 8 9 5 2 0 9 9 5 4 3 6 7 8 9 1 2 5 6 7 8 9 9 9 6 5 4 5 6 8 9 8 9 4 3 4 7 8 9 9 8 7 9 7 6 9 8 7 9 8 7 6 8 4 5 4 5}, + mkRow!{3 9 9 8 6 7 9 2 9 8 9 3 2 1 2 9 8 7 8 9 9 6 8 9 9 9 9 8 9 8 7 8 9 9 9 9 9 9 8 9 9 8 9 9 9 7 6 2 1 9 8 6 5 4 5 6 7 8 9 7 6 7 8 9 8 9 8 7 6 8 6 7 9 9 9 7 6 4 5 6 7 8 9 9 8 9 6 5 7 9 9 8 9 6 5 4 3 3 3 4}, + mkRow!{9 8 7 7 5 6 8 9 9 7 8 9 3 2 4 5 9 8 9 3 4 5 6 7 8 9 9 7 6 7 6 7 9 8 9 8 9 9 9 3 4 9 8 7 6 5 4 3 9 9 9 7 8 7 6 7 8 9 4 9 9 8 9 5 6 9 9 8 7 9 7 8 9 8 9 8 7 9 6 7 8 9 7 6 9 8 7 6 8 9 8 7 8 9 9 3 2 1 2 3}, + mkRow!{9 9 6 5 4 7 9 8 7 6 7 8 9 3 4 6 7 9 0 1 2 3 7 8 9 9 7 6 5 8 5 9 8 7 6 7 8 8 9 1 9 8 9 9 7 6 9 9 8 9 9 8 9 8 7 8 9 6 3 2 1 9 3 4 9 8 7 9 8 9 8 9 6 7 8 9 9 8 9 9 9 9 9 5 3 9 8 7 9 8 7 6 6 7 8 9 9 0 1 4}, + mkRow!{7 6 5 4 3 9 8 7 6 5 6 9 5 4 5 6 9 8 9 5 4 5 6 9 9 9 8 5 4 3 4 9 7 6 5 6 7 7 8 9 8 7 8 9 8 9 8 9 7 8 4 9 7 9 8 9 6 5 4 9 0 1 2 9 9 9 6 7 9 3 9 3 5 6 7 9 8 7 9 8 9 9 8 9 2 0 9 8 9 9 8 5 4 5 6 7 8 9 2 3}, + mkRow!{8 7 4 3 2 1 9 7 5 4 9 8 9 5 7 9 8 7 9 9 5 6 7 8 9 4 9 6 9 2 9 8 9 5 4 3 4 6 7 8 9 6 6 7 9 9 7 6 5 4 3 4 6 5 9 8 9 6 9 8 9 2 9 8 7 6 5 4 3 2 1 2 3 5 6 9 7 6 7 6 7 6 7 8 9 1 5 9 9 9 5 5 3 4 5 6 7 8 9 5}, + mkRow!{9 8 5 4 5 9 8 8 5 3 8 7 8 9 9 8 7 6 7 8 9 7 9 9 2 3 4 9 8 9 9 7 8 9 3 2 3 7 8 9 6 5 5 6 7 9 8 7 6 2 1 0 3 4 6 7 8 9 9 7 9 3 4 9 8 9 6 5 4 1 0 1 2 9 9 8 7 5 6 5 4 5 6 7 9 2 3 4 9 7 4 3 2 3 5 6 7 8 9 6}, + mkRow!{8 7 6 5 9 9 7 5 4 2 3 6 7 8 8 9 6 5 8 9 8 9 3 2 1 0 9 8 7 8 5 6 7 8 9 3 4 5 7 8 9 3 4 5 6 7 9 8 5 4 2 1 2 3 5 8 9 9 7 6 7 9 5 6 9 8 9 4 3 2 1 2 9 8 7 6 5 4 3 2 3 6 7 9 9 3 9 9 8 6 3 2 1 2 4 5 5 6 8 9}, + mkRow!{9 8 7 9 8 7 6 5 2 1 3 4 5 6 7 8 9 4 7 6 7 8 9 3 2 2 9 7 6 5 4 5 6 9 9 6 5 9 8 9 3 1 2 3 9 9 8 7 6 5 3 4 5 6 9 9 6 7 6 5 6 7 9 7 9 7 7 9 9 3 2 3 4 9 9 7 4 3 2 1 4 5 6 7 8 9 8 7 6 5 4 2 0 1 2 3 4 6 7 8}, + mkRow!{5 9 8 9 8 5 4 3 1 0 4 5 6 8 9 9 4 3 4 5 6 7 8 9 4 5 9 8 7 6 5 7 8 9 8 7 6 7 9 2 1 0 5 7 8 9 9 9 7 9 4 5 6 7 8 9 5 4 5 4 6 9 8 9 8 6 5 7 8 9 9 4 5 6 9 6 5 4 9 2 3 6 7 9 9 3 9 8 7 6 5 6 2 9 3 4 6 8 8 9}, + mkRow!{4 1 9 8 7 6 4 3 2 1 6 9 7 9 7 4 3 2 5 7 7 8 9 9 8 6 7 9 9 8 6 9 9 3 9 8 9 8 9 3 2 3 4 5 7 8 9 9 9 8 9 6 9 8 9 5 4 3 5 3 5 9 7 6 9 8 4 5 6 7 8 9 6 9 8 9 7 9 8 9 4 7 8 9 3 2 1 9 8 7 6 5 4 8 9 5 6 7 8 9}, + mkRow!{3 0 1 9 8 7 8 9 3 2 7 8 9 7 6 5 5 3 4 5 6 8 9 9 8 7 9 9 9 8 7 8 9 4 5 9 9 9 5 4 3 4 5 6 9 9 9 9 8 7 8 9 8 9 5 4 3 2 1 2 3 4 9 5 4 3 2 3 7 8 9 9 9 8 7 8 9 8 7 8 9 9 9 4 2 1 0 1 9 8 7 6 5 6 7 8 7 8 9 5}, + mkRow!{2 1 2 3 9 8 9 5 4 9 8 9 8 9 8 7 6 8 9 6 7 9 4 3 9 9 8 9 9 9 8 9 6 5 6 9 8 7 6 5 4 5 6 7 8 9 9 8 7 6 7 8 7 8 9 5 9 4 3 4 5 9 8 9 5 4 3 4 8 9 9 9 8 7 6 9 5 5 6 6 7 8 9 4 3 2 1 9 8 9 9 9 8 7 9 9 8 9 6 4}, + mkRow!{4 2 5 7 8 9 8 6 7 8 9 7 7 6 9 8 7 8 9 9 8 9 5 4 9 8 7 8 9 9 9 8 7 8 8 9 9 8 7 6 9 7 7 8 9 9 9 9 6 5 4 5 6 7 8 9 7 5 4 5 9 8 7 8 9 5 4 5 9 9 9 8 7 6 5 4 4 3 4 5 6 9 6 5 4 5 9 8 7 6 9 9 9 9 4 5 9 9 9 5}, + mkRow!{4 3 4 5 9 9 8 7 8 9 7 6 4 5 6 9 8 9 7 9 9 9 6 9 9 7 6 7 8 9 9 9 8 9 9 6 7 9 8 7 9 8 8 9 4 9 8 7 6 4 3 4 9 8 9 9 8 6 9 6 9 7 6 7 8 9 5 6 7 8 9 9 8 7 6 3 1 2 3 6 7 8 9 6 7 9 8 7 6 5 8 9 5 4 3 5 6 7 8 9}, + mkRow!{5 6 5 6 7 9 9 8 9 3 2 1 2 6 9 8 9 7 5 7 7 8 9 8 7 6 5 6 7 8 7 8 9 6 4 5 9 8 9 8 9 9 9 2 3 5 9 8 6 5 4 5 7 9 5 4 9 9 8 9 9 6 5 6 9 8 7 7 8 9 3 4 9 8 7 4 5 6 4 9 8 9 9 8 9 9 9 6 5 4 7 8 9 3 2 3 5 8 8 9}, + mkRow!{6 7 6 7 8 9 9 9 6 5 4 3 5 9 8 7 6 5 4 5 6 9 8 7 6 5 4 4 6 5 6 7 8 9 5 9 8 7 6 9 2 1 0 1 2 4 5 9 8 6 7 8 8 9 4 2 9 8 7 9 8 7 4 6 8 9 9 8 9 3 2 9 8 7 6 5 6 7 8 9 9 1 0 9 5 9 8 7 6 5 6 7 9 2 0 2 3 9 7 9}, + mkRow!{9 8 9 8 9 9 9 8 7 6 7 8 6 9 8 6 5 4 3 2 1 0 9 8 7 6 3 2 3 4 7 8 9 9 9 8 7 6 5 4 3 2 1 2 3 5 6 9 8 7 8 9 9 6 5 9 8 7 6 5 3 2 3 4 9 0 1 9 1 0 1 2 9 8 8 6 7 9 9 5 4 3 2 3 4 5 9 9 7 6 7 8 9 3 4 3 4 5 6 8} + } + } +} diff --git a/src/tests/aoc_2021_09/src/types.pr.rs b/src/tests/aoc_2021_09/src/types.pr.rs new file mode 100644 index 0000000..8441695 --- /dev/null +++ b/src/tests/aoc_2021_09/src/types.pr.rs @@ -0,0 +1,8 @@ +/*SPEC* +property unique { + \c <: (Container) -> ((for-all-elems c) \a -> ((unique-count? a) c)) +} + +type Map = {c impl (Mapping) | true} +type Set = {c impl (Container) | (unique c)} + *ENDSPEC*/ diff --git a/src/tests/aoc_2022_08/Cargo.toml b/src/tests/aoc_2022_08/Cargo.toml new file mode 100644 index 0000000..449bbdb --- /dev/null +++ b/src/tests/aoc_2022_08/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aoc-2022-08" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = { workspace = true } +primrose-library = { path = "../../crates/library" } + +[dev-dependencies] +criterion = { workspace = true } + +[[bench]] +name = "main" +harness = false diff --git a/src/tests/aoc_2022_08/benches/main.rs b/src/tests/aoc_2022_08/benches/main.rs new file mode 100644 index 0000000..462480e --- /dev/null +++ b/src/tests/aoc_2022_08/benches/main.rs @@ -0,0 +1,39 @@ +use aoc_2022_08::HeightMap; +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use rand::{rngs::StdRng, SeedableRng}; + +fn run_benches(c: &mut Criterion) { + let mut rng = StdRng::seed_from_u64(42); + for size in [1000, 2000].iter() { + c.bench_with_input( + BenchmarkId::new("aoc_2022_08-part1", size), + size, + |b, &n| { + b.iter_batched_ref( + || HeightMap::gen(&mut rng, n), + |map| map.part1(), + BatchSize::SmallInput, + ) + }, + ); + + c.bench_with_input( + BenchmarkId::new("aoc_2022_08-part2", size), + size, + |b, &n| { + b.iter_batched_ref( + || HeightMap::gen(&mut rng, n), + |map| map.part2(), + BatchSize::SmallInput, + ) + }, + ); + } +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = run_benches +); +criterion_main!(benches); diff --git a/src/tests/aoc_2022_08/src/lib.rs b/src/tests/aoc_2022_08/src/lib.rs new file mode 100644 index 0000000..9f60ac8 --- /dev/null +++ b/src/tests/aoc_2022_08/src/lib.rs @@ -0,0 +1,288 @@ +#![feature(type_alias_impl_trait)] + +use primrose_library::traits::*; +use rand::{rngs::StdRng, Rng}; + +mod types; +use types::*; + +pub struct HeightMap { + map: Map<(usize, usize), usize>, + cols: usize, + rows: usize, +} + +impl HeightMap { + pub fn new(map: Map<(usize, usize), usize>, cols: usize, rows: usize) -> Self { + Self { map, cols, rows } + } + + pub fn gen(rng: &mut StdRng, n: usize) -> Self { + let mut map = Map::default(); + for x in 0..n { + for y in 0..n { + map.insert((x, y), rng.gen_range(0..10)); + } + } + + Self { + map, + cols: n, + rows: n, + } + } + + pub fn part1(&self) -> usize { + let mut grid = Map::default(); + + (0..self.rows).for_each(|grid_row| { + self.check_vis_along_run( + (0..self.cols).map(move |grid_col| (grid_row, grid_col)), + &mut grid, + ); + self.check_vis_along_run( + (0..self.cols) + .rev() + .map(move |grid_col| (grid_row, grid_col)), + &mut grid, + ) + }); + (0..self.cols).for_each(|grid_col| { + self.check_vis_along_run( + (0..self.rows).map(move |grid_row| (grid_row, grid_col)), + &mut grid, + ); + self.check_vis_along_run( + (0..self.rows) + .rev() + .map(move |grid_row| (grid_row, grid_col)), + &mut grid, + ) + }); + + grid.iter().filter(|(_, v)| **v).count() + } + + pub fn part2(&self) -> usize { + let mut grid = Map::default(); + + (0..self.rows).for_each(|grid_row| { + self.vis_score_along_run( + (0..self.cols).map(move |grid_col| (grid_row, grid_col)), + &mut grid, + ); + self.vis_score_along_run( + (0..self.cols) + .rev() + .map(move |grid_col| (grid_row, grid_col)), + &mut grid, + ) + }); + (0..self.cols).for_each(|grid_col| { + self.vis_score_along_run( + (0..self.rows).map(move |grid_row| (grid_row, grid_col)), + &mut grid, + ); + self.vis_score_along_run( + (0..self.rows) + .rev() + .map(move |grid_row| (grid_row, grid_col)), + &mut grid, + ) + }); + + *grid.iter().map(|(_, score)| score).max().unwrap() + } + + fn check_vis_along_run( + &self, + mut run: impl Iterator, + vis_grid: &mut Map<(usize, usize), bool>, + ) { + let mut curr_height = { + let (row_idx, col_idx) = run.next().unwrap(); + + vis_grid.insert((row_idx, col_idx), true); + + self.map.get(&(row_idx, col_idx)).unwrap() + }; + for (row_idx, col_idx) in run { + let height = self.map.get(&(row_idx, col_idx)).unwrap(); + if height > curr_height { + curr_height = height; + vis_grid.insert((row_idx, col_idx), true); + } + } + } + + fn vis_score_along_run( + &self, + run: impl Iterator, + vis_grid: &mut Map<(usize, usize), usize>, + ) { + let mut next_values = [0; 10]; + for (row_idx, col_idx) in run { + let height = *self.map.get(&(row_idx, col_idx)).unwrap(); + vis_grid.insert( + (row_idx, col_idx), + vis_grid.get(&(row_idx, col_idx)).unwrap_or(&1) * next_values[height as usize], + ); + + for (val, score) in next_values.iter_mut().enumerate() { + *score = if *score == 0 || val > height as usize { + *score + 1 + } else { + 1 + }; + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn parse_input(input: &str) -> HeightMap { + let mut grid: Vec> = input + .lines() + .map(|x| { + x.chars() + .map(|x| x.to_digit(10).unwrap() as usize) + .collect() + }) + .collect(); + + let (cols, rows) = (grid.len(), grid[0].len()); + HeightMap::new( + grid.into_iter() + .enumerate() + .flat_map(|(c, vs)| vs.into_iter().enumerate().map(move |(r, v)| ((r, c), v))) + .collect(), + cols, + rows, + ) + } + + #[test] + fn test_small() { + let map = parse_input(SMALL_INPUT); + + assert_eq!(map.part1(), 21, "part 1"); + assert_eq!(map.part2(), 8, "part 2"); + } + + #[test] + fn test_large() { + let map = parse_input(LARGE_INPUT); + + assert_eq!(map.part1(), 1859, "part 1"); + assert_eq!(map.part2(), 332640, "part 2"); + } + + const SMALL_INPUT: &str = "30373 +25512 +65332 +33549 +35390"; + + const LARGE_INPUT: &str = "100221200032023210231132410224121421011444302143121341425413411104320412140011030313333000220101112 +112202123021003133332142233323404332315445153153433313154424232233100410424422313323031220233011010 +011002203101130221201112041212404433424255343232213155531144333552214422033044404110303133013102011 +121111233130221221224141101130304514242212243115142242515311345141411232002244120020312220212230110 +202100121002031143312404331332151115114223331225243515233534114435141142242331404201300323113201222 +100021031220304112421404010433522123452131415552421124411431352333224213401342034313144213120020201 +021322001301122441210433214253425221315242313124453313231211152111255512555241432402123122313012220 +102112011033320244100140342511211253345112333255454336534252113251451114422242001024234213333302113 +132330330131203301420044434343145455152343343332352256556523331132212421445241301141320302112302033 +023322331300043142101542252542114115526343233433362336426522664522241145133152512411103311030301102 +322330231444114143321233414112534365353654433452553436246452265364531225351151151443033412041221031 +012321024142334102115451552132455663265336555636436352252325655253353135241221433212232340024232223 +221313322104114224452245113321425622464562645423543656226366436236366342211223552335030321004420030 +302122222422424154133544345544642565622466255242453626235542536222223332315231425444102032032122210 +231133324324321454452534322652236666662342666356747472523623223666552524234541221123331342040102130 +210020241002443524243413355654666622264244543546744763764772255422554656666314534534123124422233033 +131014422414243524255521645632356643223334677577673636537354355442655654452624241512525104443021123 +033403033322215332325412643445254652373556346633545346456537636346453566423552515332123444244330202 +113344141003242351252543634555644673346454333353676654553676643646433222324426451413334115040003434 +001230324131334423146345655352634367445777457543465476454557474433574665556354335235344443340423222 +023244011152423313324656433232434376576677545673553663364375673667467762442263336432523122511002314 +332301042252442131435255344627377653437674735733643774776343344336573375563254444441344341324221021 +334402434231342254423323453655434536773776677775884478878536663447374436723326532641314353455441013 +044342001441534222364463342375566346646375448766484784546577575636346474474644262426334344414332232 +244130421523351525564645423735465337565786567845848555466788768336334436366242664256515555351430211 +024000015535214533542634654746473565564746464865758448476545478886463346677543522243553255453421422 +314442345152523644625564463763377468476865877455764845786446587486747367443753366233446432411453102 +403000534214215322266566347455673478488876664657887477647485758778655633543776436463262445335553104 +214212342251136353523565555447738584887668745867475764748577568657667634663643424344644433342131210 +114243351433156335446363677757688866574765658676758768885858567668678654677476636444464535114243322 +042431434431524463423673765353776887875745588995877855658794867476588746757553543264362224534141501 +304145214121645333564636455447886886885877698565995687887577645687776748545456743542356254233125332 +311331441555242635254434657548756467747985795655656986779866797467565645743544356362633255252311252 +031543523352343526446775553558756644695895589667775569668758957957865578854634733662645643413532141 +132341313125236444736663666564678758797867656955877956887969998885558485468743564462266455525122534 +232352541122446346437676338577648848957677569986976865585987699675564746846753677543463556334143154 +131122222556542463647436455856664477857588875699877776998998877775547558467576475473336454313145311 +323351431635225653436555578777465655659599588676899686697589579979794858655753634546556432442445431 +112233531246445655746654878675766685587986697767667968689785797779856485864853546544452346664152533 +441132313625454663535377687586749896896879888977889996877688569867885777667647465574425232431545142 +111111115654356235746577756578775857666766677988789889966967668865796774447665533366756456656544233 +444252452345444655545775744655786859687696799777689978899776989678787767656644764567745346442533321 +243154434235433653434536454678865969596896986887966776669777699889978977488475776367633466352332221 +011224342565624633533747786446558897878876986776988967899998768656967776846856453564345652346143322 +255513254542435577753688664747776969589697768898799988986867978878755798466564874553774433546435555 +531145456554225737775485576687555769699797776897798787876797978897659996788865775465774226546153322 +442533162233465666667386864866899875679896679977778999979877877678659766555575467467575463636255152 +222435446522644555737767458468785999996898997999997899997696787896667589475664463563534454563214511 +114215466262527345675785857555678986776986688778978997878888897668987577564444436473675662336222114 +311512225352354555566787445776557865789678977797999877977997668696567599676867476737435246555451342 +421334156234643445446758455875576958787887988878779897788997898799755999778447566575637255446655255 +125142454452645575467547748465958777796899699889787977799988676968695967468678746455475566543545252 +541132356636257333356646477666678579897866699899788787979798698767778866447456666337455556433533121 +445221446426223553556485485665966685998799898899888979878767787768599876575858773334364454262234144 +525513243446634357764748776668756995869697898999998977878876699967659655845786665456752546565235543 +242413525434333433563775775447556666686688668777988879987769688978675587574767756766775543642424544 +412342456656355557547778657458878557979677769688789988888698966858589758586466663545734543236112142 +032124116534555566453646756448767766598786768796678968666697769566795585867844377364542222543543144 +441552534565633333336768485544889775969797879987999896968699678699996564658774473347764463533212333 +014334316443544233545737775568867776768987678899897898878766665677857876456548645543346266424252231 +325452232353463343766655746785669595566587987667687678677799977887575876564756446554733252464333125 +235313513563466536365543548586589569868987876898987896869998585688675666574767347633723365564532532 +131124335362654376773466855768859778665998766696796869779797998996756554465587764356742455564311133 +404343421445554355553366675767758576985659996766997797776657667759678485655666467335666422541134511 +312435242152464645537634574874657856986757676888867976856999658767747446588655574536622635614544141 +421213311564223563546534557645478659967967597665866686567866969995544678685456636652623544254232541 +132543425342352422657766376447447764765888966699888885566685795585666784565673355564333242524212311 +302331311115224263643775435787778644568655576569775967656567865844846487483657355742644444135343420 +041452122556655345467337433384557668665698956966665778595596897875676866777643767426226256541552542 +001153531411446425663655546568788568547498779978887586997587766584748746467645733632336523244335133 +123051345234564624353634333467884847454768797578698856589577675458586647637643536245652422355524202 +214113222524335633455447435736745665746584587959858876858874857758585653673436654525322545251233013 +021144513155424252656646455733574856574765868885444777566868748678578533774364735645364444331342200 +431211353221243564244634645643745486685475647654778847854578477454755346753436664555663251321120041 +102242514555444466436542457333634684684544446466456474474878867475656557554754542332232132452524043 +200242332413522436266226554463734737646765775855488765445547588777757737677755424453334532353422100 +241403131545213353553445445364457564356667686685588677677558646353463653546344554664534324351240301 +301440432323554425253552526545676357456386755454585758845784455753574633345364523362222213444203344 +400414313234154322364222535473637766337743638757685754757674654744437433364534662421344453452322134 +001422404442155511452332334335755446737463367654664454733735476754666354564255333335224221543430334 +013133011342545224454646324324367366635745635763574765656353733477656734233264226223311131330044444 +022111144023553523455232562425243646553465743577436756535447437664477626354554366335454123020240144 +230102421342115344242436455624362236434554736674746476337464537776466226562546332255133444243414211 +310212333434541233141416642226456363654747545733335637756546635676334542222542352332333111404102411 +030003333221133245434443565522626652624656376645357754463575744634634423652323553532531310030201001 +030023023423212441345154346256652364345653336653654434533772655254643423443531524513545021442402202 +010024230302312531312212123243243535655425464532567572556636535233466523565345454255552242044131211 +130202311443320415524153221422665546664426662533646433452623222644336564221342333223401212213001023 +211130021411240202155121122543663636242422664454425543522663356225322252323355231113031230011332201 +230111130130413041333532222115236464446226463566236266425464353655322253315233224353341443240012002 +001102313010120320313214115143353526263356666453526645336434636323231453123112522432413131410213301 +311322021312344404314245522512231315322442523625223426563542243513444315534543320140204003013302020 +223031222001210200323443112312552151222246552363556365653546423412555511231131443113420044113212123 +111320133131221133413343355424321432514225151443636656325513423253211421224222110014232232113301221 +010321023321033244303433322535144241341415221344311331433254245144245522341332333121010301003132230 +211110020103304321442134112151523315235121445254445414513445335245114524313310001304234213223211022 +111122023302320302411300133103134411221211352515252145115412111545311213404224233340430222022031002 +211120112212331032422141144010135514321521155344453422441443412441135423402430103212201303331211201 +010021021121120020020341010431334133122452331123312352352313123235203300324210330421332333020210112"; +} diff --git a/src/tests/aoc_2022_08/src/types.pr.rs b/src/tests/aoc_2022_08/src/types.pr.rs new file mode 100644 index 0000000..5e3950c --- /dev/null +++ b/src/tests/aoc_2022_08/src/types.pr.rs @@ -0,0 +1,3 @@ +/*SPEC* +type Map = {c impl (Mapping) | true} + *ENDSPEC*/ diff --git a/src/tests/aoc_2022_09/Cargo.toml b/src/tests/aoc_2022_09/Cargo.toml new file mode 100644 index 0000000..f806c9c --- /dev/null +++ b/src/tests/aoc_2022_09/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aoc-2022-09" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = { workspace = true } +primrose-library = { path = "../../crates/library" } + +[dev-dependencies] +criterion = { workspace = true } + +[[bench]] +name = "main" +harness = false diff --git a/src/tests/aoc_2022_09/benches/main.rs b/src/tests/aoc_2022_09/benches/main.rs new file mode 100644 index 0000000..dd96209 --- /dev/null +++ b/src/tests/aoc_2022_09/benches/main.rs @@ -0,0 +1,39 @@ +use aoc_2022_09::{gen_moves, part1, part2}; +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use rand::{rngs::StdRng, SeedableRng}; + +fn run_benches(c: &mut Criterion) { + let mut rng = StdRng::seed_from_u64(42); + for size in [100, 1000, 2000].iter() { + c.bench_with_input( + BenchmarkId::new("aoc_2022_09-part1", size), + size, + |b, &n| { + b.iter_batched_ref( + || gen_moves(&mut rng, n).collect::>(), + |moves| part1(moves.iter()), + BatchSize::SmallInput, + ) + }, + ); + + c.bench_with_input( + BenchmarkId::new("aoc_2022_09-part2", size), + size, + |b, &n| { + b.iter_batched_ref( + || gen_moves(&mut rng, n).collect::>(), + |moves| part2(moves.iter()), + BatchSize::SmallInput, + ) + }, + ); + } +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = run_benches +); +criterion_main!(benches); diff --git a/src/tests/aoc_2022_09/src/lib.rs b/src/tests/aoc_2022_09/src/lib.rs new file mode 100644 index 0000000..9bb7364 --- /dev/null +++ b/src/tests/aoc_2022_09/src/lib.rs @@ -0,0 +1,2126 @@ +#![feature(type_alias_impl_trait)] + +use primrose_library::traits::*; +use rand::Rng; +use std::cmp::min; + +mod types; +use types::*; + +pub fn part1<'a>(moves: impl Iterator) -> usize { + visited_from_moves::<2>(moves) +} + +pub fn part2<'a>(moves: impl Iterator) -> usize { + visited_from_moves::<10>(moves) +} + +fn visited_from_moves<'a, const N: usize>(moves: impl Iterator) -> usize { + let mut tail_visited = Set::default(); + tail_visited.insert((0, 0)); + let mut knots = [(0, 0); N]; + for mv in moves { + make_move(mv, &mut knots, &mut tail_visited); + } + + tail_visited.len() +} + +fn make_move(mv: &Move, knots: &mut [Pos], tail_visited: &mut Set) { + let (dir, count) = mv; + + for _ in 0..*count { + // Move head of rope + match dir { + Direction::Up => knots[0].1 += 1, + Direction::Down => knots[0].1 -= 1, + Direction::Right => knots[0].0 += 1, + Direction::Left => knots[0].0 -= 1, + }; + + for front_idx in 0..knots.len() - 1 { + let (fx, fy) = knots[front_idx]; + let (bx, by) = &mut knots[front_idx + 1]; + let (dx, dy) = (fx - *bx, fy - *by); + if (dx.abs() == 2 && dy == 0) || (dy.abs() == 2 && dx == 0) || (dy.abs() + dx.abs() > 2) + { + *bx += (dx.signum()) * min(dx.abs(), 1); + *by += (dy.signum()) * min(dy.abs(), 1); + } + } + tail_visited.insert(knots[knots.len() - 1]); + } +} + +pub type Pos = (i32, i32); +pub type Move = (Direction, u8); + +#[derive(Debug, Clone, Copy)] +pub enum Direction { + Up, + Down, + Left, + Right, +} + +pub fn gen_moves(rng: &mut R, n: usize) -> impl Iterator + '_ { + (0..n).map(|_| { + let dir = match rng.gen_range(0..4) { + 0 => Direction::Up, + 1 => Direction::Down, + 2 => Direction::Left, + 3 => Direction::Right, + _ => unreachable!(), + }; + let count = rng.gen(); + + (dir, count) + }) +} + +#[cfg(test)] +mod tests { + use crate::*; + + fn parse_moves(input: &str) -> impl Iterator + '_ { + input.lines().map(|x| { + let (dir, count) = x.split_once(' ').unwrap(); + let count = count.parse().unwrap(); + + ( + match dir { + "L" => Direction::Left, + "R" => Direction::Right, + "U" => Direction::Up, + "D" => Direction::Down, + _ => panic!("invalid direction, {}", dir), + }, + count, + ) + }) + } + + #[test] + fn test_small() { + let moves = parse_moves(SMALL_INPUT).collect::>(); + assert_eq!(part1(moves.iter()), 13, "part 1"); + assert_eq!(part2(moves.iter()), 1, "part 2"); + } + + #[test] + fn test_large() { + let moves = parse_moves(LARGE_INPUT).collect::>(); + assert_eq!(part1(moves.iter()), 6236, "part 1"); + assert_eq!(part2(moves.iter()), 2449, "part 2"); + } + + const SMALL_INPUT: &str = "R 4 +U 4 +L 3 +D 1 +R 4 +D 1 +L 5 +R 2"; + + const LARGE_INPUT: &str = "L 1 +R 1 +U 1 +R 1 +L 1 +U 2 +L 2 +R 1 +U 2 +D 2 +R 2 +D 2 +R 1 +U 1 +R 2 +L 1 +D 1 +L 2 +R 1 +D 1 +R 1 +U 1 +D 1 +R 1 +D 1 +R 1 +D 2 +L 2 +D 1 +R 2 +L 1 +R 2 +U 2 +R 1 +U 1 +D 2 +U 1 +R 1 +D 1 +R 2 +D 1 +L 2 +R 1 +U 1 +L 1 +U 1 +D 1 +U 1 +D 1 +L 1 +D 1 +R 1 +D 2 +L 1 +D 1 +L 1 +D 1 +R 1 +U 1 +D 2 +R 1 +D 1 +L 2 +D 2 +U 1 +L 1 +U 1 +L 1 +R 2 +U 1 +L 1 +D 1 +R 2 +L 2 +U 1 +D 2 +R 1 +U 1 +R 2 +L 2 +U 1 +L 2 +R 2 +D 1 +L 1 +R 1 +D 2 +L 2 +U 1 +L 2 +R 1 +U 2 +D 1 +U 2 +D 2 +L 2 +D 1 +R 1 +L 2 +R 2 +L 2 +R 2 +L 2 +R 2 +L 1 +U 1 +R 2 +U 1 +D 1 +R 2 +D 2 +R 2 +D 2 +L 2 +R 2 +U 3 +R 1 +U 3 +D 3 +U 1 +L 2 +D 2 +R 3 +D 1 +R 3 +U 1 +L 3 +R 3 +L 1 +U 3 +R 3 +U 3 +R 3 +U 2 +L 2 +D 2 +R 3 +U 2 +L 2 +U 3 +L 2 +R 1 +U 3 +R 2 +U 3 +L 2 +R 2 +U 1 +L 3 +R 3 +L 3 +R 2 +L 3 +D 3 +L 2 +D 1 +R 1 +D 3 +U 3 +R 3 +D 2 +L 2 +D 2 +R 1 +D 1 +U 3 +R 1 +U 2 +L 3 +U 3 +L 2 +D 1 +L 3 +R 2 +D 2 +L 2 +D 3 +L 3 +U 1 +D 3 +U 3 +L 3 +R 2 +D 2 +R 3 +D 2 +R 3 +U 2 +R 1 +L 2 +R 2 +L 1 +D 3 +U 2 +L 2 +U 3 +L 1 +D 1 +L 2 +R 3 +L 1 +D 2 +U 1 +D 3 +U 1 +D 3 +L 1 +U 1 +R 3 +L 2 +U 3 +L 3 +U 1 +L 2 +D 1 +R 2 +L 1 +R 2 +L 2 +D 3 +U 2 +D 2 +U 3 +L 4 +D 4 +R 3 +D 4 +R 1 +L 2 +U 2 +R 1 +U 4 +D 4 +U 4 +D 4 +R 4 +L 2 +U 3 +D 1 +R 4 +D 2 +L 2 +D 1 +L 4 +R 3 +U 2 +D 4 +U 3 +R 3 +L 1 +R 1 +L 2 +D 4 +U 2 +R 1 +L 3 +D 3 +R 4 +U 2 +L 1 +D 3 +R 4 +D 2 +U 3 +D 1 +L 2 +D 2 +R 2 +D 3 +R 2 +U 2 +R 1 +L 1 +U 2 +D 2 +U 3 +D 1 +U 3 +D 1 +R 4 +D 2 +U 1 +L 3 +D 4 +R 3 +D 4 +U 2 +D 1 +R 2 +U 3 +L 3 +D 1 +U 2 +L 3 +D 1 +L 3 +D 1 +U 1 +D 4 +R 1 +D 4 +L 2 +R 3 +D 4 +R 2 +L 3 +D 4 +U 3 +L 4 +U 1 +L 3 +R 1 +L 1 +D 2 +L 1 +U 2 +D 3 +L 1 +R 4 +L 1 +D 2 +U 2 +L 3 +U 3 +L 1 +R 4 +U 3 +D 3 +R 1 +L 2 +R 4 +U 2 +L 3 +U 4 +L 2 +R 4 +D 5 +U 1 +R 2 +D 5 +L 5 +R 1 +D 3 +U 3 +L 3 +U 5 +R 1 +D 1 +R 3 +U 3 +D 1 +R 1 +L 4 +R 1 +L 3 +U 4 +L 3 +R 5 +D 3 +R 2 +U 1 +R 2 +D 2 +L 4 +R 2 +U 1 +L 3 +D 4 +R 4 +L 1 +R 3 +U 3 +D 2 +R 3 +D 3 +U 1 +L 5 +U 1 +L 5 +R 5 +D 1 +U 1 +R 5 +D 4 +L 1 +R 4 +L 5 +D 5 +L 2 +D 1 +L 3 +D 5 +L 4 +R 4 +D 1 +U 1 +D 4 +U 1 +R 4 +L 2 +D 4 +U 1 +L 3 +R 3 +L 3 +R 3 +D 2 +R 3 +L 5 +R 1 +L 1 +R 3 +D 5 +U 5 +L 3 +U 3 +L 5 +D 3 +L 2 +U 5 +D 5 +U 5 +D 4 +U 4 +R 5 +U 3 +D 5 +R 1 +L 4 +U 1 +L 4 +R 2 +D 1 +U 4 +L 5 +D 2 +R 1 +U 1 +R 3 +U 1 +R 4 +U 4 +L 1 +R 2 +U 5 +D 2 +L 5 +U 4 +D 2 +R 1 +D 1 +U 6 +D 5 +L 4 +U 5 +R 1 +L 3 +D 2 +R 3 +U 6 +L 2 +R 6 +D 1 +R 5 +D 1 +L 1 +R 2 +L 4 +R 3 +L 4 +D 6 +R 5 +U 1 +L 4 +D 2 +L 2 +D 3 +L 2 +D 5 +R 4 +D 3 +L 2 +D 4 +R 1 +U 5 +L 5 +U 5 +D 2 +L 3 +D 4 +L 3 +U 4 +L 4 +U 6 +D 6 +U 4 +R 2 +D 3 +U 1 +R 4 +D 3 +R 1 +D 2 +R 3 +L 2 +D 2 +L 4 +D 5 +L 5 +R 2 +L 1 +R 2 +D 2 +R 4 +U 4 +R 5 +L 4 +D 1 +L 6 +R 4 +D 2 +R 6 +L 6 +D 3 +R 2 +D 2 +U 4 +R 2 +U 2 +L 2 +R 5 +D 5 +U 6 +D 6 +L 5 +R 1 +U 3 +L 1 +D 1 +U 2 +R 5 +L 2 +D 2 +U 4 +R 2 +D 2 +U 1 +D 2 +R 3 +L 6 +U 1 +D 6 +R 3 +D 6 +R 1 +D 7 +R 7 +L 4 +R 4 +D 5 +U 6 +R 2 +L 3 +R 5 +L 5 +U 6 +D 3 +U 5 +D 3 +U 5 +R 7 +L 5 +U 7 +L 6 +U 5 +D 1 +L 7 +U 6 +L 3 +D 1 +L 6 +U 4 +D 1 +U 1 +R 1 +L 3 +D 6 +L 6 +R 3 +D 3 +U 2 +R 1 +D 6 +U 7 +R 6 +L 4 +R 4 +D 7 +R 1 +D 5 +U 6 +D 4 +R 6 +L 2 +U 4 +D 7 +R 5 +D 6 +U 7 +R 6 +D 6 +U 1 +D 4 +L 2 +U 2 +R 7 +U 1 +L 1 +U 1 +L 7 +D 3 +U 5 +D 5 +L 1 +D 4 +L 3 +U 7 +L 6 +R 7 +U 6 +R 1 +L 3 +R 1 +D 3 +L 7 +R 4 +L 3 +D 2 +L 7 +D 2 +R 5 +L 7 +D 6 +L 6 +D 3 +L 3 +D 5 +U 3 +L 5 +R 6 +L 1 +U 5 +R 4 +U 2 +D 3 +R 5 +L 4 +U 5 +D 7 +R 1 +L 3 +U 5 +D 3 +L 6 +R 2 +L 2 +U 6 +R 3 +U 7 +R 3 +D 1 +L 2 +U 7 +L 6 +D 3 +L 8 +R 6 +D 3 +L 5 +R 5 +U 5 +R 8 +D 7 +R 7 +U 8 +L 5 +D 6 +R 6 +L 6 +D 8 +U 1 +R 4 +L 3 +R 6 +L 6 +D 5 +R 4 +D 8 +L 4 +R 4 +D 3 +L 2 +U 6 +L 8 +R 1 +U 5 +L 4 +D 8 +R 6 +D 5 +U 6 +L 5 +R 1 +L 8 +U 7 +R 6 +D 4 +U 2 +D 8 +U 3 +D 7 +R 6 +D 8 +R 8 +U 8 +D 7 +L 3 +D 4 +L 1 +U 4 +R 4 +U 2 +D 6 +R 1 +D 8 +R 2 +D 4 +R 5 +L 1 +R 7 +L 3 +D 1 +U 1 +R 7 +U 5 +D 1 +L 2 +R 8 +D 8 +L 5 +U 8 +D 4 +L 5 +D 3 +U 2 +L 7 +R 2 +L 5 +U 3 +R 3 +U 6 +R 6 +D 4 +R 3 +U 4 +D 5 +U 6 +R 3 +L 4 +R 5 +L 4 +R 8 +U 6 +L 6 +U 1 +L 5 +R 3 +U 1 +D 5 +U 8 +R 1 +L 2 +R 3 +L 8 +U 6 +L 4 +R 3 +L 3 +R 7 +L 9 +D 5 +R 8 +L 5 +U 7 +D 7 +R 6 +L 8 +U 4 +D 5 +R 8 +L 4 +R 8 +U 9 +R 9 +L 8 +D 9 +L 9 +D 6 +R 1 +L 8 +U 4 +L 6 +U 5 +R 9 +L 5 +D 6 +R 9 +D 9 +U 6 +L 1 +U 8 +L 7 +R 9 +U 4 +R 6 +U 1 +R 5 +U 5 +L 4 +R 4 +D 7 +L 6 +U 3 +R 9 +U 1 +L 6 +U 5 +L 5 +U 2 +L 3 +U 2 +D 6 +R 8 +L 5 +U 4 +D 4 +R 4 +D 6 +L 8 +U 9 +R 4 +L 3 +D 1 +U 2 +D 5 +U 3 +D 3 +L 2 +D 3 +L 4 +D 5 +L 9 +D 9 +U 2 +D 8 +R 4 +L 8 +R 9 +D 7 +L 3 +D 2 +R 2 +L 4 +D 7 +R 6 +D 8 +R 9 +L 3 +D 5 +U 1 +L 8 +D 6 +R 9 +U 6 +R 9 +D 6 +L 9 +U 5 +D 10 +L 4 +U 10 +R 3 +U 7 +D 4 +L 3 +R 8 +L 4 +U 10 +R 8 +L 10 +U 8 +R 5 +L 8 +U 6 +L 5 +D 7 +L 6 +U 6 +L 9 +R 8 +U 6 +D 7 +L 10 +R 2 +D 7 +L 8 +U 5 +L 2 +D 2 +U 7 +D 6 +R 7 +D 2 +U 3 +R 10 +D 2 +U 6 +D 6 +L 8 +D 2 +L 2 +D 10 +L 2 +D 1 +L 10 +D 6 +R 6 +L 7 +D 9 +R 2 +D 5 +U 2 +R 4 +L 4 +D 1 +L 3 +R 10 +U 9 +L 4 +D 10 +L 10 +D 4 +U 2 +R 1 +L 4 +D 6 +U 2 +L 6 +R 4 +U 1 +L 9 +R 7 +L 8 +U 5 +R 1 +D 6 +L 4 +U 9 +D 1 +L 5 +R 10 +D 4 +L 6 +U 8 +R 4 +L 5 +D 10 +R 8 +D 8 +R 4 +D 5 +R 7 +L 10 +D 3 +R 1 +L 4 +R 8 +L 10 +D 2 +L 3 +D 6 +L 8 +R 10 +L 2 +D 8 +R 5 +L 8 +D 1 +U 6 +D 11 +U 7 +L 1 +U 6 +R 9 +L 8 +R 5 +U 9 +D 5 +L 10 +U 6 +L 3 +D 4 +U 6 +D 10 +L 2 +D 9 +L 5 +R 8 +D 1 +R 1 +U 1 +D 4 +R 4 +U 6 +L 9 +U 7 +R 11 +L 8 +D 3 +R 9 +L 11 +U 9 +L 4 +D 10 +U 9 +L 7 +R 9 +U 1 +R 8 +U 4 +L 3 +U 2 +D 7 +R 6 +U 1 +D 10 +U 9 +R 6 +L 6 +D 4 +U 3 +L 10 +R 10 +U 6 +R 8 +L 9 +R 2 +D 7 +R 4 +U 6 +R 2 +L 4 +D 1 +L 10 +U 9 +R 11 +U 11 +R 1 +D 5 +L 8 +U 3 +R 1 +U 4 +D 10 +U 6 +L 8 +R 4 +L 7 +R 8 +D 3 +L 9 +U 4 +L 6 +R 2 +D 2 +U 9 +D 6 +R 8 +L 2 +U 7 +L 2 +R 8 +L 7 +D 5 +R 10 +U 5 +L 10 +U 6 +R 8 +U 9 +L 7 +D 11 +U 10 +L 4 +D 5 +R 4 +L 7 +U 5 +D 8 +R 6 +D 9 +L 4 +U 9 +R 6 +D 1 +U 6 +R 8 +U 10 +D 6 +U 10 +L 3 +D 1 +L 1 +R 9 +D 10 +L 10 +U 12 +D 3 +L 2 +U 6 +L 9 +U 2 +R 6 +D 8 +R 11 +L 1 +U 3 +R 1 +U 9 +R 12 +U 3 +D 11 +U 3 +D 10 +U 12 +L 11 +R 9 +U 9 +D 11 +L 8 +D 4 +R 4 +U 4 +D 1 +L 7 +R 10 +L 4 +R 4 +U 11 +D 3 +L 6 +R 10 +L 9 +R 11 +U 6 +D 2 +U 2 +L 3 +D 11 +U 6 +D 12 +L 5 +R 5 +D 6 +R 5 +U 2 +R 8 +L 7 +D 7 +R 3 +D 8 +U 6 +D 1 +U 1 +D 4 +L 3 +D 12 +L 8 +D 8 +U 7 +R 1 +D 10 +L 5 +D 7 +L 1 +U 4 +R 12 +L 8 +U 2 +L 2 +U 1 +L 8 +U 3 +L 12 +R 3 +D 11 +R 1 +U 4 +D 12 +L 3 +U 2 +R 5 +U 2 +R 7 +U 8 +L 5 +R 1 +D 5 +R 12 +D 8 +R 9 +D 7 +L 2 +R 2 +U 9 +D 6 +U 6 +R 2 +D 2 +R 9 +D 4 +R 12 +D 13 +R 9 +L 3 +D 8 +L 13 +U 2 +R 10 +U 12 +D 12 +U 3 +L 6 +D 8 +U 1 +L 12 +D 9 +L 7 +R 2 +D 4 +R 5 +L 7 +R 12 +U 4 +L 7 +D 4 +U 10 +L 2 +D 1 +U 5 +R 5 +U 2 +L 9 +D 10 +L 1 +R 7 +L 6 +D 1 +L 12 +R 6 +U 10 +R 2 +D 10 +R 5 +L 3 +R 8 +D 1 +R 12 +L 7 +U 5 +L 11 +D 4 +U 11 +D 1 +U 11 +L 1 +D 11 +U 11 +D 4 +U 8 +R 5 +D 6 +L 12 +R 5 +D 10 +L 2 +D 5 +R 10 +U 6 +D 6 +R 4 +D 7 +L 2 +D 5 +U 2 +R 9 +L 11 +U 13 +D 9 +L 11 +D 8 +L 2 +D 4 +R 13 +L 5 +U 12 +R 11 +U 5 +L 8 +U 5 +D 7 +U 1 +R 9 +D 4 +U 3 +R 9 +L 3 +D 7 +R 8 +D 7 +L 2 +U 4 +L 12 +U 13 +L 12 +R 8 +L 3 +R 12 +L 4 +U 12 +R 13 +D 10 +L 8 +U 12 +R 5 +L 1 +U 2 +L 3 +U 2 +D 12 +L 12 +U 11 +L 2 +R 6 +U 3 +L 2 +R 7 +U 7 +L 3 +R 8 +L 11 +D 2 +U 1 +R 12 +D 1 +R 4 +L 13 +U 14 +R 14 +D 12 +R 12 +D 11 +L 11 +U 2 +L 6 +D 8 +L 5 +D 7 +R 2 +L 14 +U 12 +R 13 +L 7 +D 2 +U 4 +D 5 +R 5 +L 7 +R 7 +U 1 +R 10 +D 11 +L 7 +U 2 +R 5 +L 11 +U 11 +R 9 +U 9 +R 12 +D 14 +R 5 +L 9 +U 2 +D 12 +L 6 +U 7 +R 5 +L 10 +D 10 +U 4 +D 13 +L 13 +D 3 +R 8 +D 10 +U 12 +L 14 +U 7 +D 6 +R 4 +U 11 +R 2 +L 5 +D 12 +R 4 +L 4 +D 5 +L 12 +U 3 +L 3 +U 7 +R 4 +L 2 +R 7 +L 5 +D 5 +R 9 +L 5 +D 12 +R 3 +U 1 +D 6 +U 2 +R 10 +L 4 +U 12 +R 15 +L 2 +R 3 +D 8 +L 13 +D 3 +R 5 +D 5 +L 5 +U 7 +L 4 +R 10 +D 11 +L 3 +R 1 +U 4 +D 15 +L 8 +U 10 +L 5 +D 1 +R 5 +D 15 +R 3 +U 9 +R 4 +D 3 +L 15 +U 6 +D 10 +U 2 +R 6 +U 10 +L 12 +R 8 +D 12 +R 14 +U 10 +D 1 +L 1 +D 8 +U 3 +R 11 +D 7 +L 5 +D 14 +R 1 +D 8 +R 6 +U 6 +D 1 +U 14 +R 12 +L 5 +U 5 +L 14 +U 1 +D 3 +R 6 +U 4 +R 9 +L 13 +R 2 +U 10 +R 11 +U 7 +D 8 +U 14 +L 4 +R 3 +U 6 +R 2 +D 14 +U 10 +D 13 +U 8 +R 12 +L 12 +U 6 +L 4 +U 5 +D 6 +U 8 +L 12 +D 1 +L 3 +R 4 +L 11 +R 5 +D 3 +U 6 +D 15 +R 14 +U 8 +R 10 +U 15 +R 13 +L 13 +U 4 +D 3 +U 4 +D 1 +U 5 +R 5 +D 4 +R 2 +D 13 +R 7 +D 10 +U 3 +R 15 +D 3 +U 13 +R 16 +U 2 +D 6 +L 13 +R 8 +L 5 +R 1 +U 7 +R 6 +U 6 +R 10 +U 5 +L 14 +R 12 +U 8 +R 13 +U 4 +L 10 +R 16 +L 15 +D 7 +R 14 +D 8 +U 8 +L 15 +R 2 +U 11 +L 6 +R 6 +D 2 +U 9 +D 12 +L 10 +U 7 +R 8 +L 4 +D 5 +R 13 +L 9 +U 15 +D 11 +R 11 +D 8 +L 10 +R 14 +D 3 +R 10 +U 1 +R 11 +L 16 +R 12 +D 15 +L 13 +U 2 +L 11 +U 15 +D 9 +R 1 +D 13 +L 16 +U 9 +D 2 +R 5 +U 9 +R 11 +L 16 +U 5 +R 11 +U 8 +L 15 +U 1 +L 11 +U 3 +L 4 +U 9 +L 5 +U 11 +D 9 +U 4 +L 14 +U 8 +L 16 +D 9 +U 5 +L 14 +R 13 +U 8 +L 4 +R 9 +L 4 +R 7 +D 15 +U 14 +D 8 +U 6 +R 11 +L 15 +D 10 +R 2 +L 12 +R 11 +D 7 +R 11 +L 4 +R 4 +D 4 +R 3 +U 15 +L 6 +R 8 +L 5 +U 13 +D 6 +R 1 +D 15 +L 9 +U 2 +L 13 +R 10 +U 8 +R 15 +D 16 +L 13 +U 13 +L 12 +R 10 +U 16 +L 10 +R 14 +D 17 +R 4 +D 16 +U 17 +R 8 +D 10 +R 11 +L 10 +U 17 +L 11 +U 3 +L 4 +U 2 +D 10 +R 15 +U 1 +R 5 +L 12 +D 4 +R 1 +U 15 +R 13 +L 17 +R 15 +D 4 +L 14 +R 3 +D 1 +U 14 +R 11 +D 12 +L 7 +D 11 +R 12 +U 1 +R 5 +L 11 +D 9 +U 8 +R 1 +U 4 +L 15 +R 12 +U 17 +R 4 +U 14 +L 4 +D 16 +R 9 +U 9 +D 11 +L 7 +D 16 +R 10 +L 10 +R 15 +U 10 +R 6 +L 4 +R 6 +L 12 +U 9 +R 15 +D 12 +L 14 +U 14 +D 6 +U 4 +R 17 +U 2 +L 5 +R 13 +D 15 +U 13 +L 5 +D 3 +L 7 +U 12 +R 13 +D 15 +U 15 +L 17 +U 17 +L 6 +R 2 +U 17 +R 7 +L 15 +U 17 +R 11 +L 2 +U 1 +D 4 +U 2 +R 10 +L 9 +D 18 +U 5 +D 7 +R 18 +L 11 +D 2 +U 13 +D 12 +R 10 +D 2 +R 9 +L 3 +D 9 +R 9 +L 17 +R 4 +L 7 +D 16 +L 5 +R 3 +L 8 +U 7 +R 8 +L 1 +D 12 +U 13 +R 8 +D 18 +U 7 +R 6 +D 7 +L 7 +D 8 +R 16 +L 13 +R 6 +U 1 +L 9 +U 9 +L 12 +D 13 +R 18 +L 7 +D 18 +U 17 +R 18 +D 11 +R 1 +D 4 +U 3 +L 7 +D 17 +R 8 +U 11 +D 7 +L 4 +R 12 +U 10 +L 15 +R 14 +U 16 +D 4 +L 10 +U 6 +D 18 +R 7 +U 13 +R 11 +D 14 +L 5 +U 5 +L 7 +R 15 +L 16 +U 6 +D 9 +L 17 +R 4 +L 16 +D 10 +U 16 +D 17 +R 7 +L 16 +U 6 +L 15 +R 13 +U 8 +L 14 +R 12 +U 5 +D 17 +R 13 +D 12 +U 12 +L 16 +R 8 +U 4 +D 6 +U 10 +D 14 +R 18 +L 17 +U 15 +L 5 +U 7 +D 15 +U 10 +R 18 +L 11 +D 10 +R 12 +U 15 +D 11 +U 7 +D 3 +R 2 +U 5 +R 12 +U 15 +R 12 +U 19 +L 6 +U 18 +D 8 +L 7 +D 2 +R 1 +L 16 +D 5 +L 9 +U 11 +L 6 +U 7 +L 2 +D 18 +L 1 +U 19 +D 15 +U 8 +R 5 +U 13 +L 7 +R 14 +U 2 +D 10 +U 16 +D 3 +R 8 +L 10 +D 17 +U 16 +D 6 +R 18 +D 5 +L 5 +D 4 +L 6 +U 17 +D 7 +R 15 +D 5 +R 18 +L 6 +U 15 +L 3 +U 13 +L 15 +R 5 +D 9 +R 11 +U 15 +L 19 +D 11 +L 8 +D 14 +R 7 +L 16 +D 5 +R 13 +D 5 +L 9 +D 3 +L 3 +R 12 +U 17 +R 8 +L 11 +U 2 +R 9 +L 3 +D 6 +L 9 +U 11 +R 6 +U 19 +R 6 +L 12 +U 5 +R 4 +U 4 +L 16 +R 17 +D 12 +U 11 +R 4 +D 11 +U 4 +R 8 +U 9 +R 12 +U 13 +L 2 +D 9 +L 2"; +} diff --git a/src/tests/aoc_2022_09/src/types.pr.rs b/src/tests/aoc_2022_09/src/types.pr.rs new file mode 100644 index 0000000..d4225a9 --- /dev/null +++ b/src/tests/aoc_2022_09/src/types.pr.rs @@ -0,0 +1,7 @@ +/*SPEC* +property unique { + \c <: (Container) -> ((for-all-elems c) \a -> ((unique-count? a) c)) +} + +type Set = {c impl (Container) | (unique c)} + *ENDSPEC*/ diff --git a/src/tests/aoc_2022_14/Cargo.toml b/src/tests/aoc_2022_14/Cargo.toml new file mode 100644 index 0000000..b8c00f5 --- /dev/null +++ b/src/tests/aoc_2022_14/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "aoc-2022-14" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rand = { workspace = true } +primrose-library = { path = "../../crates/library" } + +[dev-dependencies] +criterion = { workspace = true } + +[[bench]] +name = "main" +harness = false diff --git a/src/tests/aoc_2022_14/benches/main.rs b/src/tests/aoc_2022_14/benches/main.rs new file mode 100644 index 0000000..885b389 --- /dev/null +++ b/src/tests/aoc_2022_14/benches/main.rs @@ -0,0 +1,34 @@ +use aoc_2022_14::tests::*; +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; +use rand::{rngs::StdRng, SeedableRng}; + +fn run_benches(c: &mut Criterion) { + c.bench_with_input( + BenchmarkId::new("aoc_2022_14-part1", "small"), + &SMALL_INPUT, + |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part1(), BatchSize::SmallInput), + ); + c.bench_with_input( + BenchmarkId::new("aoc_2022_14-part1", "large"), + &LARGE_INPUT, + |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part1(), BatchSize::SmallInput), + ); + + c.bench_with_input( + BenchmarkId::new("aoc_2022_14-part2", "small"), + &SMALL_INPUT, + |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part2(), BatchSize::SmallInput), + ); + c.bench_with_input( + BenchmarkId::new("aoc_2022_14-part2", "large"), + &LARGE_INPUT, + |b, &inp| b.iter_batched_ref(|| parse_input(inp), |w| w.part2(), BatchSize::SmallInput), + ); +} + +criterion_group!( + name = benches; + config = Criterion::default().sample_size(10); + targets = run_benches +); +criterion_main!(benches); diff --git a/src/tests/aoc_2022_14/src/lib.rs b/src/tests/aoc_2022_14/src/lib.rs new file mode 100644 index 0000000..3494e2e --- /dev/null +++ b/src/tests/aoc_2022_14/src/lib.rs @@ -0,0 +1,170 @@ +#![feature(type_alias_impl_trait)] + +use primrose_library::traits::*; +use std::{ + cmp::{max, min}, + ops::Add, +}; + +mod types; +use types::*; + +pub struct World { + structures: Vec, + sand_grains: Set, + floor_y: isize, +} + +impl World { + pub fn new(structures: Vec) -> Self { + let floor_y = structures + .iter() + .map(|s| s.points.iter().map(|p| p.1).max().unwrap()) + .max() + .unwrap() + + 2; + + Self { + structures, + floor_y, + sand_grains: Default::default(), + } + } + + pub fn part1(&mut self) -> usize { + (0..).take_while(|_| !self.step()).count() + } + + pub fn part2(&mut self) -> usize { + self.structures.push(Structure::new({ + let mut l: List = Default::default(); + l.insert(Pos(isize::MIN, self.floor_y)); + l.insert(Pos(isize::MAX, self.floor_y)); + l + })); + (0..).take_while(|_| !self.step()).count() + } + + fn step(&mut self) -> bool { + let mut pos = Pos(500, 0); + if self.sand_grains.contains(&pos) { + return true; + } + loop { + if pos.1 > self.floor_y { + return true; + } + pos = if !self.inhabited(pos + Pos(0, 1)) { + pos + Pos(0, 1) + } else if !self.inhabited(pos + Pos(-1, 1)) { + pos + Pos(-1, 1) + } else if !self.inhabited(pos + Pos(1, 1)) { + pos + Pos(1, 1) + } else { + self.sand_grains.insert(pos); + return false; + }; + } + } + + fn inhabited(&self, pos: Pos) -> bool { + self.structures.iter().any(|s| s.contains(pos)) || self.sand_grains.contains(&pos) + } +} + +pub struct Structure { + points: List, + bbox_min: Pos, + bbox_max: Pos, +} + +impl Structure { + pub fn new(points: List) -> Self { + let bbox_min = points.iter().fold(Pos(isize::MAX, isize::MAX), |acc, pos| { + Pos(min(acc.0, pos.0), min(acc.1, pos.1)) + }); + let bbox_max = points.iter().fold(Pos(isize::MAX, isize::MAX), |acc, pos| { + Pos(max(acc.0, pos.0), max(acc.1, pos.1)) + }); + + Structure { + points, + bbox_max, + bbox_min, + } + } + + fn contains(&self, pos: Pos) -> bool { + if pos.0 < self.bbox_min.0 + || pos.0 > self.bbox_max.0 + || pos.1 < self.bbox_min.1 + || pos.1 > self.bbox_max.1 + { + return false; + } + for (a, b) in self.points.iter().zip(self.points.iter().skip(1)) { + if a.0 == b.0 { + if pos.0 == a.0 && pos.1 >= min(a.1, b.1) && pos.1 <= max(a.1, b.1) { + return true; + } + } else { + // a.1 == b.1 + if pos.1 == a.1 && pos.0 >= min(a.0, b.0) && pos.0 <= max(a.0, b.0) { + return true; + } + } + } + return false; + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Pos(isize, isize); + +impl Add for Pos { + type Output = Pos; + + fn add(self, rhs: Self) -> Self::Output { + Pos(self.0 + rhs.0, self.1 + rhs.1) + } +} + +pub mod tests { + use super::*; + + pub fn parse_input(input: &str) -> World { + World::new(input.lines().map(parse_structure).collect()) + } + + pub fn parse_structure(l: &str) -> Structure { + Structure::new(l.split(" -> ").map(|s| parse_pos(s)).collect()) + } + + pub fn parse_pos(s: &str) -> Pos { + let (x, y) = s.split_once(',').unwrap(); + Pos(x.parse().unwrap(), y.parse().unwrap()) + } + + #[test] + fn small() { + assert_eq!(parse_input(SMALL_INPUT).part1(), 24, "part 1"); + assert_eq!(parse_input(SMALL_INPUT).part2(), 93, "part 2"); + } + + #[test] + fn large() { + assert_eq!(parse_input(LARGE_INPUT).part1(), 0, "part 1"); + assert_eq!(parse_input(LARGE_INPUT).part2(), 26360, "part 2"); + } + + pub const SMALL_INPUT: &str = "498,4 -> 498,6 -> 496,6 +503,4 -> 502,4 -> 502,9 -> 494,9"; + + pub const LARGE_INPUT: &str = "515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60 +515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60 +502,32 -> 507,32 +522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47 +516,32 -> 521,32 +501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161 +512,30 -> 517,30"; +} diff --git a/src/tests/aoc_2022_14/src/types.pr.rs b/src/tests/aoc_2022_14/src/types.pr.rs new file mode 100644 index 0000000..9d36060 --- /dev/null +++ b/src/tests/aoc_2022_14/src/types.pr.rs @@ -0,0 +1,12 @@ +/*SPEC* +property order-preserved { + \c <: (Container, Indexable) -> (forall \x -> ((equal? (op-last ((op-insert c) x))) x)) +} + +property unique { + \c <: (Container) -> ((for-all-elems c) \a -> ((unique-count? a) c)) +} + +type List = {c impl (Container, Indexable) | (order-preserved c)} +type Set = {c impl (Container) | (unique c)} + *ENDSPEC*/ -- cgit v1.2.3