Compare commits
1 Commits
4a8c5580ff
...
experiment
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f1500accd |
136
Cargo.lock
generated
136
Cargo.lock
generated
@@ -5,6 +5,7 @@ name = "advent-of-code-2020-rust"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
"usize_cast",
|
"usize_cast",
|
||||||
]
|
]
|
||||||
@@ -18,18 +19,147 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const_fn"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"const_fn",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"memoffset",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"cfg-if",
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.81"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.3.4"
|
version = "2.3.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_cpus"
|
||||||
|
version = "1.13.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"lazy_static",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
@@ -48,6 +178,12 @@ version = "0.6.21"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thread_local"
|
name = "thread_local"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
|||||||
@@ -10,3 +10,4 @@ edition = "2018"
|
|||||||
regex = "1"
|
regex = "1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
usize_cast = "1.0.0"
|
usize_cast = "1.0.0"
|
||||||
|
rayon = "1.5.0"
|
||||||
96
src/day11.rs
96
src/day11.rs
@@ -2,19 +2,27 @@ use super::util;
|
|||||||
use crate::day11::GridState::Floor;
|
use crate::day11::GridState::Floor;
|
||||||
use crate::day11::GridState::FilledSeat;
|
use crate::day11::GridState::FilledSeat;
|
||||||
use crate::day11::GridState::EmptySeat;
|
use crate::day11::GridState::EmptySeat;
|
||||||
|
use rayon::prelude::*;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
pub fn solve() {
|
pub fn solve() {
|
||||||
let lines = util::read_file("input/day11.txt");
|
let lines = util::read_file("input/day11.txt");
|
||||||
|
|
||||||
let seats = Seats::parse(&lines, 1);
|
let seats = Seats::parse(&lines);
|
||||||
|
|
||||||
|
let now = Instant::now();
|
||||||
|
|
||||||
let part1 = solve_part1(&seats);
|
let part1 = solve_part1(&seats);
|
||||||
|
|
||||||
|
println!("Part 1 took: {} μs", now.elapsed().as_micros());
|
||||||
println!("Day 11 Part 1: {}", part1);
|
println!("Day 11 Part 1: {}", part1);
|
||||||
|
|
||||||
|
let now2 = Instant::now();
|
||||||
|
|
||||||
let visible_chairs = seats.calculate_all_visible_chairs();
|
let visible_chairs = seats.calculate_all_visible_chairs();
|
||||||
let part2 = solve_part2(&seats, &visible_chairs);
|
let part2 = solve_part2(&seats, &visible_chairs);
|
||||||
|
|
||||||
|
println!("Part 2 took: {} μs", now2.elapsed().as_micros());
|
||||||
println!("Day 11 Part 2: {}", part2);
|
println!("Day 11 Part 2: {}", part2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,28 +31,39 @@ fn solve_part1(seats: &Seats) -> usize {
|
|||||||
let mut last_seats = seats.clone();
|
let mut last_seats = seats.clone();
|
||||||
let mut next_seats = seats.clone();
|
let mut next_seats = seats.clone();
|
||||||
|
|
||||||
loop {
|
let mut seat_idxs = Vec::new();
|
||||||
let mut changes = false;
|
for y in 0..seats.height {
|
||||||
for y in 1..seats.height-1 {
|
for x in 0..seats.width {
|
||||||
for x in 1..seats.width-1 {
|
let seat = seats.get(&x, &y);
|
||||||
let seat = last_seats.get(&x, &y);
|
if seat != &Floor {
|
||||||
if seat != &Floor {
|
seat_idxs.push((x, y));
|
||||||
let occupied = last_seats.count_occupied_neighbors(&x, &y);
|
|
||||||
if seat == &EmptySeat && occupied == 0 {
|
|
||||||
changes = true;
|
|
||||||
next_seats.set(&x, &y, FilledSeat);
|
|
||||||
} else if seat == &FilledSeat && occupied >= 4 {
|
|
||||||
next_seats.set(&x, &y, EmptySeat);
|
|
||||||
changes = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// next_seats.print();
|
}
|
||||||
if !changes {
|
loop {
|
||||||
|
let changes: Vec<(usize, usize, &GridState)> = seat_idxs.par_iter().map(|pos| {
|
||||||
|
let x = &pos.0;
|
||||||
|
let y = &pos.1;
|
||||||
|
let seat = last_seats.get(x, y);
|
||||||
|
let occupied = last_seats.count_occupied_neighbors(x, y);
|
||||||
|
if seat == &EmptySeat && occupied == 0 {
|
||||||
|
return Option::from((pos.0, pos.1, &FilledSeat));
|
||||||
|
} else if seat == &FilledSeat && occupied >= 4 {
|
||||||
|
return Option::from((pos.0, pos.1, &EmptySeat));
|
||||||
|
} else {
|
||||||
|
return Option::None;
|
||||||
|
}
|
||||||
|
}).filter(|o| o.is_some()).map(|o| o.unwrap()).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if changes.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for change in changes {
|
||||||
|
next_seats.set(&change.0, &change.1, *change.2);
|
||||||
|
}
|
||||||
|
// next_seats.print();
|
||||||
|
|
||||||
last_seats = next_seats.clone();
|
last_seats = next_seats.clone();
|
||||||
}
|
}
|
||||||
return last_seats.grid.iter().filter(|s| s == &&FilledSeat).count();
|
return last_seats.grid.iter().filter(|s| s == &&FilledSeat).count();
|
||||||
@@ -55,7 +74,11 @@ fn solve_part2(seats: &Seats, visible_chairs: &Vec<Option<Vec<(usize, usize)>>>)
|
|||||||
let mut last_seats = seats.clone();
|
let mut last_seats = seats.clone();
|
||||||
let mut next_seats = seats.clone();
|
let mut next_seats = seats.clone();
|
||||||
|
|
||||||
|
let mut calc_times = Vec::new();
|
||||||
|
let mut copy_times = Vec::new();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
let calc_start = Instant::now();
|
||||||
let mut changes = false;
|
let mut changes = false;
|
||||||
for y in 0..seats.height {
|
for y in 0..seats.height {
|
||||||
for x in 0..seats.width {
|
for x in 0..seats.width {
|
||||||
@@ -66,8 +89,8 @@ fn solve_part2(seats: &Seats, visible_chairs: &Vec<Option<Vec<(usize, usize)>>>)
|
|||||||
changes = true;
|
changes = true;
|
||||||
next_seats.set(&x, &y, FilledSeat);
|
next_seats.set(&x, &y, FilledSeat);
|
||||||
} else if seat == &FilledSeat && occupied >= 5 {
|
} else if seat == &FilledSeat && occupied >= 5 {
|
||||||
changes = true;
|
|
||||||
next_seats.set(&x, &y, EmptySeat);
|
next_seats.set(&x, &y, EmptySeat);
|
||||||
|
changes = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,9 +99,15 @@ fn solve_part2(seats: &Seats, visible_chairs: &Vec<Option<Vec<(usize, usize)>>>)
|
|||||||
if !changes {
|
if !changes {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
calc_times.push(calc_start.elapsed().as_micros());
|
||||||
|
|
||||||
|
let now = Instant::now();
|
||||||
last_seats = next_seats.clone();
|
last_seats = next_seats.clone();
|
||||||
|
copy_times.push(now.elapsed().as_micros());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("Avg calc time: {} μs", calc_times.iter().sum::<u128>() / (calc_times.len() as u128));
|
||||||
|
println!("Avg copy time: {} μs", copy_times.iter().sum::<u128>() / (copy_times.len() as u128));
|
||||||
return last_seats.grid.iter().filter(|s| s == &&FilledSeat).count();
|
return last_seats.grid.iter().filter(|s| s == &&FilledSeat).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,16 +123,16 @@ impl Seats {
|
|||||||
|
|
||||||
const DIRECTIONS: [(i32, i32); 8] = [(-1, 1), (-1, 0), (-1, -1), (0, -1), (0, 1), (1, 1), (1, 0), (1, -1)];
|
const DIRECTIONS: [(i32, i32); 8] = [(-1, 1), (-1, 0), (-1, -1), (0, -1), (0, 1), (1, 1), (1, 0), (1, -1)];
|
||||||
|
|
||||||
fn parse(lines: &Vec<String>, padding: usize) -> Seats {
|
fn parse(lines: &Vec<String>) -> Seats {
|
||||||
|
|
||||||
let height = lines.len() + padding * 2;
|
let height = lines.len();
|
||||||
let width = lines[0].len() + padding * 2;
|
let width = lines[0].len();
|
||||||
let mut grid = vec!(GridState::Floor; width * height);
|
let mut grid = vec!(GridState::Floor; width * height);
|
||||||
for y in 0..lines.len() {
|
for y in 0..lines.len() {
|
||||||
let line = &lines[y];
|
let line = &lines[y];
|
||||||
let mut line_chars = line.chars();
|
let mut line_chars = line.chars();
|
||||||
for x in 0..lines[0].len() {
|
for x in 0..lines[0].len() {
|
||||||
grid[(x + padding) + (y + padding) * width] = GridState::parse(&line_chars.next().unwrap())
|
grid[x + y * width] = GridState::parse(&line_chars.next().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,15 +199,20 @@ impl Seats {
|
|||||||
|
|
||||||
fn count_occupied_neighbors(&self, x: &usize, y: &usize) -> u8 {
|
fn count_occupied_neighbors(&self, x: &usize, y: &usize) -> u8 {
|
||||||
|
|
||||||
|
let x_upper = x == &(self.width - &ONE);
|
||||||
|
let x_lower = x == &0;
|
||||||
|
let y_upper = y == &(self.height - &ONE);
|
||||||
|
let y_lower = y == &0;
|
||||||
|
|
||||||
return
|
return
|
||||||
if self.is_occupied(&(x - &ONE), &(y - &ONE)) { 1 } else { 0 } +
|
if !x_lower && !y_lower && self.is_occupied(&(x - &ONE), &(y - &ONE)) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&(x - &ONE), &y) { 1 } else { 0 } +
|
if !x_lower && self.is_occupied(&(x - &ONE), &y) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&(x - &ONE), &(y + ONE)) { 1 } else { 0 } +
|
if !x_lower && !y_upper && self.is_occupied(&(x - &ONE), &(y + ONE)) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&x, &(y - ONE)) { 1 } else { 0 } +
|
if !y_lower && self.is_occupied(&x, &(y - ONE)) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&x, &(y + ONE)) { 1 } else { 0 } +
|
if !y_upper && self.is_occupied(&x, &(y + ONE)) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&(x + ONE), &(y - ONE)) { 1 } else { 0 } +
|
if !x_upper && !y_lower && self.is_occupied(&(x + ONE), &(y - ONE)) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&(x + ONE), &y) { 1 } else { 0 } +
|
if !x_upper && self.is_occupied(&(x + ONE), &y) { 1 } else { 0 } +
|
||||||
if self.is_occupied(&(x + ONE), &(y + ONE)) { 1 } else { 0 }
|
if !x_upper && !y_upper && self.is_occupied(&(x + ONE), &(y + ONE)) { 1 } else { 0 }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user