rust(day17): Optimize to run in 34 ms
This commit is contained in:
parent
7b6e8f05e0
commit
90e0a3060e
|
@ -1,56 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
|
||||||
name = "aho-corasick"
|
|
||||||
version = "0.7.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aoc"
|
name = "aoc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
|
||||||
"regex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lazy_static"
|
|
||||||
version = "1.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "memchr"
|
|
||||||
version = "2.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "1.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
|
||||||
dependencies = [
|
|
||||||
"aho-corasick",
|
|
||||||
"memchr",
|
|
||||||
"regex-syntax",
|
|
||||||
"thread_local",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex-syntax"
|
|
||||||
version = "0.6.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thread_local"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
]
|
|
||||||
|
|
|
@ -7,4 +7,3 @@ edition = "2018"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1.4.2"
|
|
||||||
|
|
|
@ -1,99 +1,100 @@
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
const SIZE: usize = 50;
|
const SIZE: usize = 20;
|
||||||
const OFFSET: usize = SIZE / 2;
|
const OFFSET: usize = SIZE / 2;
|
||||||
|
|
||||||
type Field = Vec<Vec<Vec<bool>>>;
|
type Field = Vec<[[[bool; SIZE]; SIZE]; SIZE]>;
|
||||||
|
|
||||||
pub fn step(field: &mut Field) {
|
pub fn step(hypercube: &mut Field) {
|
||||||
let mut changes = Vec::new();
|
let mut changes = Vec::new();
|
||||||
for (z, slice) in field.iter().enumerate() {
|
for w in 0..hypercube.len() as i64 {
|
||||||
for (y, row) in slice.iter().enumerate() {
|
for z in 0..SIZE as i64 {
|
||||||
for (x, cell) in row.iter().enumerate() {
|
for y in 0..SIZE as i64 {
|
||||||
let mut neighbors = 0;
|
for x in 0..SIZE as i64 {
|
||||||
for dz in -1..=1 {
|
let mut neighbors = 0;
|
||||||
for dy in -1..=1 {
|
for dw in -1..=1 {
|
||||||
for dx in -1..=1 {
|
for dz in -1..=1 {
|
||||||
let nx = dx + x as i64;
|
for dy in -1..=1 {
|
||||||
let ny = dy + y as i64;
|
for dx in -1..=1 {
|
||||||
let nz = dz + z as i64;
|
let nx = dx + x;
|
||||||
|
let ny = dy + y;
|
||||||
|
let nz = dz + z;
|
||||||
|
let nw = dw + w;
|
||||||
|
|
||||||
if (nx == x as i64 && ny == y as i64 && nz == z as i64)
|
if !(nx == x && ny == y && nz == z && nw == w)
|
||||||
|| (nx < 0 || nx >= SIZE as i64)
|
&& !(nx < 0 || nx >= SIZE as i64)
|
||||||
|| (ny < 0 || ny >= SIZE as i64)
|
&& !(ny < 0 || ny >= SIZE as i64)
|
||||||
|| (nz < 0 || nz >= SIZE as i64)
|
&& !(nz < 0 || nz >= SIZE as i64)
|
||||||
{
|
&& !(nw < 0 || nw >= hypercube.len() as i64)
|
||||||
continue;
|
&& hypercube[nw as usize][nz as usize][ny as usize]
|
||||||
}
|
[nx as usize]
|
||||||
|
{
|
||||||
if field[nz as usize][ny as usize][nx as usize] {
|
neighbors += 1;
|
||||||
neighbors += 1;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if *cell && neighbors != 2 && neighbors != 3 {
|
let cell = hypercube[w as usize][z as usize][y as usize][x as usize];
|
||||||
changes.push((x, y, z, false));
|
if cell && neighbors != 2 && neighbors != 3 {
|
||||||
}
|
changes.push((x, y, z, w, false));
|
||||||
if !cell && neighbors == 3 {
|
}
|
||||||
changes.push((x, y, z, true));
|
if !cell && neighbors == 3 {
|
||||||
|
changes.push((x, y, z, w, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x, y, z, state) in changes {
|
for (x, y, z, w, state) in changes {
|
||||||
field[z][y][x] = state;
|
hypercube[w as usize][z as usize][y as usize][x as usize] = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(_: bool) -> Duration {
|
pub fn simulate(input: &str, n: usize) -> usize {
|
||||||
|
assert!(n == 3 || n == 4);
|
||||||
|
|
||||||
|
let w_size = if n == 3 { 1 } else { SIZE };
|
||||||
|
let w_offset = if n == 3 { 0 } else { OFFSET };
|
||||||
|
|
||||||
|
let mut field = vec![[[[false; SIZE]; SIZE]; SIZE]; w_size];
|
||||||
|
for (y, line) in input.lines().enumerate() {
|
||||||
|
for (x, cell) in line.chars().enumerate() {
|
||||||
|
field[w_offset][OFFSET][y + OFFSET - 2][x + OFFSET - 2] = cell == '#';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ in 0..6 {
|
||||||
|
step(&mut field);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut alive = 0;
|
||||||
|
for cube in field {
|
||||||
|
for slice in &cube {
|
||||||
|
for row in slice {
|
||||||
|
for &cell in row {
|
||||||
|
if cell {
|
||||||
|
alive += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alive
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(print: bool) -> Duration {
|
||||||
let input = std::fs::read_to_string("../inputs/17").unwrap();
|
let input = std::fs::read_to_string("../inputs/17").unwrap();
|
||||||
|
|
||||||
let instant = Instant::now();
|
let instant = Instant::now();
|
||||||
|
|
||||||
let mut field = vec![vec![vec![false; SIZE]; SIZE]; SIZE];
|
let part1 = simulate(&input, 3);
|
||||||
for (y, line) in input.lines().enumerate() {
|
let part2 = simulate(&input, 4);
|
||||||
for (x, cell) in line.chars().enumerate() {
|
if print {
|
||||||
field[OFFSET][y + OFFSET - 1][x + OFFSET - 1] = cell == '#';
|
dbg!(part1, part2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for y in 0..SIZE {
|
|
||||||
// for x in 0..SIZE {
|
|
||||||
// print!("{}", if field[OFFSET][y][x] { '#' } else { '.' });
|
|
||||||
// }
|
|
||||||
// println!();
|
|
||||||
// }
|
|
||||||
|
|
||||||
for i in 0..6 {
|
|
||||||
step(&mut field);
|
|
||||||
|
|
||||||
println!("step {}:", i + 1);
|
|
||||||
// for z in (OFFSET - 1)..=(OFFSET + 1) {
|
|
||||||
// println!("z = {}", z as i64 - OFFSET as i64);
|
|
||||||
// for y in 0..SIZE {
|
|
||||||
// for x in 0..SIZE {
|
|
||||||
// print!("{}", if field[z][y][x] { '#' } else { '.' });
|
|
||||||
// }
|
|
||||||
// println!();
|
|
||||||
// }
|
|
||||||
// println!();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut alive = 0;
|
|
||||||
for slice in field {
|
|
||||||
for row in slice {
|
|
||||||
for cell in row {
|
|
||||||
if cell {
|
|
||||||
alive += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbg!(alive);
|
|
||||||
|
|
||||||
instant.elapsed()
|
instant.elapsed()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue