rust(day17): Optimize to run in 34 ms
This commit is contained in:
parent
7b6e8f05e0
commit
90e0a3060e
3 changed files with 73 additions and 123 deletions
50
rust/Cargo.lock
generated
50
rust/Cargo.lock
generated
|
@ -1,56 +1,6 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# 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]]
|
||||
name = "aoc"
|
||||
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
|
||||
|
||||
[dependencies]
|
||||
regex = "1.4.2"
|
||||
|
|
|
@ -1,99 +1,100 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
const SIZE: usize = 50;
|
||||
const SIZE: usize = 20;
|
||||
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();
|
||||
for (z, slice) in field.iter().enumerate() {
|
||||
for (y, row) in slice.iter().enumerate() {
|
||||
for (x, cell) in row.iter().enumerate() {
|
||||
for w in 0..hypercube.len() as i64 {
|
||||
for z in 0..SIZE as i64 {
|
||||
for y in 0..SIZE as i64 {
|
||||
for x in 0..SIZE as i64 {
|
||||
let mut neighbors = 0;
|
||||
for dw in -1..=1 {
|
||||
for dz in -1..=1 {
|
||||
for dy in -1..=1 {
|
||||
for dx in -1..=1 {
|
||||
let nx = dx + x as i64;
|
||||
let ny = dy + y as i64;
|
||||
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)
|
||||
|| (nx < 0 || nx >= SIZE as i64)
|
||||
|| (ny < 0 || ny >= SIZE as i64)
|
||||
|| (nz < 0 || nz >= SIZE as i64)
|
||||
if !(nx == x && ny == y && nz == z && nw == w)
|
||||
&& !(nx < 0 || nx >= SIZE as i64)
|
||||
&& !(ny < 0 || ny >= SIZE as i64)
|
||||
&& !(nz < 0 || nz >= SIZE as i64)
|
||||
&& !(nw < 0 || nw >= hypercube.len() as i64)
|
||||
&& hypercube[nw as usize][nz as usize][ny as usize]
|
||||
[nx as usize]
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if field[nz as usize][ny as usize][nx as usize] {
|
||||
neighbors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if *cell && neighbors != 2 && neighbors != 3 {
|
||||
changes.push((x, y, z, false));
|
||||
let cell = hypercube[w as usize][z as usize][y as usize][x as usize];
|
||||
if cell && neighbors != 2 && neighbors != 3 {
|
||||
changes.push((x, y, z, w, false));
|
||||
}
|
||||
if !cell && neighbors == 3 {
|
||||
changes.push((x, y, z, true));
|
||||
changes.push((x, y, z, w, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (x, y, z, state) in changes {
|
||||
field[z][y][x] = state;
|
||||
for (x, y, z, w, state) in changes {
|
||||
hypercube[w as usize][z as usize][y as usize][x as usize] = state;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(_: bool) -> Duration {
|
||||
let input = std::fs::read_to_string("../inputs/17").unwrap();
|
||||
pub fn simulate(input: &str, n: usize) -> usize {
|
||||
assert!(n == 3 || n == 4);
|
||||
|
||||
let instant = Instant::now();
|
||||
let w_size = if n == 3 { 1 } else { SIZE };
|
||||
let w_offset = if n == 3 { 0 } else { OFFSET };
|
||||
|
||||
let mut field = vec![vec![vec![false; SIZE]; SIZE]; SIZE];
|
||||
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[OFFSET][y + OFFSET - 1][x + OFFSET - 1] = cell == '#';
|
||||
field[w_offset][OFFSET][y + OFFSET - 2][x + OFFSET - 2] = cell == '#';
|
||||
}
|
||||
}
|
||||
|
||||
// for y in 0..SIZE {
|
||||
// for x in 0..SIZE {
|
||||
// print!("{}", if field[OFFSET][y][x] { '#' } else { '.' });
|
||||
// }
|
||||
// println!();
|
||||
// }
|
||||
|
||||
for i in 0..6 {
|
||||
for _ 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 cube in field {
|
||||
for slice in &cube {
|
||||
for row in slice {
|
||||
for cell in row {
|
||||
for &cell in row {
|
||||
if cell {
|
||||
alive += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dbg!(alive);
|
||||
}
|
||||
alive
|
||||
}
|
||||
|
||||
pub fn run(print: bool) -> Duration {
|
||||
let input = std::fs::read_to_string("../inputs/17").unwrap();
|
||||
|
||||
let instant = Instant::now();
|
||||
|
||||
let part1 = simulate(&input, 3);
|
||||
let part2 = simulate(&input, 4);
|
||||
if print {
|
||||
dbg!(part1, part2);
|
||||
}
|
||||
|
||||
instant.elapsed()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue