Compare commits
21 Commits
6f30146a2b
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
00bcb17d76 | ||
![]() |
d6ae1b03b1 | ||
![]() |
0444d97d13 | ||
![]() |
067f31bf4e | ||
![]() |
9324bc2ccc | ||
![]() |
fc5e45dcbf | ||
![]() |
d6efa60716 | ||
![]() |
73f6305410 | ||
![]() |
867a987508 | ||
![]() |
049a2181ad | ||
![]() |
865f4cf564 | ||
![]() |
1520c8af9d | ||
![]() |
90ffdd2029 | ||
![]() |
f80d4f41f4 | ||
![]() |
34c7808394 | ||
![]() |
e3d4b31f88 | ||
![]() |
672e465976 | ||
![]() |
1c368042c2 | ||
![]() |
c41e546be5 | ||
![]() |
b5943d5ce5 | ||
![]() |
ba7b8521cd |
7
day12/Cargo.lock
generated
Normal file
7
day12/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
17
day12/Cargo.toml
Normal file
17
day12/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "dp"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
[[bin]]
|
||||
name = "old"
|
||||
path= "src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "dp"
|
||||
path= "src/main_dp.rs"
|
1000
day12/input.txt
Normal file
1000
day12/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
247
day12/src/main.rs
Normal file
247
day12/src/main.rs
Normal file
@@ -0,0 +1,247 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
use std::iter;
|
||||
|
||||
// Counts all options by advancing through the spring layout from left to right, splitting at
|
||||
// possible uncertainities. Groups sequences of uncertain values and uses combinatorics.
|
||||
fn count_options(layout: &[u8], broken_sequences: &[u32], sum_broken: u32) -> u64 {
|
||||
// Assuming sum_broken must be sum of broken_sequences
|
||||
// If no more broken need to be placed, the remaining are all unbroken
|
||||
if sum_broken == 0 {
|
||||
// If the remaining data contains a surely broken spring, the configuration is impossible
|
||||
if layout.contains(&b'#') {
|
||||
return 0;
|
||||
}
|
||||
// The rest are not broken, 1 option
|
||||
return 1;
|
||||
}
|
||||
// Go ahead in the layout to find place where a split of options is
|
||||
let mut split_position = 0;
|
||||
// Skip through all unbroken
|
||||
while split_position < layout.len() && layout[split_position] == b'.' {
|
||||
split_position += 1;
|
||||
}
|
||||
// Found no place to fit remaining broken springs, impossible
|
||||
if layout.len() - split_position < sum_broken as usize + broken_sequences.len() - 1 {
|
||||
return 0;
|
||||
}
|
||||
// Count amount of uncertain springs (can be zero)
|
||||
let mut num_uncertain: usize = 0;
|
||||
while split_position < layout.len() && layout[split_position] == b'?' {
|
||||
split_position += 1;
|
||||
num_uncertain += 1;
|
||||
}
|
||||
if split_position == layout.len() || layout[split_position] == b'.' {
|
||||
// Block of 1 or more uncertain springs followed by a unbroken spring
|
||||
let mut sum_options = 0;
|
||||
// Initially try assuming all the question marks will be unbroken
|
||||
if split_position < layout.len() {
|
||||
sum_options += count_options(&layout[split_position + 1..], broken_sequences, sum_broken);
|
||||
}
|
||||
// Taking some number of elements from broken sequences
|
||||
let mut num_elems_taken = 1;
|
||||
let mut sum_elems_taken = broken_sequences[0];
|
||||
while num_elems_taken <= broken_sequences.len() && sum_elems_taken as usize + num_elems_taken - 1 <= num_uncertain {
|
||||
// If the split was done due to end of input, it's the length, otherwise advance by 1
|
||||
let corrected_split_position = std::cmp::min(split_position + 1, layout.len());
|
||||
// Multiplying the combination of elements before with recursive options after
|
||||
let pre_split_options = count_options_in_uncertain(num_uncertain as u64, sum_elems_taken as u64, num_elems_taken as u64);
|
||||
let post_split_options = count_options(
|
||||
&layout[corrected_split_position..],
|
||||
&broken_sequences[num_elems_taken..], sum_broken - sum_elems_taken);
|
||||
sum_options += pre_split_options * post_split_options;
|
||||
// Prepare for the next iteration
|
||||
if num_elems_taken < broken_sequences.len() {
|
||||
sum_elems_taken += broken_sequences[num_elems_taken];
|
||||
}
|
||||
num_elems_taken += 1;
|
||||
}
|
||||
return sum_options;
|
||||
} else {
|
||||
// Block of 0 or more uncertain springs followed by at least one broken spring
|
||||
let mut sum_options = 0;
|
||||
// Count how many known broken elements there are after the uncertain
|
||||
let mut last_min_length = 0;
|
||||
while split_position < layout.len() && layout[split_position] == b'#' {
|
||||
split_position += 1;
|
||||
last_min_length += 1;
|
||||
}
|
||||
let extended_num_uncertain = num_uncertain + last_min_length;
|
||||
// Taking some number of elements from broken sequences
|
||||
let mut last_taken_index = 0;
|
||||
let mut sum_elems_taken_no_last: u32 = 0;
|
||||
while last_taken_index < broken_sequences.len() {
|
||||
// Length of last element that is taken, we need to fit it around the end of the region
|
||||
let last_length = broken_sequences[last_taken_index];
|
||||
// Putting the last elem at some offset, subtracted from split_position
|
||||
let mut last_offset = last_min_length;
|
||||
while last_offset <= last_length as usize && last_offset <= extended_num_uncertain {
|
||||
// If sum of taken elements with free spaces (last_taken_index) doesn't fit in the
|
||||
// uncertainity region
|
||||
if sum_elems_taken_no_last as usize + last_taken_index > extended_num_uncertain - last_offset {
|
||||
break;
|
||||
}
|
||||
// Multiplying the combination of elements before with recursive options after
|
||||
let pre_split_options;
|
||||
if extended_num_uncertain > last_offset + 1 {
|
||||
pre_split_options = count_options_in_uncertain(
|
||||
(extended_num_uncertain - last_offset - 1) as u64, sum_elems_taken_no_last as u64, last_taken_index as u64);
|
||||
} else {
|
||||
pre_split_options = 1;
|
||||
}
|
||||
let post_split_options = count_options_consume_sequence(
|
||||
&layout[split_position - last_offset..],
|
||||
&broken_sequences[last_taken_index..], sum_broken - sum_elems_taken_no_last);
|
||||
sum_options += pre_split_options * post_split_options;
|
||||
// Prepare for the next iteration
|
||||
last_offset += 1;
|
||||
}
|
||||
// Prepare for the next iteration
|
||||
sum_elems_taken_no_last += broken_sequences[last_taken_index];
|
||||
last_taken_index += 1;
|
||||
}
|
||||
return sum_options;
|
||||
}
|
||||
}
|
||||
|
||||
fn choose(n: u64, k: u64) -> u64 {
|
||||
let mut prod = 1;
|
||||
let mut n_copy = n;
|
||||
for i in 1..=k {
|
||||
prod *= n_copy;
|
||||
n_copy -= 1;
|
||||
prod /= i;
|
||||
}
|
||||
prod
|
||||
}
|
||||
|
||||
fn count_options_in_uncertain(length_uncertain: u64, sum_broken: u64, num_broken: u64) -> u64 {
|
||||
let slots = length_uncertain - sum_broken + 1;
|
||||
// slots choose num_broken
|
||||
if slots == 0 || num_broken == 0 {
|
||||
return 1;
|
||||
}
|
||||
choose(slots, num_broken)
|
||||
}
|
||||
|
||||
// Helper function for count_options, assuming that a sequence of broken springs starts at
|
||||
// the beginning of the slice and that sum_broken is sum of broken_sequences and is not 0
|
||||
fn count_options_consume_sequence(layout: &[u8], broken_sequences: &[u32], sum_broken: u32) -> u64 {
|
||||
let mut sequence_position = 0usize;
|
||||
let target_position = sequence_position + broken_sequences[0] as usize;
|
||||
// If we'd run out of space trying to process this option, impossible
|
||||
if target_position > layout.len() {
|
||||
return 0;
|
||||
}
|
||||
// Go through all potentially broken elements
|
||||
while sequence_position < target_position && layout[sequence_position] != b'.' {
|
||||
sequence_position += 1;
|
||||
}
|
||||
// If found a surely unbroken element before end of sequence, impossible
|
||||
if sequence_position < target_position {
|
||||
return 0;
|
||||
}
|
||||
// If we aren't at the end of sequence
|
||||
if sequence_position < layout.len() {
|
||||
// If there's yet another surely broken spring, the sequence would be too long, impossible
|
||||
if layout[sequence_position] == b'#' {
|
||||
return 0;
|
||||
}
|
||||
// If there's a following unbroken element, advance through that because count_options
|
||||
// assumes with each call that we're starting from a fresh potential sequence
|
||||
sequence_position += 1;
|
||||
}
|
||||
// Call count_options recursively with advanced layout options and consumed one sequence
|
||||
count_options(&layout[sequence_position..], &broken_sequences[1..],
|
||||
sum_broken - broken_sequences[0])
|
||||
}
|
||||
|
||||
// Generate all configurations of replacing '?' with '#' or '.'
|
||||
fn generate_naive_options(layout: &[u8]) -> Vec<Vec<u8>> {
|
||||
let mut split_position = 0;
|
||||
while split_position < layout.len() && layout[split_position] != b'?' {
|
||||
split_position += 1;
|
||||
}
|
||||
if split_position == layout.len() {
|
||||
return vec![Vec::from(layout)];
|
||||
}
|
||||
let mut prefix1 = Vec::from(&layout[..=split_position]);
|
||||
let mut prefix2 = Vec::from(&layout[..=split_position]);
|
||||
prefix1[split_position] = b'#';
|
||||
prefix2[split_position] = b'.';
|
||||
let mut merged: Vec<Vec<u8>> = Vec::new();
|
||||
let options = generate_naive_options(&layout[split_position + 1..]);
|
||||
for option in options {
|
||||
let mut prefix1_clone = prefix1.clone();
|
||||
let mut prefix2_clone = prefix2.clone();
|
||||
prefix1_clone.extend_from_slice(&option);
|
||||
prefix2_clone.extend_from_slice(&option);
|
||||
merged.push(prefix1_clone);
|
||||
merged.push(prefix2_clone);
|
||||
}
|
||||
merged
|
||||
}
|
||||
|
||||
// Generate all configurations and test them
|
||||
fn count_naive_options(layout: &[u8], broken_sequences: &[u32]) -> u32 {
|
||||
let options = generate_naive_options(&layout);
|
||||
options.iter().filter(|&option| {
|
||||
let mut position = 0;
|
||||
for &length in broken_sequences {
|
||||
while position < option.len() && option[position] == b'.' {
|
||||
position += 1;
|
||||
}
|
||||
let target_position = position + length as usize;
|
||||
if target_position > option.len() {
|
||||
return false;
|
||||
}
|
||||
while position < target_position && option[position] == b'#' {
|
||||
position += 1;
|
||||
}
|
||||
if position != target_position {
|
||||
return false;
|
||||
}
|
||||
if position < option.len() {
|
||||
if option[position] == b'#' {
|
||||
return false;
|
||||
}
|
||||
position += 1;
|
||||
}
|
||||
}
|
||||
while position < option.len() {
|
||||
if option[position] != b'.' {
|
||||
return false;
|
||||
}
|
||||
position += 1;
|
||||
}
|
||||
true
|
||||
}).count() as u32
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut sum1 = 0u64;
|
||||
let mut sum2 = 0u64;
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let layout_str = split_whitespace.next().unwrap();
|
||||
let layout = layout_str.bytes().collect::<Vec<_>>();
|
||||
let layout2 = layout_str.bytes().chain(iter::once(b'?')).cycle().take(layout.len() * 5 + 4).collect::<Vec<_>>();
|
||||
let numbers = split_whitespace.next().unwrap()
|
||||
.split(',').map(|str| str.parse::<u32>().unwrap()).collect::<Vec<_>>();
|
||||
let numbers2 = numbers.iter().cycle().take(numbers.len() * 5).copied().collect::<Vec<_>>();
|
||||
let sum_numbers = numbers.iter().sum::<u32>();
|
||||
let sum_numbers2 = sum_numbers * 5;
|
||||
let options = count_options(&layout, &numbers, sum_numbers) as u64;
|
||||
sum1 += options;
|
||||
sum2 += count_options(&layout2, &numbers2, sum_numbers2) as u64;
|
||||
}
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
240
day12/src/main_dp.rs
Normal file
240
day12/src/main_dp.rs
Normal file
@@ -0,0 +1,240 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
use std::iter;
|
||||
|
||||
const PRINT_VALUES: bool = false;
|
||||
const PRINT_VISUALISATION: bool = false;
|
||||
|
||||
// Creates a cache for count_options_with_cache and calls it
|
||||
fn count_options_dp(layout: &[u8], broken_sequences: &[u32], sum_broken: u32) -> u64 {
|
||||
// Indexed with [a][b], storing results for computation, last a elements of layout
|
||||
// and last b elements of broken_sequences, u64::MAX are values that aren't computed yet
|
||||
let mut cache: Vec<Vec<u64>> = vec![vec![u64::MAX; broken_sequences.len() + 1]; layout.len() + 1];
|
||||
// For empty layout and empty broken sequences there's one option
|
||||
cache[0][0] = 1;
|
||||
cache[0][1..].iter_mut().for_each(|x| *x = 0);
|
||||
// Get the result
|
||||
let result = count_options_with_cache(layout, broken_sequences, sum_broken, &mut cache);
|
||||
// Visualise
|
||||
if PRINT_VISUALISATION {
|
||||
cache[layout.len()][broken_sequences.len()] = result;
|
||||
println!("{}", std::str::from_utf8(layout).unwrap());
|
||||
for j in 0..broken_sequences.len() + 1 {
|
||||
let row = cache.iter().map(|row| row[j]).collect::<Vec<_>>();
|
||||
println!("{} {:?}", row.iter().map(
|
||||
|&x| match x {
|
||||
0 => '0', u64::MAX => '.', _ => 'X'
|
||||
}).rev().collect::<String>(), &broken_sequences[broken_sequences.len() - j..]);
|
||||
}
|
||||
}
|
||||
if PRINT_VALUES {
|
||||
cache[layout.len()][broken_sequences.len()] = result;
|
||||
println!("{}", std::str::from_utf8(layout).unwrap());
|
||||
for j in 0..broken_sequences.len() + 1 {
|
||||
let row = cache.iter().map(|row| row[j]).collect::<Vec<_>>();
|
||||
println!("{:?} {:?}", row.iter().map(
|
||||
|&x| x as i64).rev().collect::<Vec<_>>(), &broken_sequences[broken_sequences.len() - j..]);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn use_or_update<F: Fn(&mut Vec<Vec<u64>>) -> u64>(cache: &mut Vec<Vec<u64>>, idx1: usize, idx2: usize, update_func: F) -> u64 {
|
||||
if cache[idx1][idx2] == u64::MAX {
|
||||
cache[idx1][idx2] = update_func(cache);
|
||||
}
|
||||
cache[idx1][idx2]
|
||||
}
|
||||
|
||||
// Counts all options by advancing through the spring layout from left to right, splitting at
|
||||
// possible uncertainities. Groups sequences of uncertain values and uses combinatorics.
|
||||
fn count_options_with_cache(layout: &[u8], broken_sequences: &[u32], sum_broken: u32, cache: &mut Vec<Vec<u64>>) -> u64 {
|
||||
// Assuming sum_broken must be sum of broken_sequences
|
||||
// If no more broken need to be placed, the remaining are all unbroken
|
||||
if sum_broken == 0 {
|
||||
// If the remaining data contains a surely broken spring, the configuration is impossible
|
||||
if layout.contains(&b'#') {
|
||||
return 0;
|
||||
}
|
||||
// The rest are not broken, 1 option
|
||||
return 1;
|
||||
}
|
||||
// Go ahead in the layout to find place where a split of options is
|
||||
let mut split_position = 0;
|
||||
// Skip through all unbroken
|
||||
while split_position < layout.len() && layout[split_position] == b'.' {
|
||||
split_position += 1;
|
||||
}
|
||||
// Found no place to fit remaining broken springs, impossible
|
||||
if layout.len() - split_position < sum_broken as usize + broken_sequences.len() - 1 {
|
||||
return 0;
|
||||
}
|
||||
// Count amount of uncertain springs (can be zero)
|
||||
let mut num_uncertain: usize = 0;
|
||||
while split_position < layout.len() && layout[split_position] == b'?' {
|
||||
split_position += 1;
|
||||
num_uncertain += 1;
|
||||
}
|
||||
if split_position == layout.len() || layout[split_position] == b'.' {
|
||||
// Block of 1 or more uncertain springs followed by a unbroken spring
|
||||
let mut sum_options = 0;
|
||||
// Initially try assuming all the question marks will be unbroken
|
||||
if split_position < layout.len() {
|
||||
sum_options += use_or_update(
|
||||
cache, layout.len() - (split_position + 1), broken_sequences.len(),
|
||||
|cache|
|
||||
count_options_with_cache(&layout[split_position + 1..], broken_sequences, sum_broken, cache));
|
||||
}
|
||||
// Taking some number of elements from broken sequences
|
||||
let mut num_elems_taken = 1;
|
||||
let mut sum_elems_taken = broken_sequences[0];
|
||||
while num_elems_taken <= broken_sequences.len() && sum_elems_taken as usize + num_elems_taken - 1 <= num_uncertain {
|
||||
// If the split was done due to end of input, it's the length, otherwise advance by 1
|
||||
let corrected_split_position = std::cmp::min(split_position + 1, layout.len());
|
||||
// Multiplying the combination of elements before with recursive options after
|
||||
let pre_split_options = count_options_in_uncertain(num_uncertain as u64, sum_elems_taken as u64, num_elems_taken as u64);
|
||||
|
||||
let post_split_options = use_or_update(
|
||||
cache, layout.len() - corrected_split_position, broken_sequences.len() - num_elems_taken,
|
||||
|cache| count_options_with_cache(
|
||||
&layout[corrected_split_position..],
|
||||
&broken_sequences[num_elems_taken..], sum_broken - sum_elems_taken, cache));
|
||||
// let post_split_options = count_options_with_cache(
|
||||
// &layout[corrected_split_position..],
|
||||
// &broken_sequences[num_elems_taken..], sum_broken - sum_elems_taken);
|
||||
sum_options += pre_split_options * post_split_options;
|
||||
// Prepare for the next iteration
|
||||
if num_elems_taken < broken_sequences.len() {
|
||||
sum_elems_taken += broken_sequences[num_elems_taken];
|
||||
}
|
||||
num_elems_taken += 1;
|
||||
}
|
||||
return sum_options;
|
||||
} else {
|
||||
// Block of 0 or more uncertain springs followed by at least one broken spring
|
||||
let mut sum_options = 0;
|
||||
// Count how many known broken elements there are after the uncertain
|
||||
let mut last_min_length = 0;
|
||||
while split_position < layout.len() && layout[split_position] == b'#' {
|
||||
split_position += 1;
|
||||
last_min_length += 1;
|
||||
}
|
||||
let extended_num_uncertain = num_uncertain + last_min_length;
|
||||
// Taking some number of elements from broken sequences
|
||||
let mut last_taken_index = 0;
|
||||
let mut sum_elems_taken_no_last: u32 = 0;
|
||||
while last_taken_index < broken_sequences.len() {
|
||||
// Length of last element that is taken, we need to fit it around the end of the region
|
||||
let last_length = broken_sequences[last_taken_index];
|
||||
// Putting the last elem at some offset, subtracted from split_position
|
||||
let mut last_offset = last_min_length;
|
||||
while last_offset <= last_length as usize && last_offset <= extended_num_uncertain {
|
||||
// If sum of taken elements with free spaces (last_taken_index) doesn't fit in the
|
||||
// uncertainity region
|
||||
if sum_elems_taken_no_last as usize + last_taken_index > extended_num_uncertain - last_offset {
|
||||
break;
|
||||
}
|
||||
// Multiplying the combination of elements before with recursive options after
|
||||
let pre_split_options;
|
||||
if extended_num_uncertain > last_offset + 1 {
|
||||
pre_split_options = count_options_in_uncertain(
|
||||
(extended_num_uncertain - last_offset - 1) as u64, sum_elems_taken_no_last as u64, last_taken_index as u64);
|
||||
} else {
|
||||
pre_split_options = 1;
|
||||
}
|
||||
let post_split_options = count_options_consume_sequence_with_cache(
|
||||
&layout[split_position - last_offset..], &broken_sequences[last_taken_index..],
|
||||
sum_broken - sum_elems_taken_no_last, cache);
|
||||
sum_options += pre_split_options * post_split_options;
|
||||
// Prepare for the next iteration
|
||||
last_offset += 1;
|
||||
}
|
||||
// Prepare for the next iteration
|
||||
sum_elems_taken_no_last += broken_sequences[last_taken_index];
|
||||
last_taken_index += 1;
|
||||
}
|
||||
return sum_options;
|
||||
}
|
||||
}
|
||||
|
||||
fn choose(n: u64, k: u64) -> u64 {
|
||||
let mut prod = 1;
|
||||
let mut n_copy = n;
|
||||
for i in 1..=k {
|
||||
prod *= n_copy;
|
||||
n_copy -= 1;
|
||||
prod /= i;
|
||||
}
|
||||
prod
|
||||
}
|
||||
|
||||
fn count_options_in_uncertain(length_uncertain: u64, sum_broken: u64, num_broken: u64) -> u64 {
|
||||
let slots = length_uncertain - sum_broken + 1;
|
||||
// slots choose num_broken
|
||||
if slots == 0 || num_broken == 0 {
|
||||
return 1;
|
||||
}
|
||||
choose(slots, num_broken)
|
||||
}
|
||||
|
||||
// Helper function for count_options, assuming that a sequence of broken springs starts at
|
||||
// the beginning of the slice and that sum_broken is sum of broken_sequences and is not 0
|
||||
fn count_options_consume_sequence_with_cache(layout: &[u8], broken_sequences: &[u32], sum_broken: u32, cache: &mut Vec<Vec<u64>>) -> u64 {
|
||||
let mut sequence_position = 0usize;
|
||||
let target_position = sequence_position + broken_sequences[0] as usize;
|
||||
// If we'd run out of space trying to process this option, impossible
|
||||
if target_position > layout.len() {
|
||||
return 0;
|
||||
}
|
||||
// Go through all potentially broken elements
|
||||
while sequence_position < target_position && layout[sequence_position] != b'.' {
|
||||
sequence_position += 1;
|
||||
}
|
||||
// If found a surely unbroken element before end of sequence, impossible
|
||||
if sequence_position < target_position {
|
||||
return 0;
|
||||
}
|
||||
// If we aren't at the end of sequence
|
||||
if sequence_position < layout.len() {
|
||||
// If there's yet another surely broken spring, the sequence would be too long, impossible
|
||||
if layout[sequence_position] == b'#' {
|
||||
return 0;
|
||||
}
|
||||
// If there's a following unbroken element, advance through that because count_options
|
||||
// assumes with each call that we're starting from a fresh potential sequence
|
||||
sequence_position += 1;
|
||||
}
|
||||
// Call count_options recursively with advanced layout options and consumed one sequence
|
||||
use_or_update(
|
||||
cache, layout.len() - sequence_position, broken_sequences.len() - 1,
|
||||
|cache|
|
||||
count_options_with_cache(&layout[sequence_position..], &broken_sequences[1..],
|
||||
sum_broken - broken_sequences[0], cache))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut sum1 = 0u64;
|
||||
let mut sum2 = 0u64;
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let layout_str = split_whitespace.next().unwrap();
|
||||
let layout = layout_str.bytes().collect::<Vec<_>>();
|
||||
let layout2 = layout_str.bytes().chain(iter::once(b'?')).cycle().take(layout.len() * 5 + 4).collect::<Vec<_>>();
|
||||
let numbers = split_whitespace.next().unwrap()
|
||||
.split(',').map(|str| str.parse::<u32>().unwrap()).collect::<Vec<_>>();
|
||||
let numbers2 = numbers.iter().cycle().take(numbers.len() * 5).copied().collect::<Vec<_>>();
|
||||
let sum_numbers = numbers.iter().sum::<u32>();
|
||||
let sum_numbers2 = sum_numbers * 5;
|
||||
sum1 += count_options_dp(&layout, &numbers, sum_numbers) as u64;
|
||||
sum2 += count_options_dp(&layout2, &numbers2, sum_numbers2) as u64;
|
||||
}
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
7
day13/Cargo.lock
generated
Normal file
7
day13/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day13"
|
||||
version = "0.1.0"
|
8
day13/Cargo.toml
Normal file
8
day13/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day13"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
1347
day13/input.txt
Normal file
1347
day13/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
123
day13/src/main.rs
Normal file
123
day13/src/main.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::iter;
|
||||
use std::cmp;
|
||||
use std::time::Instant;
|
||||
|
||||
fn encode_mirror_row(row: &[u8]) -> u32 {
|
||||
let mut result: u32 = 0;
|
||||
for &c in row {
|
||||
result = (result << 1) | (c as u32 & 1);
|
||||
// match c {
|
||||
// b'#' => result = (result << 1) | 1,
|
||||
// _ => result = result << 1
|
||||
// }
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn encode_mirror_col(rows: &Vec<&[u8]>, index: usize) -> u32 {
|
||||
let mut result = 0;
|
||||
for &row in rows {
|
||||
result = (result << 1) | (row[index] as u32 & 1);
|
||||
// match row[index] {
|
||||
// b'#' => result = (result << 1) | 1,
|
||||
// _ => result = result << 1
|
||||
// }
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn test_mirror_dim(mirror_dim: &Vec<u32>, index: usize) -> bool {
|
||||
let span = cmp::min(index, mirror_dim.len() - index);
|
||||
for i in 0..span {
|
||||
if mirror_dim[index - i - 1] != mirror_dim[index + i] {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn test_mirror_dim_smudge(mirror_dim: &Vec<u32>, index: usize) -> bool {
|
||||
let span = cmp::min(index, mirror_dim.len() - index);
|
||||
let mut num_errors = 0;
|
||||
for i in 0..span {
|
||||
let diff = mirror_dim[index - i - 1] ^ mirror_dim[index + i];
|
||||
num_errors += u32::count_ones(diff)
|
||||
}
|
||||
num_errors == 1
|
||||
}
|
||||
|
||||
fn solution(input_str: &str) -> (u32, u32) {
|
||||
let mut sum1 = 0;
|
||||
let mut sum2 = 0;
|
||||
let mut current_mirror: Vec<&[u8]> = vec![];
|
||||
let mut current_mirror_rows: Vec<u32> = vec![];
|
||||
let mut current_mirror_cols: Vec<u32> = vec![];
|
||||
for line in input_str.lines().chain(iter::once("")) {
|
||||
if !line.is_empty() {
|
||||
let as_bytes = line.as_bytes();
|
||||
current_mirror.push(as_bytes);
|
||||
current_mirror_rows.push(encode_mirror_row(as_bytes));
|
||||
} else {
|
||||
current_mirror_cols.extend((0..current_mirror[0].len()).map(
|
||||
|index| encode_mirror_col(¤t_mirror, index)
|
||||
));
|
||||
// Task 1
|
||||
let mut found = false;
|
||||
for i in 1..current_mirror_rows.len() {
|
||||
if test_mirror_dim(¤t_mirror_rows, i) {
|
||||
sum1 += i as u32 * 100;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
for i in 1..current_mirror_cols.len() {
|
||||
if test_mirror_dim(¤t_mirror_cols, i) {
|
||||
sum1 += i as u32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Task 2
|
||||
found = false;
|
||||
for i in 1..current_mirror_rows.len() {
|
||||
if test_mirror_dim_smudge(¤t_mirror_rows, i) {
|
||||
sum2 += i as u32 * 100;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
for i in 1..current_mirror_cols.len() {
|
||||
if test_mirror_dim_smudge(¤t_mirror_cols, i) {
|
||||
sum2 += i as u32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
current_mirror.clear();
|
||||
current_mirror_rows.clear();
|
||||
current_mirror_cols.clear();
|
||||
}
|
||||
}
|
||||
(sum1, sum2)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut sum1 = 0;
|
||||
let mut sum2 = 0;
|
||||
// For performance measurement
|
||||
for _ in 0..1 {
|
||||
(sum1, sum2) = solution(&input_str);
|
||||
}
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
7
day14/Cargo.lock
generated
Normal file
7
day14/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day14"
|
||||
version = "0.1.0"
|
8
day14/Cargo.toml
Normal file
8
day14/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day14"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
100
day14/input.txt
Normal file
100
day14/input.txt
Normal file
@@ -0,0 +1,100 @@
|
||||
#..#.#.O...OO....##O....#....O.O#.......O.O.#.O..#..........O...#OO.O..OO..#.#..O.O.OO...#.OOO...OO.
|
||||
..O..O#OO#....#.#O.#......#...O...O..O##.....O..........OOO.#......#OOO....#.#..O..O......OO....O.OO
|
||||
O..#O..#O#...O#....O#.O...#.#..##O.O#OOO..OOOOOO.O.#O.O....O......OO#O#..O.........O.#....O..O......
|
||||
O.O.....#O##..OO.........#.........O.#...#..#...OO##......O.....O..OO#.#.##..OO.........O#.#....#.#.
|
||||
......#....#OOOO..O#O...#...O#....O#..#..OO##..###.#.O#.O...#O.#..........O..##....O#O....OO.....O##
|
||||
..##.#O...#......#.O...O.#O.O....#....#..##.........#.O#O.O.#.####..O#.O#......O...#.#.#O..#O...OO#.
|
||||
.OO.O....O#.O..O.......O.OO#O....#..O.#....OO##..O.O....O...O.#....#......O....#.O..OO....OO..#....#
|
||||
..OOO......#..#.....#.O.........O....OO..##.OO##...#.#.O#.#......#....###...#..#...##....#..O#...O..
|
||||
O#.O.O#.O......#..O..O.OO##...O.....O...##...O.OO.O..##....#.O......O#.....O.OO.O..O.........#..#..O
|
||||
.##..#.....#....#...O.O#O#...##O....O..O.#O#.#OO.#..O#..O..#O###...........#.##O.###O...O.#....O#..O
|
||||
.#.#.#O...OO....O.###........OOO...#.#.O.....O.....#..#....#...O....O.#O...O.O.#.#...#O#O#O.#O.O...O
|
||||
.#......O.O.#..O#..#......#.....O...#.O.....O.......#.......#..O...#.#.#.##.#.#...O...........###O.#
|
||||
#..O..#....##O##..#.#.OO..O#O........O#..##O....#OOO..O.#.#.#..##.OO.#..O.#...O..O.O......#..O......
|
||||
O#O.#...O...O....#....O..O#...O#..#O.....#..#....#.O.O##.#.O.O#O#......#.##..O.O#.O.....O...O#O..OO#
|
||||
.OO#.....O....O.##...#.......#O#..OO.OO#.#..O.#.O.O..O.#.O.O..OO.O...OOO...#O..........#..#.O.O#...O
|
||||
O..O.#......#.O.O....#..O.....O...#....O..##.#.###....#.#...#O....O........O...O...OO...##..O.OO#..#
|
||||
.O.O.####.#.O....O#..O.O#.##.OO..#.....O......OO..#.O.O...#..#....#..O..O..O#O......#O.OO...##O...O.
|
||||
.O.....O.........#...O..O..O.O#..##.#...O#.......O.##O.....#.#.#..O..O...#.OO#.#.O..#...O..O.O......
|
||||
......O.O...O......O#.O.#OO.....#..#..........O..OOO...O...#.#..O#....O.#.O..O.#O..O..#.#..#.O..#...
|
||||
##.#.#O...O.#O..O..#.OO..###.......O....OO......#...O...O.#...O..O.#...#...O.O#..##O#..#...O.#....OO
|
||||
.OO#..#.#.#O..O.O..O#....#.O......###.O.O.O.#.......##...O##OO#.....##..O#.#..#.#.O.#.#...O..O.#...#
|
||||
#...OO..O..OO......O..#..#...O....O.OOOO##.....#O.....#.#..#..##.......O..O.#...#.#..#.OO#...O.O..O.
|
||||
##...O.OOO#.....#..O#..OO......OO#O.#O.#....#.OOO..#..#OO.O.O..#.O......OO.............#.O#.OO..#OO.
|
||||
.O#.#.....O....O#...#...O....O#O#........#O#.O.#.O...O.O..#O...O......#..O.#............#...##O#...O
|
||||
#...O.......#.O.O..##.O.#....O..#.....O.O...#...O.O..O.....O.OO..O..##..O...O..O......O...OO.OO.O.O.
|
||||
O......#......#OO...OO#.#O#....#....#.O.OO.#...O.#.#..O..#O..#....O..O....#....#....##.....O.OO#.#O.
|
||||
...O.O..#..#.O.#.....##.O.O.#...O..O..#.....#..OO#...O..###..#.....#.#O.....O.....##.#....O..O...O##
|
||||
#..#O#O.OO.#...O#..##.#..O.O.#....O#.#OOO..#O...OO....O.O#O.O..O#..#..O#.#.#O.##.#O.#O..O...#...#OO.
|
||||
.....O.....OO.....O.O#..OO...O.......#O....O....OO.O#.......#.O.#.O.O#O.#.....#....O.O.#..#.....O.OO
|
||||
...OOOO....##.O.....OOO.O..OO...O#..O...#O....O..O#....OO...#.#....O#.O.#......#O.O....O.......O..O.
|
||||
...#.##.##O#O#....O....#.#...#........#...#.O..#.#O.....####.O#....#.O#......O...#....#.O..#..O.#.O.
|
||||
..O.......O..O.###.....#......##.#.##.OO..OO........OOO..#.O..O.....O...#O....##..O.OOOO......O#.O..
|
||||
.#..O.O.O..#.#.#..O##O.#.......O..#....O.O....#....#.#.#O..##.....O.#O.....##O.#..#..O..#..OO....#.#
|
||||
...O.....O#..O#O#...O....##..O.....O..#.O...#..O..#....O#O...OO..OO.#........O............#....O...O
|
||||
.##OOO###..O..OO..##O#....O....OO....#.O#..#O....#.##O......O.#O.#O..O......#......#.##O#OO......O#.
|
||||
.#O#.....O#.....#...##...O..#O..O.#.O..#..O........O#.....#..O..OO#O...OO......O..#...O#...#.OOOO...
|
||||
.........O.#.#O....#OO...##........#.#..#.#..........OO..O..O..OOO#.........O.....O#..#OO.....#.#..#
|
||||
#..O.O...#..O.O##OO#..O.#O.....O.O..O.O.O.#.O.#....#.......O#O#.OO..##.....OO...#.........O.O....O.O
|
||||
OO#.#.##...#....#........OO....O..OO..O#.####.....#OO..#.....#........OO.#..#O..#.O#O#O.O..OO#O.O.O#
|
||||
#....O.O#..#O...OO..O.OOO.#.O.##.##..O..#O#.....O.....#O.O#.#...#...O.O.........O..#...#....O...O.#.
|
||||
....#O..OO..O......#O#....O.O....#..#....#....#.....OOO##.O..#..####..##.#..##..O...O.....O#....OOO.
|
||||
O...O..O#OO.####O..#OO..#.#.O....O.#.O.##........#..OOO...O....O........O.O.O.O.OOO..#OOO.#.#OO..#..
|
||||
O#O#.#..#..O..#.....#.#......O..O...O.O...#..O..#.O.....#O.....#.......#.O.O.......O...#....O..OOO#O
|
||||
.#...O...#.O......O....O....O.##.OO...O......#..O#O......O..O.........O.O...#.....#...#.##......#O..
|
||||
##O#.O......#.O..O..O.OO..##OO##.#O..O.#OO...O#..O.O.O..#.OO...O#O##O......#.#.#....O..O.......O...#
|
||||
O.#O.OO##....OO.......O......#....#O##....#....O#O......O..#.#.....O.OO.....O.#..O.#OO.O..OO.#..#.#.
|
||||
O.#.#.....#.O#.........O....O.#.O.#..O....O....OO.O#.#...O.O#..OO#O...#..#..#....#.##..OO.....#.....
|
||||
.#O.#O...O..#.OO#..O....#....#.#####............OO.O..OO.#....OO......#O...O.....O.#O..#.....#...O.O
|
||||
#.#....OO.O.O...O....O......#...#....#...##..#.#.....O..O#.#O.#.OO.##.O.#..........OO.O#.......##O#.
|
||||
O.O..O..##...#..........O.#.#.....O.#...O#.O..O........#.O#O......OO.#....OO..O.....O.O......#.OO..O
|
||||
#...#O..OO...#O#.OO#.O..OO.O.O.O##.O#O##......O#..O.#O...##...OOO...#O...O...O..O.O.##.#.......##..O
|
||||
.#.O#O........###O.##.O#..#OO.O.....OO......O......O.O#.....#O#...#...#.O......O.#.....#.O.####.O...
|
||||
..#..OOO...O#.###OOO#.#.O#....##O..#O.##......O.##...O...#...O....O.....#.O.#....#.......O..##...O.#
|
||||
OOO.##.#..OOO.....O...#..##.O...#...#.O##.......#.OO#..#.#...O.....#.#...##.O.O.O....#.O....O#..O...
|
||||
#..#..OO.....#O.....O#..O.O......O.###O.#..#..OO.#.O.#...OO...#..O.#O#..#.#..O.O..O....OO#...O..#...
|
||||
.#.O..#...O.#.O.#.OO..O..#.O..OOO.O......O.#.#O.......OO...O#.......O.O.....#..#.......O...O.O..##O#
|
||||
.O#....#O.#.....#......O...O........O...O.O........OO.O#.O...#.#....O..#.#O...#.OO#..#OO#.....O...##
|
||||
........O..#..#.O###O..O..O.O...###.O...#..O..O.O#O...#..O#O#....O.#.....O..#..OO.O.O...O.......#OO.
|
||||
#.OO..O..O..#.O..#..O....O.#O#.OO.O#.#...#...........O..O..O#.O....#......#........O....O.O.O.#..O..
|
||||
.O........#......#O...#O#...##O##...O.....#.O...##O.#.#O....O#...#O....#OO..#.#.#...#..#O.#......O.O
|
||||
O#..O..#O...O..O.........O......#.OO.O#.O..O....O........#.O..#...OOO.#..O.##O....O..O#.#..#O#..O##O
|
||||
.#..#.....#....#..O.O..O..#..OO##O..####.............O.#OO....#.O.....#OO...OO..#O#.#.#..OO.........
|
||||
..#O..#...O.O....OO.O#.#O.##...#....#OOO...O.....#......#....O##OO....#....#....#O#.O.#.#..O...#..O.
|
||||
...OO#..#..O....O.OO.#O##..O.....#..#....##.O.#.O....O....O.OO#.#O.OO.OO.#O.........#..##....O..O...
|
||||
.O#.........O.....#.OO.OO.O.O..O.O...#.O...O.....O..OO..#OO....O.OO..#.#O.O.#..OO..O....O.O..O#O..OO
|
||||
##.#..O#....O...#...O....#.......#.#..#..O...#O##...O#...O...#..........O.#O....OO..........#.......
|
||||
.OO...O.#............O.#..#..O...#.#...#.O##OO#...OOO..O..#.OO..#.......#OO.............O.#..#O.#...
|
||||
...#.#O.#....#.##..........#...#OO.O..#.O.....O.O..#.#O.....#..#O............OO#O..#O.....O...OO..O#
|
||||
#O#.O.....O.......#.......OO#..O.......O#...O........O..#.#.........OO..#....#....O...O.....#..O.#..
|
||||
....O..O.##..#.....O....##..OOO....O.O....O.....OO#O.O#.....##O.##.O.O.#..OO.OO.##.O.#........OO....
|
||||
.O.O#...#OO.#..O.#..#.##.#.......O#O.O......O.O......OO..O....#.O........#.#....#.O#O.#..O#O......O.
|
||||
.OO..#.O.#.....O#O..#..#.#....O.O####.#.O.O#OO......O........#O.O#OO#O..O.O......O.O.O#...#.O..O...O
|
||||
....O..O...##...##.##.O...#......#.O..O#O...O#O..OO....OO.#..#O#.OOO.#..#..O....#OO....#...O.#O..OO.
|
||||
#..O#..#..#..O.O.O..#..O.O#.O.....OO....O...O.OO#OO....O.#O..O.O......O..OOO...O#OO..OO.O#....O.OO..
|
||||
O.O.....O...##..#...#.O.#.#..O..O................O.#..OO.#....#......O#O..O.#.O.#..#O...........O..#
|
||||
.....OO..O..OO...O.#..........O.#O.........OO#.............#..OO...##.#.#.OO.O.O.#.##.#.OO.OOO......
|
||||
...#...#OOO.OOO..OO..##O.O.......O#.#O....O...#.##.##.##.#.O..O.O#O....O.O...O.#.O...O........O..O..
|
||||
.O.....#.O#..#..##.OO......#........#...O.#O.#..O#O.O.OO...##......O..O.....#..O...O.O.OO.O.O.#O##.O
|
||||
O....O.O..#.#...#..O.#O...#O.O..OOO.....O.#..O.O.#..#...#..O.....#..#..##...........###.....#...OO.#
|
||||
..#.....O.OO...O#........O..#O.....O.....OO...#..#.OOO......O#.#.O.O.##O.#..........O.#..O..OOO.....
|
||||
#..O.#O#.#.......#..O..#..#...#.O..#.....O........O.#..#OOO...O......#..O...O..#....#..O.........#..
|
||||
..O.OO..#O....OOOO...O....O#O....##OO.O.O..O.O......O..O.OO....O.OOO.O......#..O...#O....O...#.OO#..
|
||||
O.#O....OO....##.O......O...O..O.#....O#OO.O..#....O....##O..O....O..#.O...#...OO.O..O.O#.....O.OO..
|
||||
#.#O....O..#.O#..O...O#...O.O..O..........OO.......O#......O.......##.#..#.###.#O.O.......OO..#.O#O.
|
||||
O..##...O#O...........OO..#.#O...#OO......O#OO.#OO.#..O#OO#.#O....OO.##..O.#O.#..#.O.#.#..#O.OO.O.OO
|
||||
O.####..O#..O#....#.O#.O.#......O..O..##...#........O.......OO##.O.#.....O..O#..O...#..OO.....#....O
|
||||
...####..O..O#.#..OOO.....OO..............O.#OO.O#..##OO...#....O..#.##........##.O....O.....#..#..O
|
||||
..O.O..#OO#..O...O...OO...O....#...O.OO#.....#OO.....#.O......O.#O.#.#..#..........###OO#.OO...O..O.
|
||||
.O#.....O...O......O.#..OO..OOO......#O#.O....O.....O..O##.O#....OO.O....O..#.....O.O.O..O....OO.O..
|
||||
....OO.....##O....O##..#..OO....O.#O.OO...#....###.O....O.##..#..OOO#O#.......O...O.O..#O.......O..#
|
||||
...O...O..O.......O.#O.O........#.OOOO..............O#...O.O#O.....#......O#.#.........##.#.##O.#...
|
||||
.O.....O.O.O.#.O#OO#.....#..O.O#.O#.....##.....O..............#.......O...#O.#O...#.O...#.#O.....#O.
|
||||
.........##...#.O.#..#...#OOOO.#.OOOO...#O....O...O#....OO..##.OO..O.#.....##.O.#.O#...OOO..#.O##.O.
|
||||
#O..#....#.O....OO..OO#...#..#..O......#...#O.O....#....O...O.#.......OO....O...#...#...#.#...O....O
|
||||
.OO.#O.OOO##OO..#OO#..O.O..O.#..#..#....O...OO.O..##..#.....OO.#...#.....#.#....O.O..#...O.#......#.
|
||||
OO..#..O#O.O..O.#..............##..OO#O#O.##..O#...O..O#...O....##..##O#............###OO........##.
|
||||
..O..#..#.O....O.#.........OO.#...O.....OO.#..O..#....O...#..#...##..OOO....#..O#....#.......O.#O.O#
|
||||
O.O.OO..O.#.O.O.#.##.##.O..O.O...###..O..##..O#O#....O....O..O#O.........##..O#.OO.O....#O.OOO...#.#
|
||||
..#....O..O.....OO..#..O.OO..#OO.OOO...OO..##.O..O......O#.O.#..#O.O#..#.....O...O....#..###.O....#.
|
||||
#.......O.O.O.#....#..#O.O...OOO.......O...........#.O..O..O.O..#..#.O...O.O..O....#.O.O#....OO.O..#
|
190
day14/src/main.rs
Normal file
190
day14/src/main.rs
Normal file
@@ -0,0 +1,190 @@
|
||||
use std::hash::Hasher;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::fs::read_to_string;
|
||||
use std::hash::Hash;
|
||||
use std::time::Instant;
|
||||
|
||||
// For task 1
|
||||
fn slide_rock_north(platform: &mut Vec<Vec<u8>>, col: usize, row: usize) -> i32 {
|
||||
let mut steps = 0;
|
||||
let mut current_row = row;
|
||||
while current_row > 0 {
|
||||
let new_row = current_row - 1;
|
||||
if platform[new_row][col] != b'.' {
|
||||
break;
|
||||
}
|
||||
platform[new_row][col] = b'O';
|
||||
platform[current_row][col] = b'.';
|
||||
steps += 1;
|
||||
current_row = new_row
|
||||
}
|
||||
steps
|
||||
}
|
||||
|
||||
// Slides all rocks on platform north, returns change of load
|
||||
fn slide_platform_north(platform: &mut Vec<Vec<u8>>) -> i32 {
|
||||
let rows = platform.len();
|
||||
let cols = platform[0].len();
|
||||
let mut load_change = 0;
|
||||
for row in 1..rows {
|
||||
for col in 0..cols {
|
||||
if platform[row][col] != b'O' {
|
||||
continue;
|
||||
}
|
||||
let mut sliding_row = row;
|
||||
while sliding_row > 0 {
|
||||
let new_row = sliding_row - 1;
|
||||
if platform[new_row][col] != b'.' {
|
||||
break;
|
||||
}
|
||||
load_change += 1;
|
||||
platform[new_row][col] = b'O';
|
||||
platform[sliding_row][col] = b'.';
|
||||
sliding_row = new_row
|
||||
}
|
||||
}
|
||||
}
|
||||
load_change
|
||||
}
|
||||
|
||||
// Slides all rocks on platform south, returns change of load
|
||||
fn slide_platform_south(platform: &mut Vec<Vec<u8>>) -> i32 {
|
||||
let rows = platform.len();
|
||||
let cols = platform[0].len();
|
||||
let mut load_change = 0;
|
||||
for row in (0..rows - 1).rev() {
|
||||
for col in 0..cols {
|
||||
if platform[row][col] != b'O' {
|
||||
continue;
|
||||
}
|
||||
let mut sliding_row = row;
|
||||
while sliding_row < rows - 1 {
|
||||
let new_row = sliding_row + 1;
|
||||
if platform[new_row][col] != b'.' {
|
||||
break;
|
||||
}
|
||||
load_change -= 1;
|
||||
platform[new_row][col] = b'O';
|
||||
platform[sliding_row][col] = b'.';
|
||||
sliding_row = new_row
|
||||
}
|
||||
}
|
||||
}
|
||||
load_change
|
||||
}
|
||||
|
||||
// Slides all rocks on platform west, there's no change in load
|
||||
fn slide_platform_west(platform: &mut Vec<Vec<u8>>) {
|
||||
let rows = platform.len();
|
||||
let cols = platform[0].len();
|
||||
for row in 0..rows {
|
||||
for col in 1..cols {
|
||||
if platform[row][col] != b'O' {
|
||||
continue;
|
||||
}
|
||||
let mut sliding_col = col;
|
||||
while sliding_col > 0 {
|
||||
let new_col = sliding_col - 1;
|
||||
if platform[row][new_col] != b'.' {
|
||||
break;
|
||||
}
|
||||
platform[row][new_col] = b'O';
|
||||
platform[row][sliding_col] = b'.';
|
||||
sliding_col = new_col
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Slides all rocks on platform east, there's no change in load
|
||||
fn slide_platform_east(platform: &mut Vec<Vec<u8>>) {
|
||||
let rows = platform.len();
|
||||
let cols = platform[0].len();
|
||||
for row in 0..rows {
|
||||
for col in (0..cols - 1).rev() {
|
||||
if platform[row][col] != b'O' {
|
||||
continue;
|
||||
}
|
||||
let mut sliding_col = col;
|
||||
while sliding_col < cols - 1 {
|
||||
let new_col = sliding_col + 1;
|
||||
if platform[row][new_col] != b'.' {
|
||||
break;
|
||||
}
|
||||
platform[row][new_col] = b'O';
|
||||
platform[row][sliding_col] = b'.';
|
||||
sliding_col = new_col
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_platform(platform: &Vec<Vec<u8>>) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
platform.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut platform: Vec<Vec<u8>> = vec![];
|
||||
let mut sum1 = 0;
|
||||
let mut num_rocks = 0;
|
||||
// Solve task 1 while loading the data
|
||||
for line in input_str.lines() {
|
||||
platform.push(Vec::from(line.as_bytes()));
|
||||
sum1 += num_rocks;
|
||||
let last_row = platform.len() - 1;
|
||||
for (i, c) in line.bytes().enumerate() {
|
||||
if c == b'O' {
|
||||
num_rocks += 1;
|
||||
sum1 += 1 + slide_rock_north(&mut platform, i, last_row);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Task 2
|
||||
let mut load = sum1;
|
||||
// Complete the first cycle
|
||||
slide_platform_west(&mut platform);
|
||||
load += slide_platform_south(&mut platform);
|
||||
slide_platform_east(&mut platform);
|
||||
let mut history_hashes: Vec::<u64> = vec![hash_platform(&platform)];
|
||||
let mut history_loads: Vec::<i32> = vec![load];
|
||||
let mut completed_cycles = 1;
|
||||
let mut len_repeat_cycle = 0;
|
||||
while completed_cycles < 1000000000 {
|
||||
load += slide_platform_north(&mut platform);
|
||||
slide_platform_west(&mut platform);
|
||||
load += slide_platform_south(&mut platform);
|
||||
slide_platform_east(&mut platform);
|
||||
// Check if this value happened before
|
||||
let mut history_pos = completed_cycles - 1;
|
||||
let new_hash = hash_platform(&platform);
|
||||
loop {
|
||||
if history_hashes[history_pos] == new_hash {
|
||||
len_repeat_cycle = completed_cycles - history_pos;
|
||||
}
|
||||
if history_pos == 0 {
|
||||
break;
|
||||
}
|
||||
history_pos -= 1;
|
||||
}
|
||||
completed_cycles += 1;
|
||||
history_hashes.push(new_hash);
|
||||
history_loads.push(load);
|
||||
if len_repeat_cycle != 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const FINAL_CYCLE: usize = 1000000000;
|
||||
let offset_final = (FINAL_CYCLE - completed_cycles) % len_repeat_cycle;
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Load after first tilt: {}", sum1);
|
||||
println!("Completed cycles: {}, repeat: {}", completed_cycles, len_repeat_cycle);
|
||||
println!("Load after {} cycles: {}", FINAL_CYCLE, history_loads[completed_cycles - len_repeat_cycle - 1 + offset_final]);
|
||||
}
|
7
day15/Cargo.lock
generated
Normal file
7
day15/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
8
day15/Cargo.toml
Normal file
8
day15/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
1
day15/input.txt
Normal file
1
day15/input.txt
Normal file
File diff suppressed because one or more lines are too long
65
day15/src/main.rs
Normal file
65
day15/src/main.rs
Normal file
@@ -0,0 +1,65 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
fn get_hash(data: &[u8]) -> u8 {
|
||||
let mut state: u16 = 0;
|
||||
for &c in data {
|
||||
state += c as u16;
|
||||
state *= 17;
|
||||
state &= 255;
|
||||
}
|
||||
state as u8
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let input_line = input_str.lines().next().unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
// Task 1
|
||||
let mut sum1: u32 = 0;
|
||||
// Task 2
|
||||
let mut sum2: u32 = 0;
|
||||
// Rust is annoying
|
||||
const NEW_VEC: Vec<(&[u8], u8)> = vec![];
|
||||
let mut boxes: [Vec<(&[u8], u8)>; 256] = [NEW_VEC; 256];
|
||||
// Processing the input
|
||||
for str in input_line.split(',') {
|
||||
let bytes = str.as_bytes();
|
||||
// Task 1
|
||||
sum1 += get_hash(bytes) as u32;
|
||||
// Task 2
|
||||
if *bytes.last().unwrap() == b'-' {
|
||||
// Remove
|
||||
let label = &bytes[..bytes.len()-1];
|
||||
let hash = get_hash(label);
|
||||
let target_box = &mut boxes[hash as usize];
|
||||
if let Some(index) = target_box.iter().position(|(str, _)| *str == label ) {
|
||||
target_box.remove(index);
|
||||
}
|
||||
} else {
|
||||
// Insert / modify
|
||||
let focal = bytes.last().unwrap() - b'0';
|
||||
let label = &bytes[..bytes.len()-2];
|
||||
let hash = get_hash(label);
|
||||
let target_box = &mut boxes[hash as usize];
|
||||
if let Some(index) = target_box.iter().position(|(str, _)| *str == label ) {
|
||||
target_box[index] = (label, focal);
|
||||
} else {
|
||||
target_box.push((label, focal));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i, current_box) in boxes.iter().enumerate() {
|
||||
let box_value = i + 1;
|
||||
for (i, (_, focal)) in current_box.iter().enumerate() {
|
||||
sum2 += (box_value * (i + 1) * *focal as usize) as u32;
|
||||
}
|
||||
}
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
7
day16/Cargo.lock
generated
Normal file
7
day16/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day16"
|
||||
version = "0.1.0"
|
8
day16/Cargo.toml
Normal file
8
day16/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day16"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
110
day16/input.txt
Normal file
110
day16/input.txt
Normal file
@@ -0,0 +1,110 @@
|
||||
\...|....||/............\.......-.......................\............./..........--......................./...
|
||||
.......-..........................................-..-......../....../........................\...............
|
||||
............/....\................-................-....................|..................\..../.............
|
||||
.............|.\.................\.................|..................|..-........-...................-\......
|
||||
..|...................|.....|......................./|...../......-................/.-..|.........\...........
|
||||
.|......-..........\....../....\............\........../..\....|......................................-.......
|
||||
....\....|/......../............\..............................-....../\|..-..\../.........\..\|..............
|
||||
.........-..........-.........../...................-...........|....|\.......................................
|
||||
.....|........................-......./...\../......\./.|................\......|.-...-........|.|/\..........
|
||||
././............|............|...........\.....\..../...|....|...-.....|..............|................-......
|
||||
................/../....\..........\......-....................-../............../........../-....\...........
|
||||
......|........-................/........-......./........|......-\.............../........../.....|..........
|
||||
-\.\......|...........//...\-.../..\..-..\.............................../............../.\-.-.......\........
|
||||
.\..-...|./......./..............................\.................-....\../.................\..../...........
|
||||
-....../......|....-...||...|.................../...-........-................|.......-/......\\...|..........
|
||||
...../.........\..............\.................\..|....../....\....../.-\.....................|..\...........
|
||||
\|..................\................-........./.......|...........\...../.................../................
|
||||
..................../......\..........\..-...............\........-......................................|-...
|
||||
................-................../.................................................-..................\-....
|
||||
..\...................|....../........................./....-..........|.....................-................
|
||||
..............-...................................\...............|./...-../.-|........||.....................
|
||||
...........................././...|..........\............|...-....-..../.\\.......\...-.........\......../...
|
||||
....\........................\..........-............\/...........|..-..\.....................................
|
||||
..../.........../-\..\.........................|.........-........................|...........................
|
||||
...|./..\...............................\....................../..............................................
|
||||
..-.................\....|......-...-.........\-|..........\.-......|.....\.\....|......................|.....
|
||||
......-.........\.....|..............-......................\.\...|\.....-..-..../............................
|
||||
.....-..././......\|............................\.-.....................-.....................................
|
||||
/-....................................-....................../.................................../.........\\.
|
||||
.........|./...................................-..........|..\...\........../\.....\.....|...\.....|../..|....
|
||||
............|.....................-.....................--.|-............................\|......../.|.....-..
|
||||
-......\.........................\........|.\......../....||..||....................-........|.-.-............
|
||||
................././/|............../..\.........-|.....-...|....|.......................-.......|............
|
||||
|......|....../..............-............/........................-........\....\....|...../..............-..
|
||||
.............//..../.......-........\.............|...../............................/........\......|........
|
||||
...................-......-..........\..............\..............................\...................\......
|
||||
...............\./......|.-...................-.|.........\.............../................/..................
|
||||
.\..........-........|....................-..................||...........|...................................
|
||||
....................\......../.........|............-...........-.........\..............-.-......../...\.....
|
||||
........-.........|............\/.................-./.............-.......\...................-...............
|
||||
....................-...............-./.................|............./.......\.............\........./\......
|
||||
......\...............|........-/..................\.............../|.......\.|..............--..|.....|......
|
||||
......\...\.....././.........\||.............................|....\.\.............../....-..|/........-.......
|
||||
....../...../.................\...........|./.......|...\./....-...\........../.\......./..........-........\.
|
||||
..................\..../....|................................................................|.....|....-.....
|
||||
|..............................\......-................/|./-......./...........\........-.................|...
|
||||
.\..|\....-..............-..|...........\........|....|..|........./.................................../......
|
||||
...../...|..||.....\.--..........-....../............\..\.....|./..\....................\|......./............
|
||||
.......\...|......-.......|..../......\..\/.|./.\..........|....|..............-.......................|...../
|
||||
..............-...........\..\../...................\.........|.|....../..-/..............-...................
|
||||
.......-.......\..../................................................|...../....|................|...-........
|
||||
......................./........................|..\...|...-..-.........../....../.......-....|........../....
|
||||
.......|..................................-.....\-./.\.........................\..../....-...|................
|
||||
........../.../........./...........-.......|......./.-.........................\...\-.....................-..
|
||||
..........\.\.............|........\..|........./.................../...........\.................\.../.......
|
||||
....................-...|......|................../--.-.............-......................./.................
|
||||
......./.........|......./../.....................-....//..|..............-..|.............\............\.....
|
||||
...|...........-........................../.-..\............................\...|................\.//.......\.
|
||||
../.....\..\.......-.............../.....|../.......................\-.................../.......-|/..........
|
||||
......\.....................|.....\.............-.....\........../..........\.....-............|....\...-.....
|
||||
...../.....................-|...\..-......./.............../.|..../................\..-...........\........./.
|
||||
......|..\...........................\.........../.-............|....................-....|-.......-....\.....
|
||||
........................................./.......|......-../../.............../....................|..........
|
||||
........\.....|....../.......\.........../....../....-.........-.............||\...................-...|......
|
||||
...........|.................\..\.............|...............\.....|..............................|..........
|
||||
............|....../\....\..../.................\.-./......../\|../|..........................................
|
||||
........................................................-|....................\....|.............|..-.........
|
||||
/.|.............\\......\......./\.....................|.../.....................-...-.........../.-.....\....
|
||||
.........................\/....-...\......./......-...........................--..|........\-..../............
|
||||
.............-|...\........./..\........../..../..-.......\\.............................../.......|..../|....
|
||||
....-...../......|.................|........-.......|.....|.../........-.....\.../..\.................../.....
|
||||
.............../................|...........\............/-..|......../............-./.-./...............-....
|
||||
.....\............|..\...............\..............\\.....-......./|....|.....--../...-..............\.......
|
||||
................|............../................/......./............-..-.................-....||......./....\
|
||||
.\..............\................|.......|.............|.........\|........\....-..../.............\..\/......
|
||||
./.....\.......|......|.\..|.../.............-......\...............................-......\......\...........
|
||||
.....|...../........../.......|.......................-.-.....\..................\............/....--./..-....
|
||||
....................|..............-.\\......\..........\.....\.-.../.-.......-.......-.............\......-..
|
||||
........./...................|.../....\...|...............|./../...-.........\-.................-.............
|
||||
....................../.....\....-.\.............|............-......\.........\......\.......................
|
||||
................\..\...|....-./..............-...\\.........\..........|......-.|/./.|..........\.\......../..
|
||||
......\........-.............-/.............../...............................-.............|..........|/.....
|
||||
....|.......-|...................................../.........\................./..........................\...
|
||||
....\.......\\........-....\........\....\.............\............\........./........................\......
|
||||
../.............................................................-......\..............|...................../.
|
||||
............/../.........................\................................................../...-.............
|
||||
.\........................\/.-...................-.......-...............|.....................-..............
|
||||
./........................|.|/................\..............././..................................|.-........
|
||||
............/........-..-..........|..............-........\../.|...\............................../..........
|
||||
............\/......-.........\\............-.....................\..........\....................|..../..../.
|
||||
..........\.../.....\.....................-..\..\.|..|....../-..|......-...|............-.....................
|
||||
......................-........\.........-......................|..........-..................................
|
||||
.|................\......-...........|.../....../............................................/......../...|../
|
||||
.........-..........\...-...-................\............/..-....|\..............-.......\.|..-.../-.........
|
||||
..|....../......./../-.............../....-......|-................................./......-...-...........-..
|
||||
.............../............../....-....\......../.\../...................-............../\............|.\.|..
|
||||
..|....\................-.....|.......................|\......................\.\..-...-..-...........|.......
|
||||
.......................|......................\.../......|.................-..../..-..-.\....\................
|
||||
..........................................-..........|-......................./-............-.................
|
||||
..../...../....\.|........................................././.../...........................\................
|
||||
......./...................................-............|-./.-.........\.|.../.-//...................-........
|
||||
/......................|............|/.............../-..............-...............|.......|......|...|.....
|
||||
....|.....-....-.....................\../..-...................\........./.../................./......-.......
|
||||
........................\..............................-.\.-...|..................../............./.....-..../
|
||||
......-.-...-........-.......\........../......|.........|..................../.....\./.....--...............|
|
||||
.........-/...............-\...\..........\................|........./.../........\.|......|..................
|
||||
..|/.................../......................................................../.....\..|.....|......-....-..
|
||||
......................./......................\.........-./......................-............................
|
||||
.....-.|.\................-............................|.............-........................../....-........
|
||||
..../..|..|.\....|....\.................\.........|...-..-................/......|............/..\..........|.
|
195
day16/src/main.rs
Normal file
195
day16/src/main.rs
Normal file
@@ -0,0 +1,195 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Direction {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
}
|
||||
|
||||
const DIRECTION_MASK: [u8; 4] = [1, 2, 4, 8];
|
||||
|
||||
fn pass_light(layout: &Vec<&[u8]>, energized: &mut Vec<Vec<u8>>, mut x: usize, mut y: usize, mut dir: Direction) {
|
||||
loop {
|
||||
let energized_field = &mut energized[y][x];
|
||||
let mask = DIRECTION_MASK[dir as usize];
|
||||
if *energized_field & mask != 0 {
|
||||
return;
|
||||
}
|
||||
*energized_field |= mask;
|
||||
match dir {
|
||||
Direction::Left => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if y < layout.len() - 1 {
|
||||
y += 1;
|
||||
dir = Direction::Down;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if y > 0 {
|
||||
y -= 1;
|
||||
dir = Direction::Up;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'|' => {
|
||||
if y > 0 {
|
||||
pass_light(layout, energized, x, y - 1, Direction::Up);
|
||||
}
|
||||
if y < layout.len() - 1 {
|
||||
pass_light(layout, energized, x, y + 1, Direction::Down);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if x > 0 {
|
||||
x -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Right => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if y > 0 {
|
||||
y -= 1;
|
||||
dir = Direction::Up;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if y < layout.len() - 1 {
|
||||
y += 1;
|
||||
dir = Direction::Down;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'|' => {
|
||||
if y > 0 {
|
||||
pass_light(layout, energized, x, y - 1, Direction::Up);
|
||||
}
|
||||
if y < layout.len() - 1 {
|
||||
pass_light(layout, energized, x, y + 1, Direction::Down);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if x < layout[0].len() - 1 {
|
||||
x += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Up => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if x < layout[0].len() - 1 {
|
||||
x += 1;
|
||||
dir = Direction::Right;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if x > 0 {
|
||||
x -= 1;
|
||||
dir = Direction::Left;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'-' => {
|
||||
if x > 0 {
|
||||
pass_light(layout, energized, x - 1, y, Direction::Left);
|
||||
}
|
||||
if x < layout[0].len() - 1 {
|
||||
pass_light(layout, energized, x + 1, y, Direction::Right);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if y > 0 {
|
||||
y -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Direction::Down => {
|
||||
match layout[y][x] {
|
||||
b'/' => {
|
||||
if x > 0 {
|
||||
x -= 1;
|
||||
dir = Direction::Left;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'\\' => {
|
||||
if x < layout[0].len() - 1 {
|
||||
x += 1;
|
||||
dir = Direction::Right;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
b'-' => {
|
||||
if x > 0 {
|
||||
pass_light(layout, energized, x - 1, y, Direction::Left);
|
||||
}
|
||||
if x < layout[0].len() - 1 {
|
||||
pass_light(layout, energized, x + 1, y, Direction::Right);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if y < layout.len() - 1 {
|
||||
y += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let layout = input_str.lines().map(|str| str.as_bytes()).collect::<Vec<_>>();
|
||||
let mut energized: Vec<Vec<u8>> = vec![vec![0; layout[0].len()]; layout.len()];
|
||||
pass_light(&layout, &mut energized, 0, 0, Direction::Right);
|
||||
let count1 = energized.iter().fold(
|
||||
0, |acc, elem| acc + elem.iter().fold(
|
||||
0, |acc, &elem| acc + (elem > 0) as i32));
|
||||
let count2 =
|
||||
(0..layout.len()).map(|y| (0, y, Direction::Right))
|
||||
.chain((0..layout.len()).map(|y| (layout[0].len() - 1, y, Direction::Left)))
|
||||
.chain((0..layout[0].len()).map(|x| (x, 0, Direction::Down)))
|
||||
.chain((0..layout[0].len()).map(|x| (x, layout.len() - 1, Direction::Up)))
|
||||
.map(|(x, y, dir)| {
|
||||
energized.iter_mut().for_each(|vec| vec.iter_mut().for_each(|x| { *x = 0; }));
|
||||
pass_light(&layout, &mut energized, x, y, dir);
|
||||
energized.iter().fold(
|
||||
0, |acc, elem| acc + elem.iter().fold(
|
||||
0, |acc, &elem| acc + (elem > 0) as i32))
|
||||
}).max().unwrap();
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Energized1: {}", count1);
|
||||
println!("Energized2: {}", count2);
|
||||
}
|
7
day17/Cargo.lock
generated
Normal file
7
day17/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day17"
|
||||
version = "0.1.0"
|
17
day17/Cargo.toml
Normal file
17
day17/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "day17"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "main"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
[[bin]]
|
||||
name = "main"
|
||||
path= "src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "visualization"
|
||||
path= "src/main_visualization.rs"
|
141
day17/input.txt
Normal file
141
day17/input.txt
Normal file
@@ -0,0 +1,141 @@
|
||||
111111111212112131132322111222113111121134441444244134242144345414133353141211531241422341212232243224414141424312113113121311311222222122112
|
||||
221111111121112113112211111323141331221422241141213411314413253423542114114554431435441123231242121411314332414223323213311232232221212111211
|
||||
122122212212112212332113313234211334444312322431311314124222114353422535433132444511311544412131234133114231421144413322322123223113211211211
|
||||
211211112213233233222132223113314222121232144444221414142155253533152135533551212512145253352234424132222232343121322311232322332222111222211
|
||||
111112213111232122213132334131112244411313321453131151252321321242424323353535113152334324341155514212314424244121414423222211223321322112112
|
||||
121222231132133111231334222314212422214223113125432212324222423252331232445424252222332413413554144223211113421214313133332331232212123322121
|
||||
222121331233312113123321441242142243414224432432324432211335325333432345435112344255525522114514451353313341123333122441423222131313222232221
|
||||
222223332311211321112224141324333432131215352334224433453152113332445212433455132524245345542445553414522311444441323131141211211333111212111
|
||||
211232233321132123232124421311432311134212541131135334243341324433432524445252255431425433414442532255214441323444331133412322332112133312321
|
||||
222232132211313333134123131134144121241355515453123521213213455544412235311341223244215535311111154451441542431442423321232243321211312133322
|
||||
111221322122111133434413224444242321554333214111423545535442241454224454342364335433354153325343552534325532121323131344221323221123121213231
|
||||
123132233321232324443133231412322543411141221515222112534334466234224432342526665352355541413232211332525411453331241112144423122111113212123
|
||||
213312122113123114224121414224422421113331541414131422424445435523532345546335545366544323453414452214443314153533212241312114343213332131333
|
||||
312131133112112144423132323421155314533544545511443234332325235664433246435546432626444555645541224433251155343133333222424324134112323331331
|
||||
322321213212143231234212433144511345124152213124424266663543443643344436535543333636425243542335231552221514554133534313313244343221231111231
|
||||
312313311333114234113144444244555234224154223422254446432343253324362263262356262534352553425326642133321244423451413133432411411222311333311
|
||||
222323213314143434113141312253533135412225215262245345446422663425335263423266455333465222422635532223255541122515311223431121213332322111111
|
||||
231231111134224241312324313543223435443113623344263235462565656362446222265343623535654423563436346465314322134122454233324424143131222132132
|
||||
221231112341123121222334214134223511331516442545242236523445664445533345455664455324236344666345556256534545353242151232143211441432133121113
|
||||
122122322131422434211233312132434553212454545324655622252522334633526634334443663456535266222564622236234313353353132342114334344441212133111
|
||||
331322134234413423224422535413341524532445434332555662465363652462225553633323334665642226423652325655363512132135411323322333232431122213222
|
||||
212311224233233233131135515154245441653244226465354635432436546577634555465664535636632545223656356363264423252433323214235424134431421213122
|
||||
311313412213143212454355521322522355546343635254536244362565634474636476634577566456652655232634635325523623213155113323332314444213321222233
|
||||
133324214332421312331515232443251644532223426336553653647763645766376756336445636646356564564252224242525436664524314414345443414312424442331
|
||||
213323411311423221132215344555125444422222664536242633774763667464374537464335375364467554643632423356344232622433113124121242111313443312121
|
||||
213332133411211221115435453124343624326222332236437773437434747367473374663557665763546435633355634542436342324615513111345543312331134243213
|
||||
233334232321414111422551555121442665534433642555764764357344457675365746343446677547665346766745253623346353565454335133341315132213424341211
|
||||
311332132343411353241333214422535463523544666566336774667356734463454777767577735436556475634767452534532424533625542155251513454434131333423
|
||||
324423131343432152125351451245434246526253355635567565465364546567477476776753544767334344653637777635534523566246315451231113433424131123411
|
||||
332313133424214335134142413256554534533645663643574673653374553434644374636764355646445665555773674753364224465254645233332352143431433244334
|
||||
233444444244214512345531122645263553435665563567463734345446764566355675666636564763634446577677577763524342632255556412252232251332243342124
|
||||
334413121324344245244354552246422666334274366773637376343743467676644466478845885543333545355447556477565242425422662512551241554533442213413
|
||||
134111333232545514351215446255325354343473664437747477777448644747877875847476885558337763373453745637676443653326446253554434311142214441341
|
||||
443323222311142351213222635255656232356656665356756574775648546784447744857888748676775564776466775557675635324565633245442422214115122232324
|
||||
221322342335152535132253635442554264453675334557567665864675845877446446768566847858486746535457565667677666656652453525345311525325443213332
|
||||
324112132234124114512443463346234434645536355656743685548758576588446644565874667865658864764774746543357676665466552356244524315233231323143
|
||||
441132143315345532241322522433324674747754745454744785866748555754454664488658676548876744545336456465476563625253452442432345151435453141111
|
||||
134222341241541234326632335246344744535563674544677768455466468487644467678447656444856674765854544656563637745253666346323124543123442344121
|
||||
442342214524542235516322265653424645673467637547788744487488558567688665786747464448578766468864335677444464376663524624455442332443335231414
|
||||
213133343344342522526625324645553634343433755444488877656587476684767665665776848484468657656546646435344534753245435463342453234154542232211
|
||||
244243445525242425154532424226476466634474356457556756545468568875557776887657587485744468466446886464777634355545352454252222151214212343343
|
||||
133321414243431411355322235555377666747553375647586467584845458458978769685976766548777586786645748434357633476762663542466565335215243442322
|
||||
312133142534313553662323465625467456536544754487845786855754559595577696785969658864675787564846586735646356564766563644323364511353215113331
|
||||
213322234425331156342354532426456643353363687688574848667555655667868759959779796667785755554564848557463745757334564664453225421334151122324
|
||||
311141133124122426335532366544776464356376885585876448584959867757985568698777658999655688476457678444633355533346426564264222515254212534214
|
||||
143124124111422532546342633765737753336784744485784474476999977859875865997978997679888755777787578486434653765556765463542654642244123213133
|
||||
411421355313124464425634436366766653447865844445766664578775657555896886955856796688895797768564464878777454376647533253643526361452415441513
|
||||
233224542111542643666666527666653733434555665864558767857885786577595767578976775677699667768688774677865454353535673535644555452355215423542
|
||||
421333524312433266246232443443463573548888448554875598577665868799869756896966998795776565984754445466655756764667634642562542654115311545542
|
||||
441311131524442653334333476553673344767754744867656986577868657685959778565779658767769759686465647847668777346677773456522422652433223231243
|
||||
443425124111152325256535543474636333754888485545659967856877655978688897877698966955776966866545765547484753766345773653633226536354435232444
|
||||
423133515135126426454323436454344476788655775647957757796766957557987679977957958789769659686875746648565465654653636343442532352525433521544
|
||||
145331153233263536634625343575673568466857767686659568785568769569999669979667885658799565958575864546447554567547746774365336236325145431351
|
||||
343241332213336623253452457573577575577775774888769675578755856767778677688777888876757867998656656758746784763533433665645336333355212421435
|
||||
422233534444226666564557644734367458775556754796956786586689879896778699867676976965798959699789887878587784876355465363232366534421414421532
|
||||
341524341451222553442567557363557484767866558586596896587578888996679877868698766788859799858995664678486748846434664457364264346241251524221
|
||||
311435113234352566425664634653473577558467554556796656597866887989678689896886677796697667778888966654846586644553676575263366644532352353111
|
||||
255153115411422545535263333565657548568584465956986786969786898899976878986968766698775686565865678565487885485645363377546433666532331155353
|
||||
342554355315334355222366763736554545645484589876697687576789778869897666867697696979766588557869996784884777654466335347432234223325431511132
|
||||
433323215536236362246454645535557848464585669986668797987676688967997988679899666868699655697658867948554545688673663653446222562433521334213
|
||||
335214545323356252426274777467458886467658587658858695979766997879796678997896986868878985986877587554558745485437536457556352563323311131242
|
||||
333114345353436546626375473536564684655654566856758568696896887788966777898996699779999689785976667965555684686567754574333266523553433443331
|
||||
525311154446553254523665543475738545877578668788859767977968677996879888988789697796886967795685558865544866755654756656334445565322521211315
|
||||
531521335452226562654657747555574776756546668685599688678999978767888879979999979997876878876876588975776684688877576536442554534362511215252
|
||||
451141243326333455256775374657387888887784967555596896798966689978879799979998999778698686876568977577445554464874765556343353242555424541323
|
||||
335313444536354643644364636675568558786758867868575797779779989999887898797889877686769669779765857976687774688735575766775346245534544215133
|
||||
425553342435253346226456577375367675876488687975798567779899998889999799999979998878797668856888677898586767676847376347735554636362253224552
|
||||
144553545556552354552755676555657686756478578897997796788687668877878988977879799788768776666577659556465867476836456555766622556353533114214
|
||||
251154342262662362467663677436556757475566797875788886778966769997798977878777978677886867797768576759454464767736343576355235523433434451314
|
||||
222524225452622235625775375656447887864486679988687969969996797778989889878987977997998998685569698987484548568855367674447222656366653353312
|
||||
253324114536522225327654676334546457885847887797565666987966698978887897887989888776687877785558695568484646864644753733364336443663245224421
|
||||
123533143542444566663533336747387574875689788856959696786988699789887779787777798777668986697775998578647655678854356635547455622255525325342
|
||||
342513515236663342243553474767774547678446798897988998966776789879799877778777889869989696788967778775788658464866334434344345322663331112223
|
||||
431532531535362264266466663637665864544577769866998699679877687879798997879897778989967868997796659695855465548546637346574365326262653333541
|
||||
315223121124263333453677575667747857585886595559998698768779788787979897978889787798667996786567877598766545855453543445563635336325341435115
|
||||
524224415324634354355777675574457885657846876859886866669669679888978789987887798669667766865598585769844746748436573575455353544364422151351
|
||||
143144314356524632623674763753556774788565756965996669677897778877978899789788989669876679998766666766886474756766674375534342455463622441155
|
||||
513543311423333542643457563364554856455749995586885898998879699778979879778899977998879767876566888586767547674637356633663524266534422332341
|
||||
441245215215262565254377774553468478745565578975756586676999797697797778888887788776678796965765556655548665484533766677675554355522332512234
|
||||
233344141256444466643557445674688774765846976595698786687678977887878778999997697966967696657869879674784758657447765354463235362243423151442
|
||||
234315154554326255344547557475557445858785675569799957999988878788978898978967698876797996689667998785648664886743377765664222365465222252432
|
||||
151152243454425225435335463764474468765666565677986675977996988669676878897769897697697865767887955875887668484443675534336562226445133145131
|
||||
443243413113652525445263657743365686576566695656589855676768668776879897879867886697988978596858585864577745475545443336454256556363353342215
|
||||
124153542233226424323434767346738884577874875865666965867779977868978776989979776886988865567756698786886845448747737744746624526552553545212
|
||||
211211312134526355453275577364343857548875686987766955769678769997686976697787876987776567587756785688876558665663576565424365224251512545554
|
||||
255151334333355432632336767657643554678647555767658769686796787769876666897969968686899785689998599446544768745656554763323655362441353423254
|
||||
144511144543225526644554334434446568674648776966786799777999789798887798996676967676697585856568558457576648583555774573624553335225443211255
|
||||
412454143411434533462635635644474666885457655755887957989887769789789778787876867696965589895976788867887657657756763363456663344635445544412
|
||||
211145534512452424322524563467357654778477455455895699695585867776996988687887787999567766578959788568687484877356356474656333434311315231342
|
||||
322154131442133263256243676737374758845877576889656565599896886799976698998897696667687578558997658854887584633664477633445346453412135344131
|
||||
132135154424564322444436556436347457745685446786677978566578758576767767896778778797579857655778556448655578553576736654526235434641431111152
|
||||
223332534513125265524653655564763346676546746565889867578955787989899668999669998766697766558666484474556764543353756773633332552542521315441
|
||||
324255115414512346244536635677365754677878488765588776869799785666789898586697779887887887879865777754748784454366757435643244264452532542414
|
||||
122135532114535646525345644665357654447457685858847657566555769879957758675587659878957799785456576867656833475673464665322623545333335351431
|
||||
334225511144144624622524627373437633356658856747676998856787986989857796655568985967777856585868744455777334477535756242354323531134354132221
|
||||
433425151433342654662262345743756634737656664444745465776556957785556769965765766955976559974647447654688736546477433332366345222243142534523
|
||||
143435532553142563526244443367337345643784466656877774875695696875559886859867956678796776768854888454683564634377772454653265233125213342241
|
||||
112242421243151456464562552676674464467354577488754886889895757867875786898655978997766766854855486456836474565665356554645426654235114115411
|
||||
213414232311422536624243554447757447655475587784785677855868666985756959567858555769787844847866568577547753546753726345435323541545522353434
|
||||
322312423142452446322532433366737644737577678586758784674457556557956558765975769979754565556755864844546545757536324242632622452115442333421
|
||||
422112444121223534534526263257335463573347384444555888575845796688857967958776757754648675447784887453747764644764363245452524432511113131332
|
||||
342223414542213354464332235625373654466375744846456546786765677587759875799578465888747487458584466434675647545644653665324543255322423443132
|
||||
433324424531455155362332534425355666555633434846474748768677554674654755456444787745678465857657646556374456657355665244266454541133525342442
|
||||
214144134355225235145354363526234665477364777454676668488457558847747548468668646658656756857878853443453466735662432236232423351245325432414
|
||||
132213335435212541453363546265454374465653646546446757468576587864877764457644564647445778847685544375747564366555263623325234121534434233431
|
||||
234314111414153341334456635662452333565645443545464885865646577887888676768745554857445767568757443666766436335224634434622413542142423112414
|
||||
233334442234224321424663334265462563335634463653637857774685657884464876545677874566548746464547556775333464566252536652324222415134542114424
|
||||
343121234251224212433546336456464527347567433765536554677486465844467788655667747886756885863547746637475357556625354662234431533153433144241
|
||||
423111243212254124411126453366343355457437373764373376857676566744447884744874485644484483544635534453666762465444244446122112224545222431413
|
||||
444122132314115454324535256242632465667747353356666355376656476558465684458666884885546566474673674734765535442323353263555113122525322233231
|
||||
132222141331331351331323364232632466354763555654767377337446867547446488554548548846534563645466545773636256363654535641551212443122124321444
|
||||
132431211424143123532312235226235325552665647357537337653333457775684767478556585636373674663533375443434456535255455252513323542251113334311
|
||||
123141143132442544455144224534265545542467454744565735545734556464636366473555765573353664777637755334533324233535544252253341251242312322343
|
||||
242424133124145514525144143623244446233322746457637535463644547456576774536476764764366677366765375572434563252263221213233532413214444322123
|
||||
221212434411112423234213421442645453565465637436767566436574666654363356637474377775367465533453736535454464256664341542551214452432244333414
|
||||
322223143224133242523313554455655433342643264757774536473647353737545365465446537447666573353667635324643226254544453552141551242324213312213
|
||||
231222221333142143535252445252333362225545532444755776654657653355666535666736664764455445463344225334432554462421144414144245542231311432441
|
||||
233213331322343245211222532425362242425445252624656735465364343743554633653576745334565443577323554224632533653252342125122132122432224412421
|
||||
132311113231341341214252245135212645645222326632562475357353764375554764636354375755774665332356232234223453365415133112255144332333231334132
|
||||
232121132231231221511112114321544433323634665263224255336645536655537373476756543466553555434426664425344645324251445443443342343232132432131
|
||||
223211441112423423125145233125434122456233422223222234353475367676773456647774354647545245533633334532633264233515111233443532421334414412221
|
||||
211233234132133123333312513223255252242556253255334662665535344637767365546545533754332645636653332456236652345153255441142423211232242221123
|
||||
133213233243341333122214451245423541153255226526322463346326225644546744464332545353255353333545262436223453452252542553124443314442313223132
|
||||
232211133442411421424455223145443344343323322663465633563564346366663335336334233344434442225365622265234343253254321523541234213114222323132
|
||||
123322311214132141432422354335153531553324436525455522463446522633442324555536644352446345224553452656311243545541552244412414332411243123113
|
||||
133211222113312134421324222451533115155115656223434322322452524462466232363452354554234553353264232523312554114521224521432424141122121121233
|
||||
212311121234242433341332242152141553333244354563456222643236552462346656256334543456526544645454545542241512252234224323434431412423321313211
|
||||
222122112312442434413232313254441431141324312465365343422332336353546464245236443225222446345434452544524253112544414434332434133333232121213
|
||||
121232223333222214434322341334554344131214514444325554653334225522466653232344445252536523222412522544244132253421513132122212322131221122333
|
||||
113131122223322232141114243331521414415413533325135225524334364322554243344264355644334224641252234112231341254441341432441241422211231112331
|
||||
231123223113121444412313444423455315135451132535143131363333546335563423364442224634623415221554313215113253124322313122434111313313121221223
|
||||
112113113123112332212433333412111211411133422254351211534253623363326425452243643352445333153245212235422115313142313231211411431311312123222
|
||||
211213233222131232431413123142142225252115252341423313455125554215465526343655453211314142245541113511214122542423121243443331313132211333121
|
||||
122321331211331332113342142141132114324415231124313352252433232445422232331232155211321143532154212114324412242413332414241331133312223321232
|
||||
212223232212122321231221343434321232125535343413225131312324433232331244112442143143324221451555333434153144434214124413413232131323221131112
|
||||
212112333321332322113441221213413333314144231141524123524452415351421533524512545332455212414232252213454124311231311313212211121332311331112
|
||||
212111323123221332211321312241223411344113322342235323434535352431241233313555211253443123115512211323331323234421322121313231121211332211112
|
||||
222212111232113311213222424321133422212214325542112432543334532224412134424331552233242424324114254432311123223233332332223131132131223321111
|
||||
122111113213323333233233213443233121231131213241332245435455232435225535554542341415215111125413311222432124332321141313231123223213223112221
|
||||
211221122133231223233221112441411433213334221121214334445231523455224113133444221414114425513333222111423124443111423213313122113313122112121
|
||||
212222122213211112131132322314331233144333433324442315513412314345522434534255522423411231242242432133224141342114131323221212223211111111112
|
115
day17/src/main.rs
Normal file
115
day17/src/main.rs
Normal file
@@ -0,0 +1,115 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
fn find_path(layout: &[&[u8]], min_consecutive: u8, max_consecutive: u8) -> i32 {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
enum Direction {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
}
|
||||
const ALL_DIRECTIONS: [Direction; 4] = [Direction::Left, Direction::Right, Direction::Up, Direction::Down];
|
||||
const OPPOSITE_DIRECTION: [Direction; 4] = [Direction::Right, Direction::Left, Direction::Down, Direction::Up];
|
||||
const DIRECTION_OFFSET: [(i32, i32); 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)];
|
||||
struct Node {
|
||||
x: i32,
|
||||
y: i32,
|
||||
cost: i32,
|
||||
dir: Direction,
|
||||
consecutive: u8,
|
||||
}
|
||||
let width = layout[0].len();
|
||||
let height = layout.len();
|
||||
let index_multiplier = max_consecutive as usize * 4;
|
||||
// Evaluation function for visited nodes, -1 is unvisited
|
||||
// Node is treated as a different one unless direction and consecutive counter are the same
|
||||
let mut scores: Vec<i32> = vec![-1; width * height * index_multiplier];
|
||||
let mut queue: BTreeMap<i32, Node> = BTreeMap::new();
|
||||
let get_node_index = |node: &Node| -> usize {
|
||||
(node.y as usize * width + node.x as usize) * index_multiplier
|
||||
+ node.dir as usize * max_consecutive as usize + node.consecutive as usize - 1
|
||||
};
|
||||
let target_x = width as i32 - 1;
|
||||
let target_y = height as i32 - 1;
|
||||
let get_heuristic = |node: &Node| -> i32 {
|
||||
// Heuristic is manhattan distance with addition of correction due to forced turns
|
||||
// This correction seems to give minor but nonzero improvement of performance
|
||||
let dx = target_x - node.x;
|
||||
let dy = target_y - node.y;
|
||||
let x_correction = dx / max_consecutive as i32 * min_consecutive as i32;
|
||||
let y_correction = dy / max_consecutive as i32 * min_consecutive as i32;
|
||||
dx + x_correction + dy + y_correction
|
||||
};
|
||||
let mut current_node = Node { x: 0, y: 0, cost: 0, dir: Direction::Down, consecutive: 0 };
|
||||
'outer: loop {
|
||||
for dir in ALL_DIRECTIONS {
|
||||
// Can't turn 180
|
||||
if OPPOSITE_DIRECTION[current_node.dir as usize] == dir {
|
||||
continue;
|
||||
}
|
||||
// Can't go in one direction less than min_consecutive tiles, 0 is only for start
|
||||
if current_node.consecutive > 0 && current_node.consecutive < min_consecutive
|
||||
&& current_node.dir != dir {
|
||||
continue;
|
||||
}
|
||||
// Compute new node consecutive counter
|
||||
let mut new_node = Node {
|
||||
x: current_node.x,
|
||||
y: current_node.y,
|
||||
cost: current_node.cost,
|
||||
dir: dir,
|
||||
consecutive: if current_node.dir == dir { current_node.consecutive + 1 } else { 1 },
|
||||
};
|
||||
// Can't go in one direction more than max_consecutive tiles
|
||||
if new_node.consecutive > max_consecutive as u8 {
|
||||
continue;
|
||||
}
|
||||
// Calculating new node position and bounds checking
|
||||
let (offset_x, offset_y) = DIRECTION_OFFSET[dir as usize];
|
||||
new_node.x += offset_x;
|
||||
new_node.y += offset_y;
|
||||
if new_node.x < 0 || new_node.y < 0 || new_node.x as usize >= width || new_node.y as usize >= height {
|
||||
continue;
|
||||
}
|
||||
// If the node hasn't been visited yet
|
||||
let node_index = get_node_index(&new_node);
|
||||
if scores[node_index] < 0 {
|
||||
let new_tile_cost = (layout[new_node.y as usize][new_node.x as usize] - b'0') as i32;
|
||||
new_node.cost += new_tile_cost;
|
||||
let new_score = new_node.cost + get_heuristic(&new_node);
|
||||
scores[node_index] = new_score;
|
||||
if new_node.x == target_x && new_node.y == target_y && new_node.consecutive >= min_consecutive {
|
||||
current_node = new_node;
|
||||
break 'outer;
|
||||
}
|
||||
// Combines node score with node index to provide unique keys
|
||||
queue.insert((new_score as usize * scores.len() + node_index) as i32, new_node);
|
||||
}
|
||||
}
|
||||
match queue.pop_first() {
|
||||
Some((_, node)) => {
|
||||
current_node = node;
|
||||
}
|
||||
None => { return -1; }
|
||||
}
|
||||
}
|
||||
current_node.cost
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let layout = input_str.lines().map(|str| str.as_bytes()).collect::<Vec<_>>();
|
||||
let loss1 = find_path(&layout, 1, 3);
|
||||
let loss2 = find_path(&layout, 4, 10);
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Loss1: {}", loss1);
|
||||
println!("Loss2: {}", loss2);
|
||||
}
|
165
day17/src/main_visualization.rs
Normal file
165
day17/src/main_visualization.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
fn find_path(layout: &[&[u8]], min_consecutive: u8, max_consecutive: u8,
|
||||
out_path: &mut Vec<(i32, i32)>, out_history: &mut Vec<(i32, i32)>) -> i32 {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
enum Direction {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
}
|
||||
const ALL_DIRECTIONS: [Direction; 4] = [Direction::Left, Direction::Right, Direction::Up, Direction::Down];
|
||||
const OPPOSITE_DIRECTION: [Direction; 4] = [Direction::Right, Direction::Left, Direction::Down, Direction::Up];
|
||||
const DIRECTION_OFFSET: [(i32, i32); 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)];
|
||||
struct Node {
|
||||
x: i32,
|
||||
y: i32,
|
||||
cost: i32,
|
||||
dir: Direction,
|
||||
consecutive: u8,
|
||||
}
|
||||
let width = layout[0].len();
|
||||
let height = layout.len();
|
||||
let index_multiplier = max_consecutive as usize * 4;
|
||||
// Evaluation score for visited nodes, -1 is unvisited
|
||||
// Node is treated as a different one unless direction and consecutive counter are the same
|
||||
let mut scores: Vec<i32> = vec![-1; width * height * index_multiplier];
|
||||
let mut previous: Vec<i32> = vec![-1; width * height * index_multiplier];
|
||||
let mut queue: BTreeMap<i32, Node> = BTreeMap::new();
|
||||
let get_node_index = |node: &Node| -> usize {
|
||||
(node.y as usize * width + node.x as usize) * index_multiplier
|
||||
+ node.dir as usize * max_consecutive as usize + node.consecutive as usize - 1
|
||||
};
|
||||
let target_x = width as i32 - 1;
|
||||
let target_y = height as i32 - 1;
|
||||
let get_heuristic = |node: &Node| -> i32 {
|
||||
// Heuristic is manhattan distance with addition of correction due to forced turns
|
||||
// This correction seems to give minor but nonzero improvement of performance
|
||||
let dx = target_x - node.x;
|
||||
let dy = target_y - node.y;
|
||||
let x_correction = dx / max_consecutive as i32 * min_consecutive as i32;
|
||||
let y_correction = dy / max_consecutive as i32 * min_consecutive as i32;
|
||||
dx + x_correction + dy + y_correction
|
||||
};
|
||||
let mut current_node = Node { x: 0, y: 0, cost: 0, dir: Direction::Right, consecutive: 0 };
|
||||
let mut current_index: i32 = -1;
|
||||
'outer: loop {
|
||||
out_history.push((current_node.x, current_node.y));
|
||||
for dir in ALL_DIRECTIONS {
|
||||
// Can't turn 180
|
||||
if OPPOSITE_DIRECTION[current_node.dir as usize] == dir {
|
||||
continue;
|
||||
}
|
||||
// Can't go in one direction less than min_consecutive tiles, 0 is only for start
|
||||
if current_node.consecutive > 0 && current_node.consecutive < min_consecutive
|
||||
&& current_node.dir != dir {
|
||||
continue;
|
||||
}
|
||||
// Compute new node consecutive counter
|
||||
let mut new_node = Node {
|
||||
x: current_node.x,
|
||||
y: current_node.y,
|
||||
cost: current_node.cost,
|
||||
dir: dir,
|
||||
consecutive: if current_node.dir == dir { current_node.consecutive + 1 } else { 1 },
|
||||
};
|
||||
// Can't go in one direction more than max_consecutive tiles
|
||||
if new_node.consecutive > max_consecutive as u8 {
|
||||
continue;
|
||||
}
|
||||
// Calculating new node position and bounds checking
|
||||
let (offset_x, offset_y) = DIRECTION_OFFSET[dir as usize];
|
||||
new_node.x += offset_x;
|
||||
new_node.y += offset_y;
|
||||
if new_node.x < 0 || new_node.y < 0 || new_node.x as usize >= width || new_node.y as usize >= height {
|
||||
continue;
|
||||
}
|
||||
// If the node hasn't been visited yet
|
||||
let node_index = get_node_index(&new_node);
|
||||
if scores[node_index] < 0 {
|
||||
let new_tile_cost = (layout[new_node.y as usize][new_node.x as usize] - b'0') as i32;
|
||||
new_node.cost += new_tile_cost;
|
||||
let new_score = new_node.cost + get_heuristic(&new_node);
|
||||
scores[node_index] = new_score;
|
||||
previous[node_index] = current_index;
|
||||
if new_node.x == target_x && new_node.y == target_y && new_node.consecutive >= min_consecutive {
|
||||
current_node = new_node;
|
||||
break 'outer;
|
||||
}
|
||||
// Combines node score with node index to provide unique keys
|
||||
queue.insert((new_score as usize * scores.len() + node_index) as i32, new_node);
|
||||
}
|
||||
}
|
||||
match queue.pop_first() {
|
||||
Some((_, node)) => {
|
||||
current_node = node;
|
||||
current_index = get_node_index(¤t_node) as i32;
|
||||
}
|
||||
None => { return -1; }
|
||||
}
|
||||
}
|
||||
let mut temp_x = current_node.x;
|
||||
let mut temp_y = current_node.y;
|
||||
let mut temp_index = get_node_index(¤t_node) as i32;
|
||||
while temp_index >= 0 {
|
||||
out_path.push((temp_x, temp_y));
|
||||
temp_index = previous[temp_index as usize];
|
||||
temp_x = temp_index / index_multiplier as i32;
|
||||
temp_y = temp_x / width as i32;
|
||||
temp_x -= temp_y * width as i32;
|
||||
}
|
||||
current_node.cost
|
||||
}
|
||||
|
||||
fn visualize_path(layout: &[&[u8]], path: &Vec<(i32, i32)>) {
|
||||
let mut layout_copy = layout.iter().map(|&bytes| Vec::from(bytes)).collect::<Vec<_>>();
|
||||
for &(x, y) in path {
|
||||
layout_copy[y as usize][x as usize] = b'.';
|
||||
}
|
||||
for line in layout_copy.iter() {
|
||||
println!("{}", std::str::from_utf8(&line).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
fn visualize_history(layout: &[&[u8]], history: &Vec<(i32, i32)>) {
|
||||
let grayscale = " .:-=+*#%@%#*+=-:. ".as_bytes();
|
||||
let mut layout_history = layout.iter().map(|&bytes| Vec::from(bytes)).collect::<Vec<_>>();
|
||||
for (i, &(x, y)) in history.iter().enumerate() {
|
||||
layout_history[y as usize][x as usize] = grayscale[i * grayscale.len() / history.len()];
|
||||
}
|
||||
for line in layout_history.iter() {
|
||||
println!("{}", std::str::from_utf8(&line).unwrap());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let layout = input_str.lines().map(|str| str.as_bytes()).collect::<Vec<_>>();
|
||||
let mut path: Vec<(i32, i32)> = vec![];
|
||||
let mut history: Vec<(i32, i32)> = vec![];
|
||||
let mut path2: Vec<(i32, i32)> = vec![];
|
||||
let mut history2: Vec<(i32, i32)> = vec![];
|
||||
let loss1 = find_path(&layout, 0, 3, &mut path, &mut history);
|
||||
let loss2 = find_path(&layout, 4, 10, &mut path2, &mut history2);
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Part 1 path:");
|
||||
visualize_path(&layout, &path);
|
||||
println!("\nPart 1 search order:");
|
||||
visualize_history(&layout, &history);
|
||||
println!("\nPart 2 path:");
|
||||
visualize_path(&layout, &path2);
|
||||
println!("\nPart 2 search order:");
|
||||
visualize_history(&layout, &history2);
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Loss1: {}", loss1);
|
||||
println!("Loss2: {}", loss2);
|
||||
}
|
7
day18/Cargo.lock
generated
Normal file
7
day18/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day18"
|
||||
version = "0.1.0"
|
8
day18/Cargo.toml
Normal file
8
day18/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day18"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
712
day18/input.txt
Normal file
712
day18/input.txt
Normal file
@@ -0,0 +1,712 @@
|
||||
L 4 (#38ce32)
|
||||
U 3 (#55f513)
|
||||
L 6 (#46c2c2)
|
||||
U 3 (#2c5aa3)
|
||||
R 7 (#3137a2)
|
||||
U 4 (#3bc623)
|
||||
R 6 (#924a52)
|
||||
D 4 (#2880c3)
|
||||
R 7 (#924a50)
|
||||
U 6 (#639303)
|
||||
R 5 (#3137a0)
|
||||
U 3 (#6ada33)
|
||||
L 6 (#3f9e92)
|
||||
U 4 (#2f1fa3)
|
||||
R 6 (#471352)
|
||||
U 4 (#2fd2a3)
|
||||
L 5 (#09d272)
|
||||
U 4 (#213a13)
|
||||
L 6 (#78b222)
|
||||
U 3 (#2fc1a3)
|
||||
L 3 (#4cbb52)
|
||||
U 3 (#4ac623)
|
||||
R 4 (#70efe2)
|
||||
U 2 (#5eb1f3)
|
||||
R 5 (#70efe0)
|
||||
U 3 (#2bf113)
|
||||
L 6 (#1882e2)
|
||||
U 3 (#3fca23)
|
||||
R 4 (#62ba80)
|
||||
U 5 (#2c54c3)
|
||||
L 4 (#1dee90)
|
||||
U 6 (#73a233)
|
||||
R 5 (#2c7800)
|
||||
U 4 (#4ad3a3)
|
||||
L 7 (#4f8940)
|
||||
U 3 (#48d041)
|
||||
R 7 (#5221c0)
|
||||
U 4 (#75a591)
|
||||
R 2 (#03ec80)
|
||||
U 4 (#2c54c1)
|
||||
R 4 (#1bbc10)
|
||||
D 4 (#4f1b13)
|
||||
R 4 (#7f90f0)
|
||||
D 5 (#2752d3)
|
||||
R 4 (#1eae30)
|
||||
D 3 (#2a9653)
|
||||
L 6 (#36eb10)
|
||||
D 2 (#2a9651)
|
||||
L 2 (#454ad0)
|
||||
D 3 (#1557e3)
|
||||
R 3 (#7707d0)
|
||||
D 4 (#73c6b3)
|
||||
R 5 (#295690)
|
||||
D 6 (#24a233)
|
||||
R 3 (#7bc852)
|
||||
U 6 (#15b743)
|
||||
R 3 (#224732)
|
||||
U 4 (#4a0323)
|
||||
R 4 (#810412)
|
||||
U 7 (#5fba61)
|
||||
L 4 (#1c2ee2)
|
||||
U 4 (#6977f3)
|
||||
R 4 (#3ff1b0)
|
||||
U 6 (#8ee1f3)
|
||||
R 4 (#544e00)
|
||||
U 4 (#244c23)
|
||||
R 2 (#5bc1f0)
|
||||
U 4 (#1e5873)
|
||||
L 3 (#6420d2)
|
||||
U 4 (#836a83)
|
||||
R 6 (#6420d0)
|
||||
U 3 (#024693)
|
||||
L 6 (#0a2540)
|
||||
U 4 (#65eda3)
|
||||
L 2 (#2649e0)
|
||||
U 2 (#195ba3)
|
||||
L 4 (#74d120)
|
||||
U 3 (#795ca3)
|
||||
R 3 (#31c470)
|
||||
U 2 (#59afe3)
|
||||
R 6 (#873020)
|
||||
U 4 (#695263)
|
||||
L 9 (#1dc2b0)
|
||||
U 3 (#288a33)
|
||||
L 4 (#090860)
|
||||
D 8 (#00eb93)
|
||||
L 4 (#5de760)
|
||||
D 2 (#00eb91)
|
||||
L 3 (#5ae5c0)
|
||||
D 4 (#162813)
|
||||
L 3 (#182e50)
|
||||
D 5 (#5848f1)
|
||||
L 2 (#89c410)
|
||||
D 6 (#5848f3)
|
||||
L 4 (#549dc0)
|
||||
D 4 (#7e5a93)
|
||||
L 2 (#5ac572)
|
||||
U 4 (#39f613)
|
||||
L 4 (#300c42)
|
||||
U 3 (#2c94e1)
|
||||
R 6 (#68ae32)
|
||||
U 7 (#2c94e3)
|
||||
L 3 (#289422)
|
||||
U 5 (#06ded3)
|
||||
L 3 (#025d52)
|
||||
U 2 (#1c4373)
|
||||
L 5 (#21b252)
|
||||
U 4 (#8646d3)
|
||||
L 3 (#764a62)
|
||||
U 5 (#8646d1)
|
||||
L 6 (#6d5762)
|
||||
U 6 (#1c4371)
|
||||
R 3 (#3c7462)
|
||||
U 3 (#041483)
|
||||
R 4 (#01cab2)
|
||||
U 5 (#784883)
|
||||
R 3 (#60f6c2)
|
||||
U 6 (#057d73)
|
||||
R 2 (#1fb832)
|
||||
U 2 (#775953)
|
||||
R 4 (#3c9532)
|
||||
U 4 (#404733)
|
||||
R 7 (#2423b2)
|
||||
U 3 (#1eee81)
|
||||
R 7 (#797832)
|
||||
U 3 (#1eee83)
|
||||
R 4 (#220652)
|
||||
U 5 (#15f0b3)
|
||||
R 3 (#4c0d62)
|
||||
D 4 (#2083c3)
|
||||
R 4 (#1c5cf2)
|
||||
D 3 (#5f0f33)
|
||||
R 3 (#5494e2)
|
||||
D 5 (#684523)
|
||||
R 4 (#1202b2)
|
||||
U 9 (#455503)
|
||||
R 2 (#15d2a2)
|
||||
D 9 (#36e533)
|
||||
R 4 (#1c78a0)
|
||||
D 3 (#4bcc43)
|
||||
R 6 (#4baf50)
|
||||
D 3 (#66edf3)
|
||||
R 4 (#4baf52)
|
||||
D 4 (#222a23)
|
||||
L 9 (#1c78a2)
|
||||
D 2 (#043003)
|
||||
R 9 (#1d0a42)
|
||||
D 4 (#1e6941)
|
||||
R 5 (#3a6662)
|
||||
U 4 (#1df801)
|
||||
R 3 (#8b8d92)
|
||||
U 7 (#35c951)
|
||||
R 4 (#8b8d90)
|
||||
U 3 (#4d8771)
|
||||
R 3 (#1b5502)
|
||||
U 3 (#4a6233)
|
||||
R 5 (#71c6c2)
|
||||
D 4 (#408383)
|
||||
R 5 (#057732)
|
||||
U 4 (#076963)
|
||||
R 4 (#045692)
|
||||
U 6 (#4e80e1)
|
||||
R 3 (#5f77d2)
|
||||
U 3 (#114573)
|
||||
R 2 (#6c4b92)
|
||||
U 3 (#114571)
|
||||
L 8 (#07cc82)
|
||||
U 3 (#4e80e3)
|
||||
R 8 (#166fe2)
|
||||
U 4 (#924f11)
|
||||
R 3 (#496b52)
|
||||
U 2 (#912dc3)
|
||||
R 3 (#0e9052)
|
||||
D 3 (#2e8443)
|
||||
R 4 (#572312)
|
||||
D 4 (#31d0d3)
|
||||
L 5 (#745c00)
|
||||
D 5 (#058313)
|
||||
R 5 (#2847e0)
|
||||
D 3 (#5ba6c3)
|
||||
R 7 (#58b860)
|
||||
U 4 (#560193)
|
||||
R 4 (#5e3d90)
|
||||
U 7 (#36d363)
|
||||
R 6 (#02d030)
|
||||
D 7 (#49d633)
|
||||
R 4 (#4e03d2)
|
||||
U 4 (#8d4853)
|
||||
R 8 (#3b9d12)
|
||||
U 4 (#8d4851)
|
||||
R 5 (#302542)
|
||||
U 6 (#40e003)
|
||||
R 7 (#130d32)
|
||||
D 4 (#5323d1)
|
||||
R 6 (#4ed652)
|
||||
D 6 (#5323d3)
|
||||
R 4 (#541fd2)
|
||||
U 2 (#0f08e3)
|
||||
R 3 (#16bd42)
|
||||
U 5 (#603191)
|
||||
R 6 (#3545f2)
|
||||
U 3 (#011651)
|
||||
R 4 (#3ecb62)
|
||||
U 6 (#963781)
|
||||
R 5 (#2c7612)
|
||||
D 6 (#509971)
|
||||
R 6 (#885a52)
|
||||
D 6 (#3b0dd3)
|
||||
R 2 (#2afe62)
|
||||
D 4 (#1f4e53)
|
||||
R 3 (#2c0ab2)
|
||||
D 5 (#3be5a3)
|
||||
L 3 (#2c0ab0)
|
||||
D 4 (#55e5c3)
|
||||
L 7 (#2afe60)
|
||||
D 4 (#5bf153)
|
||||
L 5 (#617782)
|
||||
U 4 (#094123)
|
||||
L 4 (#5186f2)
|
||||
U 4 (#544353)
|
||||
L 3 (#40f5c2)
|
||||
D 3 (#325493)
|
||||
L 6 (#40b782)
|
||||
D 5 (#713cc3)
|
||||
L 4 (#3fdd60)
|
||||
D 8 (#0b87f3)
|
||||
L 5 (#41cfe0)
|
||||
D 3 (#340bf3)
|
||||
L 2 (#718d12)
|
||||
D 7 (#6a0d63)
|
||||
R 6 (#88f440)
|
||||
U 3 (#612011)
|
||||
R 2 (#4eb270)
|
||||
U 4 (#6f7821)
|
||||
R 5 (#077c50)
|
||||
U 6 (#209901)
|
||||
R 4 (#1eeaa0)
|
||||
D 3 (#1176f1)
|
||||
R 2 (#2b79f0)
|
||||
D 5 (#6cd941)
|
||||
R 5 (#72d3a0)
|
||||
D 3 (#25a453)
|
||||
R 3 (#09e140)
|
||||
D 3 (#7944e3)
|
||||
R 4 (#071320)
|
||||
U 9 (#540d61)
|
||||
R 2 (#63bb30)
|
||||
U 5 (#317753)
|
||||
R 3 (#5a9e00)
|
||||
D 5 (#056963)
|
||||
R 3 (#385080)
|
||||
D 3 (#75cda3)
|
||||
R 2 (#331280)
|
||||
D 7 (#23db43)
|
||||
R 2 (#11d3e2)
|
||||
D 3 (#2f8123)
|
||||
R 4 (#77eef2)
|
||||
D 3 (#2f8121)
|
||||
R 4 (#3c3e32)
|
||||
D 5 (#541c03)
|
||||
R 6 (#531fb0)
|
||||
D 3 (#43a463)
|
||||
R 3 (#2a8950)
|
||||
D 6 (#2a8193)
|
||||
R 3 (#078660)
|
||||
D 3 (#668ce3)
|
||||
R 3 (#640a50)
|
||||
D 3 (#64e5a3)
|
||||
R 5 (#961a02)
|
||||
D 6 (#492053)
|
||||
R 4 (#4d71d0)
|
||||
D 3 (#48f563)
|
||||
R 4 (#14d310)
|
||||
D 5 (#48f561)
|
||||
R 5 (#53be70)
|
||||
U 5 (#195313)
|
||||
R 3 (#0b2550)
|
||||
U 2 (#5fde13)
|
||||
R 2 (#7dbeb0)
|
||||
U 4 (#5fde11)
|
||||
R 6 (#145d90)
|
||||
U 4 (#34b771)
|
||||
R 6 (#834300)
|
||||
U 3 (#34b773)
|
||||
L 6 (#0387d0)
|
||||
U 4 (#469471)
|
||||
R 6 (#9406f0)
|
||||
U 6 (#469473)
|
||||
R 3 (#2a4d50)
|
||||
D 5 (#037633)
|
||||
R 7 (#14d340)
|
||||
D 6 (#11daf1)
|
||||
R 7 (#337f90)
|
||||
D 4 (#526051)
|
||||
R 4 (#757a30)
|
||||
D 8 (#643b43)
|
||||
R 3 (#1185a0)
|
||||
D 6 (#07f453)
|
||||
R 3 (#621c50)
|
||||
D 2 (#07f451)
|
||||
R 3 (#30dcf0)
|
||||
D 4 (#0a7101)
|
||||
L 4 (#08b2b0)
|
||||
D 3 (#0c9b51)
|
||||
L 2 (#1c5e10)
|
||||
D 7 (#6bf7c1)
|
||||
L 4 (#5702a0)
|
||||
D 2 (#6bf7c3)
|
||||
L 8 (#2d1240)
|
||||
D 5 (#5cf4e1)
|
||||
L 6 (#14c4d2)
|
||||
D 4 (#98b1f1)
|
||||
L 3 (#4b01e2)
|
||||
D 8 (#2711a1)
|
||||
L 2 (#4dca52)
|
||||
U 8 (#41b261)
|
||||
L 3 (#114f32)
|
||||
U 5 (#842761)
|
||||
L 6 (#3f4122)
|
||||
U 4 (#842763)
|
||||
L 3 (#4d3102)
|
||||
D 3 (#41b263)
|
||||
L 2 (#1118e2)
|
||||
D 5 (#59cc03)
|
||||
L 8 (#8b9742)
|
||||
D 2 (#65f793)
|
||||
R 8 (#328982)
|
||||
D 4 (#85c501)
|
||||
L 3 (#441702)
|
||||
D 5 (#0a1f51)
|
||||
L 8 (#2ccc92)
|
||||
D 3 (#52f541)
|
||||
L 6 (#5dfc42)
|
||||
D 5 (#52f543)
|
||||
L 4 (#1d83f2)
|
||||
D 6 (#5eeab1)
|
||||
R 4 (#4634e0)
|
||||
D 4 (#968ca1)
|
||||
L 3 (#437e40)
|
||||
D 7 (#968ca3)
|
||||
L 3 (#62b0a0)
|
||||
D 5 (#38aa71)
|
||||
L 5 (#3c8e22)
|
||||
U 5 (#7bb931)
|
||||
L 6 (#172202)
|
||||
U 3 (#809981)
|
||||
L 5 (#172200)
|
||||
D 4 (#0b1ac1)
|
||||
L 2 (#3c8e20)
|
||||
D 4 (#1d0d71)
|
||||
L 6 (#82ea50)
|
||||
D 2 (#373bd1)
|
||||
L 2 (#1ec200)
|
||||
D 7 (#471d01)
|
||||
R 6 (#3b6472)
|
||||
D 4 (#0273b3)
|
||||
R 3 (#2b4df2)
|
||||
D 2 (#0273b1)
|
||||
R 7 (#3af9f2)
|
||||
D 4 (#432781)
|
||||
R 6 (#161170)
|
||||
D 3 (#682741)
|
||||
L 6 (#5aee90)
|
||||
D 4 (#574c13)
|
||||
L 4 (#4c3770)
|
||||
D 2 (#5eadb3)
|
||||
R 4 (#3b4a30)
|
||||
D 5 (#5eadb1)
|
||||
L 3 (#4700c0)
|
||||
D 5 (#574c11)
|
||||
L 5 (#4569e0)
|
||||
D 5 (#250471)
|
||||
L 5 (#014740)
|
||||
D 4 (#61e5f1)
|
||||
L 3 (#772650)
|
||||
D 3 (#1e6f21)
|
||||
R 3 (#1d3220)
|
||||
D 6 (#430041)
|
||||
R 2 (#608810)
|
||||
D 6 (#341ae3)
|
||||
R 4 (#5bd730)
|
||||
U 6 (#3132d3)
|
||||
R 2 (#3fab42)
|
||||
U 6 (#90b273)
|
||||
R 4 (#3fab40)
|
||||
D 7 (#263173)
|
||||
R 4 (#5bd732)
|
||||
D 5 (#423813)
|
||||
R 5 (#6ba250)
|
||||
D 2 (#773ab1)
|
||||
R 5 (#37ed60)
|
||||
D 4 (#048871)
|
||||
L 10 (#4de780)
|
||||
D 3 (#185e81)
|
||||
R 3 (#40d660)
|
||||
D 6 (#5dd3d3)
|
||||
L 7 (#4d2210)
|
||||
U 3 (#364dd3)
|
||||
L 4 (#2208a0)
|
||||
U 7 (#13db53)
|
||||
L 4 (#1ff800)
|
||||
D 3 (#74fa63)
|
||||
L 8 (#5405c0)
|
||||
D 6 (#7a2ee3)
|
||||
L 2 (#4ac3c0)
|
||||
D 3 (#30c2e3)
|
||||
L 2 (#15a070)
|
||||
D 6 (#0cac13)
|
||||
L 5 (#495b10)
|
||||
U 8 (#8c3253)
|
||||
L 3 (#495b12)
|
||||
U 2 (#2b5c03)
|
||||
L 5 (#1bbdb0)
|
||||
U 8 (#203f53)
|
||||
L 3 (#57a1e2)
|
||||
U 3 (#5032f3)
|
||||
L 4 (#57a1e0)
|
||||
U 6 (#327c63)
|
||||
R 4 (#50a820)
|
||||
U 4 (#2b3343)
|
||||
L 3 (#7014d0)
|
||||
U 4 (#12bef3)
|
||||
L 3 (#656f40)
|
||||
U 4 (#2dc663)
|
||||
L 6 (#113020)
|
||||
U 4 (#3a26d3)
|
||||
L 5 (#133f60)
|
||||
U 8 (#024a51)
|
||||
L 2 (#584c70)
|
||||
U 3 (#024a53)
|
||||
L 4 (#364750)
|
||||
U 4 (#3a26d1)
|
||||
L 3 (#023e50)
|
||||
U 6 (#07ffd3)
|
||||
R 6 (#6a4610)
|
||||
U 3 (#0a1a53)
|
||||
R 4 (#1d5f72)
|
||||
U 4 (#3dc7a3)
|
||||
L 10 (#43bdc0)
|
||||
U 3 (#2c8853)
|
||||
L 8 (#43bdc2)
|
||||
U 6 (#646bb3)
|
||||
R 6 (#1d5f70)
|
||||
U 7 (#2d4373)
|
||||
R 3 (#8264e0)
|
||||
U 5 (#35f151)
|
||||
R 4 (#2b1760)
|
||||
U 4 (#999c03)
|
||||
R 3 (#4175f0)
|
||||
D 8 (#999c01)
|
||||
R 5 (#3c0e70)
|
||||
D 2 (#32a5e1)
|
||||
R 3 (#1b64a0)
|
||||
D 6 (#261bc1)
|
||||
R 3 (#0b6c22)
|
||||
U 2 (#2d3081)
|
||||
R 4 (#72b8a2)
|
||||
U 4 (#236cb1)
|
||||
R 6 (#45dba2)
|
||||
U 4 (#209921)
|
||||
L 6 (#128470)
|
||||
U 6 (#4d6b01)
|
||||
L 2 (#190550)
|
||||
U 3 (#40f381)
|
||||
L 7 (#804a40)
|
||||
U 4 (#1accd1)
|
||||
L 4 (#5d9a40)
|
||||
U 2 (#042311)
|
||||
L 6 (#1fa392)
|
||||
U 3 (#3b7471)
|
||||
L 3 (#565ac2)
|
||||
U 5 (#3b7473)
|
||||
L 7 (#4c7822)
|
||||
U 7 (#47ab31)
|
||||
L 3 (#184fa2)
|
||||
U 7 (#417391)
|
||||
L 4 (#4cffd2)
|
||||
U 3 (#3bf361)
|
||||
L 3 (#84fdd0)
|
||||
D 7 (#178953)
|
||||
L 2 (#5ddab0)
|
||||
D 3 (#178951)
|
||||
L 5 (#44ed60)
|
||||
D 5 (#6eb101)
|
||||
L 3 (#455aa0)
|
||||
U 4 (#231db1)
|
||||
L 8 (#2511b0)
|
||||
U 4 (#886b31)
|
||||
R 4 (#2511b2)
|
||||
U 3 (#36b861)
|
||||
R 4 (#421320)
|
||||
U 4 (#267471)
|
||||
L 3 (#43b980)
|
||||
U 3 (#214141)
|
||||
R 3 (#2491c0)
|
||||
U 2 (#214143)
|
||||
R 7 (#4ae330)
|
||||
U 3 (#4c5d41)
|
||||
R 8 (#1897d0)
|
||||
D 5 (#39eba1)
|
||||
R 5 (#6c3442)
|
||||
D 7 (#439aa1)
|
||||
R 4 (#652a42)
|
||||
U 7 (#5437e1)
|
||||
R 3 (#3c7ae2)
|
||||
U 6 (#3653c1)
|
||||
L 5 (#6b4d52)
|
||||
U 4 (#5cb7f1)
|
||||
L 3 (#073a02)
|
||||
U 5 (#360581)
|
||||
L 3 (#6d9fd2)
|
||||
U 7 (#7901a1)
|
||||
L 2 (#123b32)
|
||||
U 3 (#4b1f83)
|
||||
L 4 (#2d6582)
|
||||
U 10 (#342933)
|
||||
R 4 (#538792)
|
||||
U 5 (#263fd3)
|
||||
L 5 (#0a3c42)
|
||||
D 2 (#433c41)
|
||||
L 3 (#4c3042)
|
||||
D 5 (#35f621)
|
||||
L 6 (#42f670)
|
||||
D 6 (#466371)
|
||||
R 6 (#42f672)
|
||||
D 7 (#6248a1)
|
||||
L 2 (#670152)
|
||||
D 5 (#90e203)
|
||||
L 5 (#4495b2)
|
||||
U 4 (#90fc73)
|
||||
L 2 (#5707b2)
|
||||
U 8 (#4c76e1)
|
||||
L 4 (#540512)
|
||||
U 3 (#492111)
|
||||
R 4 (#540510)
|
||||
U 6 (#0ff091)
|
||||
L 4 (#2b4272)
|
||||
U 5 (#05b161)
|
||||
L 3 (#7483e2)
|
||||
D 6 (#6b3f11)
|
||||
L 3 (#480342)
|
||||
D 6 (#307111)
|
||||
L 5 (#0f29d2)
|
||||
D 6 (#019f91)
|
||||
L 6 (#342822)
|
||||
D 4 (#180cb1)
|
||||
R 8 (#00f720)
|
||||
D 4 (#31b091)
|
||||
L 8 (#2f1380)
|
||||
D 3 (#4ab461)
|
||||
L 6 (#2194c0)
|
||||
U 5 (#6bee03)
|
||||
L 5 (#65f3b0)
|
||||
U 8 (#1076f3)
|
||||
L 3 (#1c34c0)
|
||||
U 3 (#1151c1)
|
||||
R 6 (#0bed40)
|
||||
U 3 (#3db921)
|
||||
L 4 (#4e4190)
|
||||
U 2 (#674151)
|
||||
L 2 (#2f95c0)
|
||||
U 8 (#097d01)
|
||||
L 3 (#4f5a20)
|
||||
D 2 (#69a8c1)
|
||||
L 2 (#04b560)
|
||||
D 3 (#2ca343)
|
||||
L 4 (#70ccd0)
|
||||
D 5 (#6c7323)
|
||||
R 4 (#377f50)
|
||||
D 4 (#3ae061)
|
||||
L 2 (#5883f0)
|
||||
D 6 (#5e3601)
|
||||
L 2 (#27eb00)
|
||||
D 7 (#6fffc3)
|
||||
L 4 (#06e992)
|
||||
D 4 (#43dee3)
|
||||
L 4 (#06e990)
|
||||
D 4 (#759353)
|
||||
L 6 (#7da150)
|
||||
D 5 (#5f0761)
|
||||
R 5 (#0ec360)
|
||||
D 3 (#4b82f1)
|
||||
R 3 (#400b40)
|
||||
D 3 (#72f301)
|
||||
R 4 (#288900)
|
||||
D 3 (#4b0f11)
|
||||
R 8 (#288902)
|
||||
D 4 (#471d21)
|
||||
L 8 (#708912)
|
||||
D 4 (#2264e1)
|
||||
R 4 (#708910)
|
||||
D 6 (#3c2e31)
|
||||
R 2 (#23e370)
|
||||
D 2 (#6e40f1)
|
||||
R 4 (#2ccbc0)
|
||||
U 9 (#51a4c1)
|
||||
R 4 (#1e2560)
|
||||
D 9 (#1dafa1)
|
||||
R 3 (#44ac70)
|
||||
D 5 (#028461)
|
||||
R 9 (#3d9be0)
|
||||
D 4 (#929d31)
|
||||
L 6 (#5e7b02)
|
||||
D 6 (#559df1)
|
||||
L 8 (#5e7b00)
|
||||
D 4 (#48ec01)
|
||||
L 5 (#93cfe2)
|
||||
D 8 (#1cafe1)
|
||||
L 4 (#0459f2)
|
||||
U 8 (#724081)
|
||||
L 4 (#47c962)
|
||||
D 4 (#5e74e1)
|
||||
L 3 (#495f80)
|
||||
D 5 (#7299e1)
|
||||
L 5 (#495f82)
|
||||
D 5 (#045f61)
|
||||
R 7 (#47c960)
|
||||
D 3 (#2335f1)
|
||||
R 6 (#499fd2)
|
||||
D 6 (#43b841)
|
||||
R 6 (#031222)
|
||||
D 6 (#48f681)
|
||||
L 5 (#727da2)
|
||||
D 4 (#41d7e1)
|
||||
R 5 (#113942)
|
||||
D 5 (#03ee33)
|
||||
R 4 (#0350c2)
|
||||
D 2 (#4727a3)
|
||||
R 4 (#148620)
|
||||
D 4 (#33d453)
|
||||
R 8 (#148622)
|
||||
D 3 (#210703)
|
||||
L 3 (#1c3d42)
|
||||
D 3 (#19c743)
|
||||
L 7 (#3991b2)
|
||||
D 4 (#4fb431)
|
||||
L 3 (#0563c2)
|
||||
D 4 (#6a0431)
|
||||
L 5 (#592952)
|
||||
D 6 (#0898b1)
|
||||
L 4 (#1f2f32)
|
||||
D 6 (#42ac11)
|
||||
L 3 (#045bb2)
|
||||
D 5 (#62d0c1)
|
||||
L 6 (#84e602)
|
||||
D 2 (#68e891)
|
||||
L 6 (#2c8512)
|
||||
D 5 (#16e5c1)
|
||||
L 5 (#2dc202)
|
||||
U 3 (#08e561)
|
||||
L 2 (#1d84c0)
|
||||
U 8 (#64b671)
|
||||
L 4 (#1d84c2)
|
||||
U 3 (#2d4741)
|
||||
L 4 (#5342c2)
|
||||
D 3 (#012ce1)
|
||||
L 6 (#229ca2)
|
||||
D 3 (#5d0f51)
|
||||
L 2 (#6f27a2)
|
||||
D 5 (#3102b1)
|
||||
L 2 (#39f292)
|
||||
D 3 (#0e1d31)
|
||||
L 4 (#1fe602)
|
||||
U 6 (#1fbbb1)
|
||||
L 6 (#001c52)
|
||||
U 3 (#880b71)
|
||||
L 4 (#001c50)
|
||||
U 7 (#12db41)
|
||||
L 2 (#2d7072)
|
||||
U 3 (#941843)
|
||||
R 8 (#255d72)
|
||||
U 3 (#0ac063)
|
||||
L 5 (#481670)
|
||||
U 4 (#7f2aa3)
|
||||
L 5 (#481672)
|
||||
U 3 (#379e93)
|
||||
L 4 (#255d70)
|
||||
U 5 (#025ca3)
|
||||
R 3 (#958792)
|
||||
U 2 (#258701)
|
||||
R 5 (#32e690)
|
||||
D 4 (#6c9431)
|
||||
R 2 (#32e692)
|
||||
U 4 (#850cf1)
|
||||
R 4 (#1f6942)
|
||||
U 4 (#8dc581)
|
||||
L 8 (#5949e2)
|
||||
U 3 (#62cf01)
|
||||
R 3 (#930cf2)
|
||||
U 2 (#014781)
|
||||
R 5 (#39d8b2)
|
||||
U 4 (#9a50e1)
|
||||
R 2 (#4e2032)
|
||||
D 4 (#1129e1)
|
||||
R 4 (#68c522)
|
||||
U 5 (#030c91)
|
||||
R 6 (#46e632)
|
||||
U 3 (#54c0c1)
|
||||
R 3 (#1104c2)
|
||||
U 6 (#3b3a11)
|
||||
L 7 (#72ea42)
|
||||
U 7 (#5eaf41)
|
||||
L 3 (#140192)
|
||||
D 4 (#05dbd1)
|
||||
L 2 (#507802)
|
||||
D 2 (#05dbd3)
|
||||
L 7 (#732442)
|
||||
U 6 (#144931)
|
||||
L 4 (#2e2f92)
|
||||
U 7 (#29bd33)
|
||||
L 4 (#1b1ca2)
|
||||
U 4 (#89f183)
|
181
day18/src/main.rs
Normal file
181
day18/src/main.rs
Normal file
@@ -0,0 +1,181 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::btree_map::Entry;
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
enum Direction {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
}
|
||||
|
||||
const DIRECTION_OFFSET: [(i32, i32); 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)];
|
||||
|
||||
fn get_area(horizontal_edges: &BTreeMap<i32, Vec<(i32, i32)>>) -> u64 {
|
||||
struct Segment {
|
||||
x0: i32,
|
||||
x1: i32,
|
||||
// coverage refers to coverage in current row if the segment shrinks in this row,
|
||||
// if the segment shrinks in this row, coverage remains its previous bigger version
|
||||
coverage: i32,
|
||||
to_delete: bool, // whether it needs to be deleted after this row
|
||||
}
|
||||
// Segments present in currently processed row
|
||||
let mut current_segments: Vec<Segment> = vec![];
|
||||
// Current vertical position, start doesn't matter but must be very low
|
||||
let mut current_y = i32::MIN;
|
||||
// Result
|
||||
let mut area: u64 = 0;
|
||||
// Going through the edge map
|
||||
for (&y, edges) in horizontal_edges.iter() {
|
||||
// Catch up from the previous vertical position
|
||||
for segment in current_segments.iter() {
|
||||
area += (segment.coverage as i64 * (y - current_y - 1) as i64) as u64;
|
||||
}
|
||||
current_y = y;
|
||||
// Going through all the edges
|
||||
for &edge in edges {
|
||||
let mut found_intersection = false;
|
||||
// Segment to insert for splitting
|
||||
let mut segment_to_insert: Option<Segment> = None;
|
||||
// Checking if the processed edge intersects with some segment and acting accordingly
|
||||
for segment in current_segments.iter_mut() {
|
||||
if segment.x1 == edge.0 {
|
||||
segment.x1 = edge.1;
|
||||
segment.coverage += edge.1 - edge.0;
|
||||
found_intersection = true;
|
||||
} else if segment.x0 == edge.1 {
|
||||
segment.x0 = edge.0;
|
||||
segment.coverage += edge.1 - edge.0;
|
||||
found_intersection = true;
|
||||
} else if segment.x0 == edge.0 && segment.x1 == edge.1 {
|
||||
// Here the edge is exactly the same like one segment, so it's going to end
|
||||
segment.to_delete = true;
|
||||
found_intersection = true;
|
||||
} else if segment.x0 == edge.0 {
|
||||
segment.x0 = edge.1;
|
||||
found_intersection = true;
|
||||
} else if segment.x1 == edge.1 {
|
||||
segment.x1 = edge.0;
|
||||
found_intersection = true;
|
||||
} else if segment.x0 < edge.0 && segment.x1 > edge.1 {
|
||||
// Here the edge is fully inside one of current segments, need to split
|
||||
segment_to_insert = Some(Segment {
|
||||
x0: edge.1,
|
||||
x1: segment.x1,
|
||||
coverage: 0, // Don't care how coverage is split, it will be recalculated
|
||||
to_delete: false,
|
||||
});
|
||||
segment.x1 = edge.0;
|
||||
found_intersection = true;
|
||||
}
|
||||
if found_intersection {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found_intersection {
|
||||
// No intersection, add new segment
|
||||
current_segments.push(Segment {
|
||||
x0: edge.0,
|
||||
x1: edge.1,
|
||||
coverage: edge.1 - edge.0 + 1,
|
||||
to_delete: false,
|
||||
});
|
||||
} else if let Some(segment) = segment_to_insert {
|
||||
// Do the splitting
|
||||
current_segments.push(segment);
|
||||
}
|
||||
}
|
||||
// Sort by lower bound and then merge segments which have overlapping bounds
|
||||
current_segments.sort_by(|a, b| a.x0.cmp(&b.x0));
|
||||
let mut i = 1;
|
||||
while i < current_segments.len() {
|
||||
if current_segments[i - 1].x1 == current_segments[i].x0 {
|
||||
current_segments[i - 1].x1 = current_segments[i].x1;
|
||||
current_segments[i - 1].coverage += current_segments[i].coverage - 1;
|
||||
current_segments.remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
// Add up current row coverage and update coverages for catching up
|
||||
for segment in current_segments.iter_mut() {
|
||||
area += segment.coverage as u64;
|
||||
segment.coverage = segment.x1 - segment.x0 + 1;
|
||||
}
|
||||
// Remove segments which were removed this iteration
|
||||
current_segments.retain(|segment| !segment.to_delete);
|
||||
}
|
||||
area
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
// edge maps, keys - y (vertical) position, values: list of horizontal edges (x1, x2)
|
||||
let mut horizontal_edges1: BTreeMap<i32, Vec<(i32, i32)>> = BTreeMap::new();
|
||||
let mut horizontal_edges2: BTreeMap<i32, Vec<(i32, i32)>> = BTreeMap::new();
|
||||
// Current position for parsing
|
||||
let mut current_pos1 = (0, 0);
|
||||
let mut current_pos2 = (0, 0);
|
||||
// Takes current_pos, direction and distance of the next step
|
||||
// Inserts horizontal edges into the map, ignores vertical, modifies current_pos
|
||||
let process_edge = |horizontal_edges: &mut BTreeMap<i32, Vec<(i32, i32)>>,
|
||||
current_pos: &mut (i32, i32), dir: Direction, dist: i32| {
|
||||
let mut offset = DIRECTION_OFFSET[dir as usize];
|
||||
offset.0 *= dist;
|
||||
offset.1 *= dist;
|
||||
let new_pos = (current_pos.0 + offset.0, current_pos.1 + offset.1);
|
||||
if dir == Direction::Left || dir == Direction::Right {
|
||||
let vec;
|
||||
match horizontal_edges.entry(new_pos.1) {
|
||||
Entry::Vacant(vacant_entry) => {
|
||||
vec = vacant_entry.insert(vec![]);
|
||||
}
|
||||
Entry::Occupied(occupied_entry) => {
|
||||
vec = occupied_entry.into_mut();
|
||||
}
|
||||
}
|
||||
if dir == Direction::Left {
|
||||
vec.push((new_pos.0, current_pos.0));
|
||||
} else {
|
||||
vec.push((current_pos.0, new_pos.0));
|
||||
}
|
||||
}
|
||||
*current_pos = new_pos;
|
||||
};
|
||||
// Populate both edge maps
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let dir1 = match split_whitespace.next().unwrap().as_bytes()[0] {
|
||||
b'L' => Direction::Left,
|
||||
b'R' => Direction::Right,
|
||||
b'U' => Direction::Up,
|
||||
_ => Direction::Down
|
||||
};
|
||||
let dist1 = split_whitespace.next().unwrap().parse::<u8>().unwrap();
|
||||
let code = &split_whitespace.next().unwrap()[2..8];
|
||||
let dir2 = match code.as_bytes()[5] {
|
||||
b'0' => Direction::Right,
|
||||
b'1' => Direction::Down,
|
||||
b'2' => Direction::Left,
|
||||
_ => Direction::Up
|
||||
};
|
||||
let dist2 = i32::from_str_radix(&code[0..5], 16).unwrap();
|
||||
process_edge(&mut horizontal_edges1, &mut current_pos1, dir1, dist1 as i32);
|
||||
process_edge(&mut horizontal_edges2, &mut current_pos2, dir2, dist2);
|
||||
}
|
||||
// Compute areas based on the edge maps
|
||||
let area1 = get_area(&horizontal_edges1);
|
||||
let area2 = get_area(&horizontal_edges2);
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Area1: {}", area1);
|
||||
println!("Area2: {}", area2);
|
||||
}
|
54
day19/Cargo.lock
generated
Normal file
54
day19/Cargo.lock
generated
Normal file
@@ -0,0 +1,54 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day19"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
9
day19/Cargo.toml
Normal file
9
day19/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "day19"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
regex = "1.10.2"
|
797
day19/input.txt
Normal file
797
day19/input.txt
Normal file
@@ -0,0 +1,797 @@
|
||||
brk{s<3727:A,m>3500:A,s<3845:A,A}
|
||||
lt{a<982:A,s<274:vg,R}
|
||||
cms{s>621:A,x<502:dz,m<3295:R,nzd}
|
||||
mfd{a<2692:A,R}
|
||||
xcv{x>3826:R,a<1965:A,A}
|
||||
gtr{m<2488:R,s>1479:R,x<766:R,R}
|
||||
cm{m<2381:ff,m<3360:A,a<210:R,dd}
|
||||
fks{m>3641:llh,x>3409:xr,s>2575:xh,kvx}
|
||||
qpk{x<1633:A,x>1755:R,A}
|
||||
qtr{a>671:A,A}
|
||||
fdj{s<2953:mpr,gx}
|
||||
sdh{x>3471:pq,bqm}
|
||||
kkq{m<3791:R,a<1960:R,m>3871:xck,A}
|
||||
fxf{a>2645:R,a<2563:R,s>1762:A,A}
|
||||
mzh{a<3350:R,R}
|
||||
xd{m<3532:R,A}
|
||||
rcr{s>340:A,x>158:A,R}
|
||||
xmj{m<2852:mqq,pxh}
|
||||
ccj{s<3489:R,m>1373:fl,R}
|
||||
dm{x>2462:R,m<3451:A,A}
|
||||
tvg{m<407:A,A}
|
||||
sl{s<3430:A,A}
|
||||
csm{m<2603:kz,m>3229:pdr,x<2006:pn,kt}
|
||||
vp{m<1377:R,R}
|
||||
fz{s<3314:A,R}
|
||||
cl{s>2425:bm,A}
|
||||
mt{x>3089:fks,s<2167:nhd,ck}
|
||||
hdj{a>2641:rld,m>501:jcg,x<790:kpb,hzs}
|
||||
fr{s>1476:A,m<2837:A,s<840:R,cn}
|
||||
prt{x>1207:fqk,x<1076:R,R}
|
||||
mhd{x<215:A,a<614:A,x<473:A,A}
|
||||
qg{s<819:chx,tz}
|
||||
xzs{a>3775:R,a<3614:tkl,x<440:dxb,zff}
|
||||
xjx{m<2030:A,a<1186:R,s<3638:R,R}
|
||||
srj{x<1029:slm,a<390:rf,s>2991:dl,cl}
|
||||
tm{m<2243:bn,jfc}
|
||||
pc{m<3591:zjn,m<3847:A,a>2274:R,hvg}
|
||||
crq{x>2138:R,A}
|
||||
fl{m>1681:A,R}
|
||||
mxd{a>2884:pkc,s>2033:hnt,vpk}
|
||||
gr{a>3121:R,R}
|
||||
bpv{s>1041:A,s>841:R,R}
|
||||
kft{a>2883:rhq,a<2461:ns,xmj}
|
||||
qch{s>1420:R,A}
|
||||
qq{s<3024:A,a<1621:R,x<3397:R,A}
|
||||
hf{m<1930:bf,dp}
|
||||
lb{s>3448:A,R}
|
||||
zmv{s<3274:R,x>3417:R,A}
|
||||
ctr{m<3609:R,a<1962:R,x<2540:A,A}
|
||||
hkp{s>1646:A,srp}
|
||||
mvx{m>2859:R,x<3488:A,R}
|
||||
vhb{a<363:qch,A}
|
||||
bp{s>2455:R,dsv}
|
||||
hsh{s<530:hxt,s<1090:xrl,jtv}
|
||||
bx{s<2039:A,a<3303:R,m>2291:R,R}
|
||||
pnd{a<2844:rgz,m<2449:A,m>2479:jn,gqk}
|
||||
qlk{s>2611:A,s<2092:A,A}
|
||||
vqb{a>443:A,A}
|
||||
jnk{s<2464:bbp,fz}
|
||||
qf{s>2452:A,x<3493:R,a>2585:R,A}
|
||||
hhf{s>3215:A,s>3204:R,R}
|
||||
fqk{s>3289:A,A}
|
||||
ts{s<637:vqb,a>588:sb,rl}
|
||||
fqr{x>2070:R,s<2020:R,m<253:kk,R}
|
||||
xhf{s>2527:tqf,a<1637:jpp,s>1510:stv,A}
|
||||
vv{x<236:A,A}
|
||||
phz{x>1705:A,bcs}
|
||||
rpq{a>371:A,a<189:A,s<1681:A,A}
|
||||
ksd{x<861:gnl,m<1879:bd,x<1267:R,A}
|
||||
llh{s<2375:R,m>3826:R,a>3360:dhv,zmv}
|
||||
dl{x<1110:gn,R}
|
||||
kc{s<2887:bcz,x<730:qlq,gjq}
|
||||
rnv{a>2030:R,A}
|
||||
jfz{m<3510:A,x<232:tbr,R}
|
||||
vz{m>3640:A,x>486:R,R}
|
||||
rh{x>2717:lp,dsz}
|
||||
vb{m>3771:R,x<1919:A,R}
|
||||
pfr{s<3524:krf,x<1618:R,R}
|
||||
rsd{a<2380:R,m<3388:jp,fn}
|
||||
gx{s>3460:cf,a>961:xt,m<2457:rqx,hg}
|
||||
qpz{x<571:A,m<900:R,a>1295:R,R}
|
||||
ctj{a<2109:rcr,R}
|
||||
cg{a<801:nrl,m<655:ljs,xq}
|
||||
tvv{a>3123:dx,m<3516:A,lql}
|
||||
pbn{m<2844:A,m<2979:R,x<869:czg,R}
|
||||
psc{x<2808:fls,fd}
|
||||
mfn{s>361:gbb,mmx}
|
||||
rq{m>3477:A,bdt}
|
||||
qjf{m>3469:jf,a>3075:R,s<3247:zfg,R}
|
||||
pt{a<943:A,s<2493:R,A}
|
||||
nqk{x>1088:A,m<3482:cjv,R}
|
||||
nm{x<3016:A,R}
|
||||
lrn{m>2221:R,s<944:R,R}
|
||||
nx{x<1228:R,A}
|
||||
dd{x<3424:R,x>3749:R,R}
|
||||
kvn{m<3865:A,s>2276:A,s<1944:A,A}
|
||||
fdd{s>1070:A,s<510:R,A}
|
||||
db{s>3186:dpk,a>267:gzv,a<165:nqj,cm}
|
||||
hzl{x<3742:tds,A}
|
||||
ng{m<3172:xbl,m>3206:nfn,A}
|
||||
tx{s>3352:A,x<761:nvq,qqb}
|
||||
qk{x>1230:sv,s<2839:cc,s>3467:kqx,nqk}
|
||||
fdg{x>2748:A,A}
|
||||
hdp{m>194:fc,hn}
|
||||
kfn{s>1076:sqq,x<3311:R,A}
|
||||
kqx{a>2382:qrf,x<1127:A,A}
|
||||
xcj{m<1971:A,R}
|
||||
xbh{a>2219:A,A}
|
||||
zff{m>3648:A,R}
|
||||
gb{m>3833:A,R}
|
||||
fm{s>3311:sdh,s>2946:db,vx}
|
||||
hvm{x>852:A,A}
|
||||
vvl{a>3121:R,x<1888:A,R}
|
||||
mqq{x>649:A,a<2667:djs,s<2270:nrh,R}
|
||||
lvr{x>3164:A,A}
|
||||
mm{m>1622:R,m<1576:R,a<3617:R,A}
|
||||
dnl{m<1785:pdh,x>1500:qh,m>3058:gk,fmj}
|
||||
znf{a>3644:R,m>616:R,R}
|
||||
jx{s<2270:dc,mhd}
|
||||
qkm{m<3068:A,m>3082:A,s<2345:A,A}
|
||||
vpk{x<476:R,s>906:lqh,s<543:R,A}
|
||||
np{a<2600:A,A}
|
||||
sdc{x<3298:A,x>3586:A,R}
|
||||
gd{a>2233:A,rnr}
|
||||
pxh{x>956:pbh,x<633:tpx,s>1719:fml,mfd}
|
||||
ccb{x>1805:zzt,gtc}
|
||||
fjj{m<3563:R,a<3062:A,R}
|
||||
bxd{a<2061:dht,x<1214:ddg,s>713:phn,xxm}
|
||||
gc{a>3697:A,x>1586:R,A}
|
||||
pq{m<2538:R,brk}
|
||||
st{s>985:A,R}
|
||||
sj{s<2968:qtr,s<3559:A,s<3717:xjx,A}
|
||||
cc{x<1067:xtc,m>3623:R,R}
|
||||
mf{m<640:A,R}
|
||||
jh{a>1578:A,a>1429:kd,gsd}
|
||||
kk{m>146:A,x<1964:A,a<2410:R,R}
|
||||
tg{s<2462:A,vh}
|
||||
gv{m>886:R,A}
|
||||
pfs{x<1627:A,x<1710:R,m>3873:A,R}
|
||||
cv{s<841:A,m<3680:R,A}
|
||||
fsl{s>594:cz,m<3496:vt,x<3596:nb,cs}
|
||||
sk{m<420:R,R}
|
||||
fd{x>2977:R,x<2893:A,x>2941:A,A}
|
||||
xtc{m>3658:A,s>1963:A,R}
|
||||
fv{m>1518:tb,R}
|
||||
rzz{a>2302:R,a>2054:A,x>2519:ctr,R}
|
||||
tl{x>1375:mqn,x>1305:qcv,A}
|
||||
mfj{s>525:A,R}
|
||||
tpx{a>2714:A,R}
|
||||
jn{a<3598:R,R}
|
||||
lh{s<765:fjj,x<2579:R,a>3123:A,A}
|
||||
vl{m<640:A,A}
|
||||
nkb{x>1198:csm,s<1799:qg,x>616:tgp,fdj}
|
||||
qcv{s<2985:A,A}
|
||||
khd{s>1945:A,x>438:R,x>179:R,R}
|
||||
hg{a<485:A,R}
|
||||
cz{m<3595:kv,A}
|
||||
mp{m>2937:R,s<2500:A,fdq}
|
||||
kpb{m>238:rv,m>140:R,rjv}
|
||||
pns{m>1520:kj,s>2684:pfr,jm}
|
||||
qrh{x>2812:R,R}
|
||||
rm{x>723:sxc,bb}
|
||||
vk{m>877:A,x<981:A,a<2928:A,R}
|
||||
hbn{m<831:tvg,R}
|
||||
jrl{s>3423:A,R}
|
||||
rjv{s<2026:R,R}
|
||||
sgk{a<1410:R,A}
|
||||
xh{m<3280:A,m<3424:lb,x>3301:A,lvr}
|
||||
gbb{a<2591:A,m>3659:A,R}
|
||||
kz{m<1495:dg,s>2364:sj,hh}
|
||||
lpc{a<1432:xp,x>3244:kr,hp}
|
||||
jvz{s<3621:R,R}
|
||||
tkl{m<3638:A,A}
|
||||
vm{s<1460:R,x<567:R,R}
|
||||
ph{s<2907:A,a>1552:R,x<3818:R,R}
|
||||
czg{m<3013:R,x<517:R,m>3043:A,R}
|
||||
sr{x<3617:R,x<3755:A,x>3887:A,A}
|
||||
gl{m<3472:R,a<2437:R,x>338:R,R}
|
||||
dhv{x>3631:A,x>3309:R,m<3743:A,R}
|
||||
zj{x<2822:R,R}
|
||||
zc{x<2284:R,R}
|
||||
tk{m<243:R,a>762:A,A}
|
||||
fn{s<1386:A,a<2507:A,x>1878:R,R}
|
||||
pct{a<796:R,R}
|
||||
gqk{a>3284:R,m>2462:R,m>2455:A,A}
|
||||
pkc{s<1958:R,s>2881:kh,s<2559:A,R}
|
||||
fst{s>907:R,s<859:A,A}
|
||||
dr{m<1214:zkm,x<1089:mxd,s<1851:bcc,pns}
|
||||
rsx{m>1063:R,s<2954:R,R}
|
||||
jqc{x>3241:vc,A}
|
||||
rgz{x>558:R,m>2449:R,m>2406:R,R}
|
||||
pdh{x>2318:vnv,m>793:dr,a<3139:cq,frf}
|
||||
ps{x<2979:A,A}
|
||||
lj{m<1381:R,m>1474:R,R}
|
||||
pzr{s>2658:R,A}
|
||||
mg{m<3270:R,s<324:R,s>434:A,R}
|
||||
qqc{m<3150:sp,x>1498:R,m>3190:A,kg}
|
||||
srp{s>918:A,m>3662:R,m>3473:R,R}
|
||||
gpt{s<362:A,m<1712:zq,qc}
|
||||
xt{x<319:R,s<3141:tv,m>2094:R,R}
|
||||
css{x>562:A,x>354:R,A}
|
||||
tpm{a<111:R,R}
|
||||
gzv{a>336:R,A}
|
||||
cn{m<2915:A,x<1526:A,s<1244:R,A}
|
||||
zfg{x>459:R,m<3274:A,A}
|
||||
bjn{m<513:nnv,xmv}
|
||||
gz{a<2008:A,x<3451:R,s<2017:A,A}
|
||||
lph{s<3046:R,A}
|
||||
bf{m<1858:hb,a>3679:A,A}
|
||||
kh{x>519:A,A}
|
||||
bn{x>1011:A,m<1155:nmp,qvd}
|
||||
jbq{x<483:R,A}
|
||||
lql{x<1189:R,s<794:A,s<1096:R,A}
|
||||
sqq{m<344:R,R}
|
||||
lk{x>1380:R,x>555:A,rj}
|
||||
bxb{s>964:A,m<2003:mfj,x>560:R,R}
|
||||
hh{m<2169:R,m>2318:A,lrn}
|
||||
pk{x>383:R,x>129:A,m<708:R,A}
|
||||
kls{x<895:R,s<2440:A,a>1576:R,A}
|
||||
tb{a<1584:A,R}
|
||||
bbp{m<2468:R,m>2511:R,s>1950:R,A}
|
||||
stq{s>1124:dhj,x>3727:ts,pm}
|
||||
jjf{a>2228:R,s<676:R,a>2168:R,R}
|
||||
dxq{m<1766:A,x<3488:A,x<3716:A,A}
|
||||
scv{m>1319:A,s>1706:A,R}
|
||||
cb{a>954:R,s<3281:A,A}
|
||||
kj{s<2613:R,a>2986:mm,bg}
|
||||
rhc{s>496:R,s>252:A,A}
|
||||
kn{s<2246:A,A}
|
||||
bqm{a<174:ps,x>2831:A,pb}
|
||||
nv{x<846:nr,zl}
|
||||
tp{m<3318:R,a>894:R,s<2534:R,R}
|
||||
srq{s<2858:xg,hzm}
|
||||
nr{a>3476:xzs,s>2508:qjf,md}
|
||||
gj{x<2161:R,A}
|
||||
czm{s>222:A,m>3220:A,R}
|
||||
mqn{m<3143:A,R}
|
||||
js{m<2226:dlt,zhz}
|
||||
qpb{m<126:A,m>255:A,a<2135:R,R}
|
||||
zzt{x>1994:gj,a>2235:R,s>2411:R,R}
|
||||
kd{s>3005:A,a>1499:R,A}
|
||||
lr{a>2103:xcz,kfn}
|
||||
sxc{x>889:R,s>3111:R,x>824:A,R}
|
||||
tf{s<2663:A,s>2689:A,m<851:R,A}
|
||||
qc{a<351:A,x<934:R,R}
|
||||
gbr{a>705:cb,m<2130:sh,A}
|
||||
ljs{m>294:A,A}
|
||||
nb{m<3714:A,s<381:jdr,gb}
|
||||
rld{x<607:hlt,m<447:R,R}
|
||||
rk{m>3616:A,s>3146:A,s>2420:A,A}
|
||||
ddn{a<370:R,R}
|
||||
hl{x>3111:prr,m>1911:gbr,ccj}
|
||||
bk{s>3269:bt,x>3219:lph,gm}
|
||||
bb{m>3596:R,A}
|
||||
pp{m<3651:bkz,frs}
|
||||
qv{x>982:qk,znt}
|
||||
tqf{x>2607:R,x<2521:R,A}
|
||||
mht{a>2451:A,m>1438:A,m>1341:R,R}
|
||||
sgs{m>3460:A,m>3201:shc,A}
|
||||
mfm{a>2176:R,s<614:R,A}
|
||||
lx{a<1079:A,R}
|
||||
nqj{s>3042:R,x>3012:R,qrh}
|
||||
ddd{m>3779:R,A}
|
||||
kt{x<2175:mp,ckn}
|
||||
dxb{x>170:A,A}
|
||||
zfb{a>421:R,s>878:A,R}
|
||||
dlt{m<2140:np,s<1831:R,xrr}
|
||||
dx{a>3306:A,m>3568:R,a>3212:A,A}
|
||||
snv{x>641:R,R}
|
||||
qvd{m<1570:R,A}
|
||||
zd{s>2964:A,s>2728:A,R}
|
||||
ff{a<230:A,R}
|
||||
sg{s<993:A,m<849:A,A}
|
||||
nsf{x>3378:stq,a<715:snm,dh}
|
||||
vt{a>2421:mg,czm}
|
||||
nvq{m>3480:A,R}
|
||||
jcg{m>647:A,x>816:R,m>579:jbq,A}
|
||||
znt{s<2517:vr,x<552:jfz,a<2437:rm,tx}
|
||||
cjj{s<2391:R,rsx}
|
||||
dp{s<2929:fk,s<3614:R,m>2016:xmc,A}
|
||||
hqd{x>3367:R,s>1503:A,R}
|
||||
hk{s<277:R,s>483:R,m>1358:R,btx}
|
||||
sgg{m<2348:js,jzh}
|
||||
nfn{a>2132:R,x>1793:R,A}
|
||||
ftj{x<1389:R,R}
|
||||
xcz{m<466:A,a<2325:jjf,R}
|
||||
kzs{a>1910:A,x<951:R,A}
|
||||
xxm{m>3336:xcs,a>2151:A,ftj}
|
||||
mnn{s>3268:A,A}
|
||||
rl{m>1634:A,A}
|
||||
crp{s>557:R,R}
|
||||
fkh{a<1419:pz,rs}
|
||||
xxb{a<2370:A,A}
|
||||
mh{m>3820:R,x<2083:A,a>2996:R,A}
|
||||
fgb{s>2569:A,x>2450:A,R}
|
||||
nk{a<162:A,m<2726:frn,xpj}
|
||||
fc{x>1147:rvm,R}
|
||||
lm{m<3260:ng,rsd}
|
||||
cf{s>3729:rbt,m<2604:jvz,mq}
|
||||
dcf{x>3774:R,s<3116:R,R}
|
||||
lxx{x>1530:sl,x>518:vk,R}
|
||||
tgp{x<868:kc,a<752:srj,a<1341:tm,dk}
|
||||
kxv{a>891:R,R}
|
||||
zq{m<604:A,A}
|
||||
in{a<1805:pkg,dnl}
|
||||
zjn{m>3311:A,R}
|
||||
qqb{s<2931:R,x<851:R,R}
|
||||
pkg{x>2464:ljb,nkb}
|
||||
xg{a>149:A,m>2665:R,A}
|
||||
hc{x>279:cms,s<810:ctj,ttg}
|
||||
pm{s<517:R,m<1522:zfb,A}
|
||||
bcc{a>2934:xlj,x<1869:tkh,pnl}
|
||||
dj{m<103:R,m<138:R,A}
|
||||
nhd{x<2267:px,a<3424:lh,x>2623:szv,dm}
|
||||
bz{s>1704:qkp,x<3526:gr,R}
|
||||
rlz{a<3140:A,a>3293:R,x<297:A,R}
|
||||
vr{m<3643:R,a<2289:khd,htn}
|
||||
xr{a>3318:R,s<2341:A,s<3166:fcb,tn}
|
||||
cnp{m>911:R,m>568:A,tq}
|
||||
cq{x<1353:hdj,kx}
|
||||
zf{x<3828:A,a>1730:A,R}
|
||||
vx{s>2774:srq,m<1675:jt,s<2684:hv,nk}
|
||||
fnv{x>1143:R,R}
|
||||
xm{s<2292:R,R}
|
||||
kkp{m<2571:R,s<2085:hx,m>2800:gvm,R}
|
||||
hv{s<2661:A,m>2764:A,A}
|
||||
hzs{a>2161:R,x>1063:A,rnv}
|
||||
dh{x<3018:xdd,jqc}
|
||||
kvr{s<2242:vv,pk}
|
||||
hxt{a>2221:R,A}
|
||||
fct{m>3536:R,a<2575:A,R}
|
||||
ndh{m<972:znf,A}
|
||||
mpr{m>2022:jx,a<771:tg,s<2472:kvr,cnp}
|
||||
cp{m<2848:mzh,m>2927:gbz,A}
|
||||
nzd{s>238:R,x>606:R,x>549:R,R}
|
||||
mmx{x>1313:R,m<3589:R,A}
|
||||
vbr{a>3008:A,s<584:A,s<808:R,R}
|
||||
pmh{x>3296:R,m<489:sk,mf}
|
||||
fjg{a<1047:ddn,m<3101:qkm,a>1301:A,qnd}
|
||||
msp{m<717:gjj,a<3625:fgb,bxp}
|
||||
snl{x>3421:A,m<252:A,R}
|
||||
jdt{a<3134:qcg,s>1586:hf,cxg}
|
||||
xmc{x<570:A,x<1144:A,m>2053:R,R}
|
||||
kx{m>382:phz,x>1822:fqr,ztt}
|
||||
gbz{x<965:A,m<3013:A,m>3029:A,A}
|
||||
mx{x>3328:hzl,a<3372:jmc,x>2691:ndh,msp}
|
||||
frn{x<3473:A,a<285:A,R}
|
||||
bcs{x<1512:A,m>603:R,A}
|
||||
ttg{a>2011:R,A}
|
||||
hp{m>1412:psc,x>2760:hbn,xhf}
|
||||
nz{s>3208:R,s<2786:R,s>2974:A,A}
|
||||
krf{s<3091:A,m>1327:A,A}
|
||||
bcz{x>711:pt,a>1188:A,s<2432:A,A}
|
||||
rnr{a<2207:R,R}
|
||||
rj{x>314:A,s<912:A,a>3832:A,R}
|
||||
dg{s>1406:A,zsq}
|
||||
mzv{x>3263:R,R}
|
||||
qcg{x<980:lsp,qx}
|
||||
zhz{a>3088:jzq,kp}
|
||||
mzf{x>1264:A,R}
|
||||
btx{m>888:R,x>745:A,R}
|
||||
jtv{x<1844:mlv,x>2006:R,x>1914:A,htc}
|
||||
dgl{a<3453:R,s>2663:A,A}
|
||||
rp{m<2155:qpz,s<1318:sn,s<1583:css,R}
|
||||
tc{s<2033:A,a>1598:zf,a>1490:ph,dcf}
|
||||
hr{s<3608:R,x>447:R,R}
|
||||
rtb{m<2921:A,R}
|
||||
djs{x<335:A,s<1702:R,m>2691:A,A}
|
||||
nh{x>2140:R,m>1477:R,x>2039:A,A}
|
||||
kf{a<2025:R,s<3004:A,A}
|
||||
xlj{m<1564:lj,m>1698:tj,a>3333:gc,jc}
|
||||
jfc{a>995:R,x<1009:A,x<1095:A,tp}
|
||||
tkh{s>682:xxb,s>330:crp,a<2194:rz,mht}
|
||||
gn{x<1066:A,R}
|
||||
rhq{s>1782:cp,pbn}
|
||||
vj{s<3790:A,m<339:R,x<2823:A,A}
|
||||
tps{x>674:A,s<3265:A,A}
|
||||
szv{x<2868:ft,x>2976:vkh,s>841:R,rhc}
|
||||
trj{a<2273:jlj,gs}
|
||||
skv{a<2338:A,s>2958:R,s<2678:A,R}
|
||||
xmv{s<2988:A,s<3065:klm,kxv}
|
||||
hx{m>2810:R,A}
|
||||
sc{s<2986:A,R}
|
||||
zqz{s<3128:fg,x>611:jrl,A}
|
||||
frf{s<1691:jl,m<423:hdp,vrr}
|
||||
gsd{m>2232:R,s<2763:R,A}
|
||||
shl{a<2163:rd,x>3349:bp,nd}
|
||||
kr{x<3615:qmz,tc}
|
||||
bc{x<3311:A,s<3351:kf,xd}
|
||||
xgj{s>3591:A,m<548:R,x<3697:R,A}
|
||||
pnl{a>2241:nh,rcn}
|
||||
chx{x<575:lt,a<897:gpt,x>917:fkh,hk}
|
||||
fhs{m>700:R,A}
|
||||
nrh{x>238:R,a>2784:R,a<2732:A,R}
|
||||
hrz{x>1950:hm,a<902:A,m>3685:R,R}
|
||||
pxb{x>1142:mzf,gdx}
|
||||
xvz{s>561:ccg,R}
|
||||
xcs{s<422:A,a<2161:R,A}
|
||||
rx{a<3008:A,m<901:R,A}
|
||||
tbr{a<2365:R,s>3452:A,s>2930:A,R}
|
||||
frp{x>900:htl,s>573:sq,kkq}
|
||||
md{s>1652:vz,s<1077:vbr,rlz}
|
||||
ms{a>2247:fct,a>1974:A,s>2168:A,zc}
|
||||
frs{x<3540:kvn,m>3878:A,xcv}
|
||||
dgd{s>3214:hr,m<644:tnm,x>467:mr,R}
|
||||
lq{s<3221:sc,m<3569:A,x<3563:lvc,ddd}
|
||||
nnv{s>2853:tk,s>2735:snl,m>327:A,fln}
|
||||
qx{a<2498:R,a>2737:A,m<1893:fxf,R}
|
||||
xrr{s<3174:R,m>2190:A,x>908:A,R}
|
||||
hvg{a<1985:A,A}
|
||||
htl{a>2010:R,A}
|
||||
lsp{s<2234:xcj,m>1926:A,skv}
|
||||
rd{s<2503:R,x<3017:fdg,A}
|
||||
jds{x>1157:A,ssh}
|
||||
ddg{m>3417:mfm,x>942:ml,s<466:hvm,A}
|
||||
kv{a<2344:A,A}
|
||||
xdd{m>2260:A,a<992:gv,scv}
|
||||
jc{a<3114:A,R}
|
||||
sql{s<3259:br,a>3232:ggp,mh}
|
||||
snm{m>2141:vhb,m<1213:pv,nhb}
|
||||
vkh{s<955:R,s<1453:A,A}
|
||||
vnv{a>2559:mx,m>739:shl,s<1629:lr,cht}
|
||||
bkz{m<3362:gz,a>1950:hsz,R}
|
||||
slm{x<964:R,s>3235:vp,x<998:R,A}
|
||||
ft{m>3486:R,A}
|
||||
xck{x>451:A,A}
|
||||
hsz{a>2033:A,a<2000:A,m<3504:A,A}
|
||||
vh{a>503:R,s<2712:R,s>2843:A,R}
|
||||
pn{m<3019:fr,s<1453:qqc,x<1554:tl,fjg}
|
||||
px{x<1919:A,a>3411:crq,R}
|
||||
qkp{a<2827:A,m<2764:A,A}
|
||||
hn{a<3478:R,dj}
|
||||
gk{a>2753:nv,s>1384:qv,qtk}
|
||||
ggp{x>2183:R,A}
|
||||
tz{a>850:rp,nxm}
|
||||
jzh{x<856:pnd,s<1629:xvz,jnk}
|
||||
rvm{x<1863:R,m<286:A,A}
|
||||
kcm{x<915:kls,qlk}
|
||||
xp{s>2278:zk,hq}
|
||||
fls{a<1668:R,A}
|
||||
kg{a<833:R,s<541:R,A}
|
||||
td{s<1606:fsl,s>2769:qs,a<2163:pp,dqq}
|
||||
cxg{m<1949:ksd,a>3471:bxb,a<3282:ch,snv}
|
||||
jkx{s<1504:A,kn}
|
||||
rn{a<535:R,A}
|
||||
qh{m<3052:rh,a>2744:mt,x>2911:td,pj}
|
||||
nrl{x>3482:xgj,s>3672:vj,a<577:A,vl}
|
||||
cht{m>330:pmh,bfr}
|
||||
vg{x>366:A,R}
|
||||
fcb{s>2877:R,a<2979:A,m<3367:A,A}
|
||||
rv{s>2225:A,a<2143:R,A}
|
||||
fdq{x>2118:A,A}
|
||||
dz{a<2077:A,m>3350:A,s>221:R,R}
|
||||
cs{m>3766:szs,x<3765:A,R}
|
||||
jlj{x>2392:A,x>2372:A,R}
|
||||
qrf{m>3565:R,s<3757:R,R}
|
||||
pb{a>351:R,a>257:A,A}
|
||||
qnd{a>1151:R,x<1745:R,x>1864:R,A}
|
||||
ck{m>3671:sql,sgs}
|
||||
mq{a<1025:A,s>3611:R,s<3520:R,R}
|
||||
htn{x>503:A,m>3852:R,s>2112:R,A}
|
||||
pz{a<1213:R,s<531:A,A}
|
||||
shc{a<3329:R,s>2874:A,s<2537:A,R}
|
||||
gnl{a<3649:A,R}
|
||||
dqq{a<2368:gd,s<2264:rq,bcq}
|
||||
qr{s>3033:R,s>2249:R,s>1972:R,R}
|
||||
kp{a<2531:R,s<1615:R,a>2828:R,R}
|
||||
xpj{s>2734:A,m<3285:R,x<3369:A,R}
|
||||
sbs{x>2566:pc,x>2455:rzz,x>2351:trj,ms}
|
||||
sv{a>2152:R,a>1957:R,s<2504:A,ktn}
|
||||
ch{x<818:R,s<530:A,A}
|
||||
dc{m>2856:A,x>364:R,a>679:A,R}
|
||||
ccg{a>2984:A,a<2383:A,R}
|
||||
kzq{a>2303:A,xbh}
|
||||
tds{m<1004:R,s<1678:R,x<3470:R,R}
|
||||
stv{x<2625:R,s>1999:R,m>887:A,R}
|
||||
tn{m>3378:R,a>3123:A,A}
|
||||
xrl{x>1894:cv,a>2121:A,x<1674:mn,A}
|
||||
rql{x<292:A,A}
|
||||
bm{s<2693:R,a>530:A,A}
|
||||
jf{s<3466:A,m>3716:A,R}
|
||||
rz{s<154:R,A}
|
||||
nt{m>1697:R,R}
|
||||
sft{s>3185:A,x>1604:dgl,x>1373:xm,pzr}
|
||||
lvc{s>3545:R,s>3369:A,A}
|
||||
rf{a<197:tpm,s>2658:A,s<2248:R,A}
|
||||
tnm{m>562:R,x<697:R,x>882:R,A}
|
||||
nd{a>2411:zj,x>2779:nm,R}
|
||||
jzz{x>717:xf,x>282:A,m>3530:st,bpv}
|
||||
hm{m<3674:A,s>3421:R,a<946:A,A}
|
||||
dht{a>1916:R,a>1856:R,m>3310:fnv,A}
|
||||
lv{a>1547:R,nt}
|
||||
jzq{m>2270:R,A}
|
||||
pbh{a>2740:A,R}
|
||||
rqx{m>877:A,m<466:rql,fhs}
|
||||
jm{m<1319:R,m>1434:A,vvl}
|
||||
bd{x<1278:R,R}
|
||||
phn{s>1047:R,x>1340:R,A}
|
||||
htc{s<1275:R,a<2126:R,m>3702:A,R}
|
||||
bs{m<2785:vm,kzs}
|
||||
tv{s<3016:R,m>1424:R,A}
|
||||
mn{m<3801:A,R}
|
||||
ndr{a<2451:A,R}
|
||||
gjq{s<3377:mqf,R}
|
||||
xdq{x<1040:R,R}
|
||||
tq{m>255:A,x<241:R,m<126:R,A}
|
||||
ktn{m<3428:R,R}
|
||||
sn{a>1291:R,R}
|
||||
lqh{s>1302:A,A}
|
||||
bdt{x<3511:R,R}
|
||||
bfr{a>2244:A,x<3334:A,a>1974:qpb,qr}
|
||||
fp{m>3697:R,a>2058:R,x>1621:R,R}
|
||||
xq{m>820:mzv,m<714:A,sdc}
|
||||
jl{a<3597:xdq,lk}
|
||||
dsz{a<2722:kkp,bx}
|
||||
nhb{a>443:R,m<1590:xjt,A}
|
||||
qtc{m<857:A,A}
|
||||
pv{m>556:qtc,rpq}
|
||||
lp{m>2290:bz,lgs}
|
||||
ml{s>883:A,a<2164:A,s<393:A,A}
|
||||
fg{x<893:A,R}
|
||||
kvx{x<3291:A,x>3337:hqd,x>3313:fdd,mql}
|
||||
mqf{s>3110:R,x<798:R,A}
|
||||
kmt{s<1459:R,m>3633:vb,A}
|
||||
bcq{s<2597:qf,A}
|
||||
fk{m<2037:A,R}
|
||||
hnt{a<2261:R,x<687:A,x<935:A,R}
|
||||
pj{x>2249:sbs,m<3497:lm,s>1474:ccb,hsh}
|
||||
cjv{a>2375:R,a>2069:A,R}
|
||||
bg{x<1849:A,a>2393:R,a<2075:R,R}
|
||||
pdr{s>2635:hrz,a>617:kmt,x>1754:jkx,hkp}
|
||||
fmj{m>2534:kft,m>2093:sgg,jdt}
|
||||
tj{x<1824:A,m<1745:R,x>2008:A,R}
|
||||
hlt{a>2845:R,a>2760:A,x>221:A,A}
|
||||
ljb{a>1200:lpc,s<2627:nsf,a<441:fm,gfb}
|
||||
sh{s<3242:A,s<3602:R,R}
|
||||
zl{s>2245:prt,s>1272:pxb,a>3502:jds,tvv}
|
||||
nxm{s>1200:gtr,s<965:fst,R}
|
||||
nzs{m<882:sg,m>905:nx,x<886:R,R}
|
||||
ssh{x>965:R,a<3788:A,A}
|
||||
mql{x>3299:A,a>3451:A,A}
|
||||
vrr{x<1239:dgd,sft}
|
||||
gxq{m<3686:ndr,m>3886:A,x<829:A,R}
|
||||
xf{s<1136:R,A}
|
||||
jp{m<3305:R,R}
|
||||
bt{x>3254:sr,s<3547:R,s<3826:A,R}
|
||||
qtk{a>2269:rjn,m>3609:frp,x>707:bxd,hc}
|
||||
fml{x>777:A,R}
|
||||
lgs{a>3182:A,x>3362:R,m>2105:A,A}
|
||||
szs{m>3858:R,a<2142:A,R}
|
||||
gjj{x<2561:A,a>3790:A,R}
|
||||
mlv{s>1239:A,m<3825:A,x<1728:A,A}
|
||||
zsq{a<619:R,x<1745:A,x<2145:A,A}
|
||||
qmz{m<2523:R,s<1599:R,qq}
|
||||
zk{x<3150:R,zd}
|
||||
rs{a>1601:A,R}
|
||||
qs{a>2415:lq,bc}
|
||||
gdx{s<1774:R,A}
|
||||
jpp{m<764:R,m<1091:A,R}
|
||||
jt{x>3303:R,x<2817:ttm,s<2710:tf,A}
|
||||
klm{s>3017:A,m>799:A,m<681:R,R}
|
||||
ztt{m>192:R,a>2369:R,qpk}
|
||||
fln{x<3047:R,m>193:A,a<853:R,R}
|
||||
br{x<2460:A,R}
|
||||
hq{m<1545:A,s>849:rtb,mvx}
|
||||
rbt{m<2269:A,x>339:R,a<1074:R,R}
|
||||
ns{s>2422:zqz,a>2120:kzq,bs}
|
||||
dk{x>1017:jh,x>954:lv,s>3140:fv,kcm}
|
||||
sb{s>897:R,s<753:R,R}
|
||||
jdr{s>209:R,m<3863:R,m<3923:R,A}
|
||||
rjn{s>679:jzz,x<530:gl,x>1059:mfn,gxq}
|
||||
gfb{m>2467:bk,m>990:hl,s>3218:cg,bjn}
|
||||
ttm{s<2678:R,A}
|
||||
gvm{a>2405:A,s<2926:A,m<2950:A,A}
|
||||
gtc{a<2342:fp,m<3796:rk,pfs}
|
||||
hb{m<1813:R,A}
|
||||
zkm{m>940:cjj,s<2335:nzs,lxx}
|
||||
sp{s<869:R,m>3063:R,a<1081:R,R}
|
||||
gs{s<1767:A,A}
|
||||
rcn{x>2139:R,R}
|
||||
dpk{a>173:R,s>3240:mnn,hhf}
|
||||
vc{a<1019:R,R}
|
||||
prr{a>765:R,dxq}
|
||||
qlq{s>3515:R,a>727:A,tps}
|
||||
hzm{m>1445:R,R}
|
||||
sq{m>3864:A,m<3760:R,x<438:R,A}
|
||||
xjt{x<2801:R,a>256:R,R}
|
||||
bxp{x>2497:R,R}
|
||||
mr{m>730:R,R}
|
||||
gm{s<2923:pct,m<3485:R,x>2891:R,A}
|
||||
dsv{s>1297:A,m<1434:R,m>1572:R,A}
|
||||
xbl{a<2315:A,a<2548:A,s>2455:R,A}
|
||||
jmc{s<2500:rx,a<2842:R,x<2783:A,nz}
|
||||
ckn{a<715:A,s>1703:sgk,lx}
|
||||
dhj{s>1705:A,rn}
|
||||
nmp{x<937:A,x<974:R,a>973:A,A}
|
||||
|
||||
{x=97,m=3034,a=520,s=1230}
|
||||
{x=48,m=2597,a=1043,s=2427}
|
||||
{x=520,m=825,a=547,s=205}
|
||||
{x=90,m=1232,a=115,s=882}
|
||||
{x=1532,m=1668,a=2430,s=2369}
|
||||
{x=2095,m=753,a=347,s=1636}
|
||||
{x=15,m=3389,a=126,s=2070}
|
||||
{x=793,m=1658,a=310,s=2364}
|
||||
{x=959,m=1660,a=1185,s=681}
|
||||
{x=1109,m=1979,a=109,s=336}
|
||||
{x=415,m=424,a=1721,s=270}
|
||||
{x=323,m=1374,a=905,s=1917}
|
||||
{x=1450,m=1674,a=3109,s=2981}
|
||||
{x=205,m=89,a=1825,s=443}
|
||||
{x=92,m=70,a=712,s=655}
|
||||
{x=209,m=1050,a=320,s=1643}
|
||||
{x=488,m=834,a=1222,s=520}
|
||||
{x=32,m=746,a=577,s=133}
|
||||
{x=1206,m=740,a=223,s=1454}
|
||||
{x=109,m=978,a=3025,s=222}
|
||||
{x=149,m=1568,a=186,s=367}
|
||||
{x=49,m=680,a=375,s=113}
|
||||
{x=1071,m=321,a=194,s=866}
|
||||
{x=1099,m=246,a=767,s=3686}
|
||||
{x=463,m=1245,a=132,s=180}
|
||||
{x=2031,m=2121,a=127,s=99}
|
||||
{x=22,m=384,a=2498,s=1219}
|
||||
{x=1647,m=1199,a=1182,s=450}
|
||||
{x=1383,m=1078,a=240,s=1829}
|
||||
{x=481,m=995,a=475,s=428}
|
||||
{x=1461,m=1352,a=186,s=246}
|
||||
{x=871,m=1677,a=41,s=2389}
|
||||
{x=26,m=3600,a=1,s=2609}
|
||||
{x=229,m=498,a=633,s=325}
|
||||
{x=1893,m=314,a=678,s=505}
|
||||
{x=3819,m=1,a=101,s=734}
|
||||
{x=1247,m=520,a=564,s=390}
|
||||
{x=134,m=1176,a=275,s=1027}
|
||||
{x=873,m=2365,a=667,s=659}
|
||||
{x=271,m=189,a=332,s=826}
|
||||
{x=1928,m=972,a=191,s=2033}
|
||||
{x=403,m=379,a=3351,s=833}
|
||||
{x=629,m=690,a=486,s=1}
|
||||
{x=360,m=3135,a=352,s=583}
|
||||
{x=1066,m=889,a=949,s=402}
|
||||
{x=1953,m=229,a=1595,s=179}
|
||||
{x=861,m=2271,a=700,s=20}
|
||||
{x=9,m=1627,a=81,s=2023}
|
||||
{x=313,m=1388,a=667,s=1091}
|
||||
{x=1137,m=1665,a=124,s=626}
|
||||
{x=1061,m=429,a=54,s=1830}
|
||||
{x=815,m=51,a=550,s=1247}
|
||||
{x=124,m=952,a=897,s=1886}
|
||||
{x=680,m=148,a=2408,s=2}
|
||||
{x=3132,m=1257,a=1604,s=1052}
|
||||
{x=698,m=749,a=81,s=59}
|
||||
{x=2834,m=262,a=1239,s=2597}
|
||||
{x=191,m=218,a=444,s=53}
|
||||
{x=1740,m=750,a=46,s=335}
|
||||
{x=468,m=531,a=2898,s=1772}
|
||||
{x=655,m=1360,a=2860,s=973}
|
||||
{x=854,m=529,a=1226,s=550}
|
||||
{x=486,m=785,a=2418,s=614}
|
||||
{x=534,m=1710,a=2052,s=594}
|
||||
{x=116,m=2580,a=27,s=428}
|
||||
{x=778,m=1090,a=1359,s=1328}
|
||||
{x=405,m=2739,a=3242,s=2159}
|
||||
{x=34,m=2314,a=1055,s=857}
|
||||
{x=1110,m=1263,a=216,s=2526}
|
||||
{x=1177,m=284,a=1042,s=1597}
|
||||
{x=251,m=3649,a=1844,s=1427}
|
||||
{x=872,m=1048,a=1991,s=411}
|
||||
{x=2299,m=154,a=113,s=2699}
|
||||
{x=399,m=432,a=939,s=7}
|
||||
{x=2885,m=756,a=344,s=96}
|
||||
{x=1945,m=2586,a=1677,s=787}
|
||||
{x=1497,m=1101,a=1879,s=349}
|
||||
{x=1066,m=938,a=1124,s=27}
|
||||
{x=285,m=370,a=2779,s=1235}
|
||||
{x=210,m=203,a=1392,s=2350}
|
||||
{x=3118,m=2349,a=342,s=108}
|
||||
{x=1181,m=668,a=1853,s=2686}
|
||||
{x=143,m=662,a=404,s=37}
|
||||
{x=3342,m=2811,a=432,s=630}
|
||||
{x=539,m=432,a=160,s=465}
|
||||
{x=378,m=752,a=1528,s=32}
|
||||
{x=579,m=903,a=1012,s=807}
|
||||
{x=5,m=606,a=2425,s=2214}
|
||||
{x=409,m=493,a=1110,s=3168}
|
||||
{x=1662,m=1930,a=20,s=1684}
|
||||
{x=49,m=2284,a=528,s=29}
|
||||
{x=106,m=1201,a=1842,s=572}
|
||||
{x=2,m=1241,a=489,s=2092}
|
||||
{x=747,m=774,a=1023,s=51}
|
||||
{x=766,m=2744,a=1260,s=35}
|
||||
{x=225,m=85,a=313,s=203}
|
||||
{x=1065,m=3852,a=3001,s=224}
|
||||
{x=1080,m=68,a=2236,s=579}
|
||||
{x=1202,m=709,a=650,s=113}
|
||||
{x=1368,m=50,a=1621,s=72}
|
||||
{x=142,m=761,a=557,s=154}
|
||||
{x=1898,m=77,a=380,s=707}
|
||||
{x=1022,m=155,a=3318,s=556}
|
||||
{x=376,m=1130,a=1293,s=7}
|
||||
{x=268,m=873,a=408,s=453}
|
||||
{x=2057,m=1316,a=1370,s=1291}
|
||||
{x=81,m=285,a=1445,s=2015}
|
||||
{x=2449,m=725,a=1567,s=1198}
|
||||
{x=2550,m=779,a=178,s=9}
|
||||
{x=719,m=574,a=3040,s=2694}
|
||||
{x=272,m=92,a=1526,s=811}
|
||||
{x=10,m=354,a=285,s=476}
|
||||
{x=43,m=2071,a=1017,s=501}
|
||||
{x=680,m=1749,a=2515,s=3395}
|
||||
{x=369,m=1441,a=444,s=820}
|
||||
{x=1946,m=616,a=398,s=1840}
|
||||
{x=693,m=3478,a=53,s=487}
|
||||
{x=2902,m=429,a=237,s=525}
|
||||
{x=442,m=209,a=2734,s=1911}
|
||||
{x=3447,m=953,a=696,s=392}
|
||||
{x=658,m=65,a=1036,s=821}
|
||||
{x=720,m=570,a=40,s=463}
|
||||
{x=1607,m=147,a=952,s=1673}
|
||||
{x=1169,m=1312,a=481,s=2083}
|
||||
{x=709,m=160,a=186,s=1370}
|
||||
{x=1283,m=2187,a=337,s=89}
|
||||
{x=2933,m=2469,a=55,s=1198}
|
||||
{x=1009,m=813,a=1280,s=1980}
|
||||
{x=1128,m=446,a=56,s=2315}
|
||||
{x=320,m=839,a=1176,s=1555}
|
||||
{x=2719,m=1776,a=2869,s=593}
|
||||
{x=1236,m=2786,a=1644,s=131}
|
||||
{x=1806,m=1125,a=196,s=2414}
|
||||
{x=175,m=1618,a=381,s=2136}
|
||||
{x=748,m=58,a=1006,s=676}
|
||||
{x=449,m=56,a=852,s=428}
|
||||
{x=1447,m=515,a=2256,s=550}
|
||||
{x=2372,m=2045,a=845,s=2483}
|
||||
{x=3147,m=1641,a=708,s=702}
|
||||
{x=123,m=426,a=4,s=59}
|
||||
{x=615,m=253,a=1880,s=1551}
|
||||
{x=99,m=1119,a=473,s=987}
|
||||
{x=3070,m=1697,a=1137,s=2525}
|
||||
{x=967,m=2275,a=429,s=106}
|
||||
{x=1615,m=2679,a=405,s=166}
|
||||
{x=1564,m=200,a=307,s=154}
|
||||
{x=74,m=2971,a=1556,s=199}
|
||||
{x=3023,m=1890,a=2602,s=416}
|
||||
{x=2854,m=67,a=662,s=718}
|
||||
{x=95,m=97,a=214,s=252}
|
||||
{x=2025,m=788,a=191,s=880}
|
||||
{x=975,m=485,a=355,s=52}
|
||||
{x=619,m=758,a=491,s=569}
|
||||
{x=197,m=12,a=193,s=2070}
|
||||
{x=839,m=652,a=20,s=24}
|
||||
{x=83,m=92,a=309,s=536}
|
||||
{x=3025,m=501,a=1418,s=1540}
|
||||
{x=42,m=1817,a=170,s=2125}
|
||||
{x=808,m=662,a=41,s=577}
|
||||
{x=30,m=142,a=1692,s=474}
|
||||
{x=854,m=1999,a=3126,s=1189}
|
||||
{x=346,m=1370,a=1116,s=2035}
|
||||
{x=233,m=752,a=516,s=1179}
|
||||
{x=3217,m=3109,a=29,s=73}
|
||||
{x=484,m=2314,a=225,s=2}
|
||||
{x=898,m=2681,a=2313,s=1328}
|
||||
{x=1095,m=1220,a=331,s=1174}
|
||||
{x=3569,m=1665,a=27,s=324}
|
||||
{x=170,m=2228,a=3119,s=618}
|
||||
{x=17,m=186,a=1137,s=5}
|
||||
{x=75,m=938,a=235,s=73}
|
||||
{x=569,m=330,a=1178,s=1201}
|
||||
{x=2288,m=199,a=2644,s=21}
|
||||
{x=741,m=580,a=114,s=1896}
|
||||
{x=234,m=524,a=1372,s=616}
|
||||
{x=1027,m=27,a=905,s=1145}
|
||||
{x=170,m=24,a=888,s=1257}
|
||||
{x=2412,m=2908,a=327,s=627}
|
||||
{x=2041,m=1036,a=1798,s=3228}
|
||||
{x=887,m=164,a=75,s=2456}
|
||||
{x=56,m=595,a=1643,s=86}
|
||||
{x=88,m=394,a=292,s=277}
|
||||
{x=1343,m=1241,a=2035,s=180}
|
||||
{x=50,m=150,a=496,s=378}
|
||||
{x=1414,m=828,a=1585,s=226}
|
||||
{x=3243,m=117,a=1357,s=141}
|
||||
{x=528,m=854,a=259,s=619}
|
||||
{x=40,m=794,a=1497,s=2787}
|
||||
{x=2157,m=388,a=658,s=993}
|
||||
{x=911,m=1159,a=346,s=1165}
|
||||
{x=105,m=916,a=84,s=2514}
|
||||
{x=2577,m=1880,a=601,s=2679}
|
||||
{x=2262,m=1108,a=1022,s=45}
|
||||
{x=780,m=445,a=291,s=201}
|
||||
{x=3173,m=535,a=1280,s=3422}
|
||||
{x=1308,m=49,a=910,s=1391}
|
||||
{x=944,m=158,a=3,s=1409}
|
||||
{x=125,m=340,a=1970,s=3505}
|
||||
{x=145,m=2289,a=1040,s=1482}
|
||||
{x=1395,m=1185,a=224,s=1174}
|
17
day19/input_test.txt
Normal file
17
day19/input_test.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
in{s<1351:px,qqz}
|
||||
px{a<2006:qkq,m>2090:A,rfg}
|
||||
pv{a>1716:R,A}
|
||||
lnx{m>1548:A,A}
|
||||
rfg{s<537:gd,x>2440:R,A}
|
||||
qs{s>3448:A,lnx}
|
||||
qkq{x<1416:A,crn}
|
||||
crn{x>2662:A,R}
|
||||
qqz{s>2770:qs,m<1801:hdj,R}
|
||||
gd{a>3333:R,R}
|
||||
hdj{m>838:A,pv}
|
||||
|
||||
{x=787,m=2655,a=1222,s=2876}
|
||||
{x=1679,m=44,a=2067,s=496}
|
||||
{x=2036,m=264,a=79,s=2244}
|
||||
{x=2461,m=1339,a=466,s=291}
|
||||
{x=2127,m=1623,a=2188,s=1013}
|
187
day19/src/main.rs
Normal file
187
day19/src/main.rs
Normal file
@@ -0,0 +1,187 @@
|
||||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::read_to_string;
|
||||
use std::ops::Range;
|
||||
use std::time::Instant;
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
enum RuleConditionVariable {
|
||||
X,
|
||||
M,
|
||||
A,
|
||||
S,
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
enum RuleConditionOperation {
|
||||
Less,
|
||||
Greater,
|
||||
}
|
||||
|
||||
struct Rule<'a> {
|
||||
variable: RuleConditionVariable,
|
||||
operation: RuleConditionOperation,
|
||||
argument: i32,
|
||||
result: &'a str,
|
||||
}
|
||||
|
||||
fn check_part(workflows: &HashMap<&str, Vec<Rule>>, part: &[i32; 4]) -> bool {
|
||||
let mut workflow: &Vec<Rule> = &workflows["in"];
|
||||
let mut workflow_index: usize = 0;
|
||||
while workflow_index < workflow.len() {
|
||||
let rule = &workflow[workflow_index];
|
||||
let mut passed_condition = true;
|
||||
if rule.variable != RuleConditionVariable::None {
|
||||
match rule.operation {
|
||||
RuleConditionOperation::Less => {
|
||||
passed_condition = part[rule.variable as usize] < rule.argument;
|
||||
}
|
||||
RuleConditionOperation::Greater => {
|
||||
passed_condition = part[rule.variable as usize] > rule.argument;
|
||||
}
|
||||
}
|
||||
}
|
||||
if passed_condition {
|
||||
match rule.result {
|
||||
"R" => return false,
|
||||
"A" => return true,
|
||||
_ => {
|
||||
workflow = &workflows[rule.result];
|
||||
workflow_index = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
workflow_index += 1;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn count_options(workflows: &HashMap<&str, Vec<Rule>>,
|
||||
start: &str, parts: &[Range<i32>; 4]) -> u64 {
|
||||
let workflow: &Vec<Rule> = &workflows[start];
|
||||
let mut workflow_index: usize = 0;
|
||||
let mut options = 0u64;
|
||||
let mut checked_parts = parts.clone();
|
||||
let count_ranges_options = |parts: &[Range<i32>; 4], next: &str| {
|
||||
match next {
|
||||
"R" => 0,
|
||||
"A" => parts.iter().fold(1u64, |acc, range| {
|
||||
acc * cmp::max(0, range.end - range.start) as u64
|
||||
}),
|
||||
_ => count_options(workflows, next, parts)
|
||||
}
|
||||
};
|
||||
while workflow_index < workflow.len() {
|
||||
let rule = &workflow[workflow_index];
|
||||
if rule.variable != RuleConditionVariable::None {
|
||||
let mut new_parts = checked_parts.clone();
|
||||
let new_parts_var = &mut new_parts[rule.variable as usize];
|
||||
let checked_parts_var = &mut checked_parts[rule.variable as usize];
|
||||
match rule.operation {
|
||||
RuleConditionOperation::Less => {
|
||||
new_parts_var.end = rule.argument;
|
||||
checked_parts_var.start = rule.argument;
|
||||
}
|
||||
RuleConditionOperation::Greater => {
|
||||
new_parts_var.start = rule.argument + 1;
|
||||
checked_parts_var.end = rule.argument + 1;
|
||||
}
|
||||
}
|
||||
if new_parts_var.start < new_parts_var.end {
|
||||
options += count_ranges_options(&new_parts, rule.result);
|
||||
}
|
||||
if checked_parts_var.start >= checked_parts_var.end {
|
||||
return options;
|
||||
}
|
||||
} else {
|
||||
return options + count_ranges_options(&checked_parts, rule.result);
|
||||
}
|
||||
workflow_index += 1;
|
||||
}
|
||||
panic!("No rules for remaining ranges");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut workflows: HashMap<&str, Vec<Rule>> = HashMap::new();
|
||||
let mut parts: Vec<[i32; 4]> = vec![];
|
||||
let mut currently_parsing_rules = true;
|
||||
let rule_re = Regex::new("(?:([xmas])([><])([0-9]+):)?([a-zAR]+),?").unwrap();
|
||||
let part_re = Regex::new("\\{x=([0-9]+),m=([0-9]+),a=([0-9]+),s=([0-9]+)}").unwrap();
|
||||
for line in input_str.lines() {
|
||||
if currently_parsing_rules {
|
||||
let mut workflow_key: &str = "";
|
||||
let mut rules: Vec<Rule> = vec![];
|
||||
for captures in rule_re.captures_iter(line) {
|
||||
if workflow_key.is_empty() {
|
||||
workflow_key = captures.get(4).unwrap().as_str();
|
||||
} else {
|
||||
if let Some(_) = captures.get(1) {
|
||||
rules.push(Rule {
|
||||
variable: match captures[1].as_bytes()[0] {
|
||||
b'x' => RuleConditionVariable::X,
|
||||
b'm' => RuleConditionVariable::M,
|
||||
b'a' => RuleConditionVariable::A,
|
||||
b's' => RuleConditionVariable::S,
|
||||
_ => RuleConditionVariable::None
|
||||
},
|
||||
operation: match captures[2].as_bytes()[0] {
|
||||
b'<' => RuleConditionOperation::Less,
|
||||
_ => RuleConditionOperation::Greater
|
||||
},
|
||||
argument: captures[3].parse::<i32>().unwrap(),
|
||||
result: captures.get(4).unwrap().as_str(),
|
||||
});
|
||||
} else {
|
||||
rules.push(Rule {
|
||||
variable: RuleConditionVariable::None,
|
||||
operation: RuleConditionOperation::Less,
|
||||
argument: 0,
|
||||
result: captures.get(4).unwrap().as_str(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if workflow_key.is_empty() {
|
||||
currently_parsing_rules = false;
|
||||
continue;
|
||||
} else {
|
||||
// Remove useless conditions (those that give the same result as the last)
|
||||
while rules.len() > 1 {
|
||||
if rules[rules.len() - 1].variable == RuleConditionVariable::None
|
||||
&& rules[rules.len() - 1].result == rules[rules.len() - 2].result {
|
||||
rules.remove(rules.len() - 2);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
workflows.insert(workflow_key, rules);
|
||||
}
|
||||
} else {
|
||||
if let Some(capture) = part_re.captures(line) {
|
||||
let mut part = [0; 4];
|
||||
for (i, re_match) in capture.iter().skip(1).enumerate() {
|
||||
part[i] = re_match.unwrap().as_str().parse::<i32>().unwrap();
|
||||
}
|
||||
parts.push(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
let sum1 = parts.iter()
|
||||
.filter(|&part| check_part(&workflows, part))
|
||||
.fold(0, |acc, part| acc + part.iter().sum::<i32>());
|
||||
let sum2 = count_options(&workflows, "in", &[(1..4001), (1..4001), (1..4001), (1..4001)]);
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum1: {}", sum2);
|
||||
}
|
92
day20/Cargo.lock
generated
Normal file
92
day20/Cargo.lock
generated
Normal file
@@ -0,0 +1,92 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "day20"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
18
day20/Cargo.toml
Normal file
18
day20/Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "day20"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "sane"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
num = "0.4.1"
|
||||
|
||||
[[bin]]
|
||||
name = "oop"
|
||||
path= "src/main_oop.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "sane"
|
||||
path= "src/main_sane.rs"
|
58
day20/input.txt
Normal file
58
day20/input.txt
Normal file
@@ -0,0 +1,58 @@
|
||||
%vb -> ck
|
||||
%pb -> xv
|
||||
> -> jq
|
||||
%hj -> lk, hh
|
||||
%zd -> fm
|
||||
%hr -> hh
|
||||
%rg -> tp
|
||||
%tf -> ck, tx
|
||||
%pp -> vs, hh
|
||||
%vx -> df
|
||||
%tx -> mr, ck
|
||||
%nh -> vx
|
||||
%sc -> ck, vb
|
||||
%cc -> ck, rj
|
||||
%tn -> kz, lt
|
||||
%fp -> rb
|
||||
%hc -> kz
|
||||
%rb -> ns, mf
|
||||
%pc -> vh
|
||||
broadcaster -> tf, br, zn, nc
|
||||
%zn -> kz, fv
|
||||
&ns -> pb, lr, br, fp, gp, gv, jl
|
||||
%nc -> hh, hj
|
||||
%mf -> ns, gp
|
||||
%xv -> ns, kh
|
||||
%rj -> ck, sc
|
||||
%tg -> cc
|
||||
%gp -> pb
|
||||
%jz -> lj, ns
|
||||
%jl -> fp
|
||||
&vr -> jq
|
||||
&jq -> rx
|
||||
&kz -> zf, nl, df, zn, vx, nh
|
||||
%gv -> jl
|
||||
%gf -> zf, kz
|
||||
%df -> gf
|
||||
%kq -> pp
|
||||
%lk -> hh, zd
|
||||
%vs -> bp
|
||||
%lt -> ls, kz
|
||||
&nl -> jq
|
||||
%mr -> rg
|
||||
%zf -> qf
|
||||
%br -> gv, ns
|
||||
%rk -> hh, hr
|
||||
%qf -> kz, tn
|
||||
%rv -> rk, hh
|
||||
%ls -> hc, kz
|
||||
%fm -> kq
|
||||
&ck -> tp, vr, pc, tg, mr, tf, rg
|
||||
%fv -> nh, kz
|
||||
%tp -> pc
|
||||
%vh -> ck, tg
|
||||
&hh -> vs, kq, gt, nc, zd, fm
|
||||
&lr -> jq
|
||||
%kh -> ns, jz
|
||||
%bp -> hh, rv
|
||||
%lj -> ns
|
92
day20/input_part2_analysis.txt
Normal file
92
day20/input_part2_analysis.txt
Normal file
@@ -0,0 +1,92 @@
|
||||
The input of rx is conjunction of hh, ck, kz, ns (truth = low pulse)
|
||||
&jq -> rx
|
||||
|
||||
> -> jq
|
||||
&vr -> jq
|
||||
&nl -> jq
|
||||
&lr -> jq
|
||||
|
||||
|
||||
Counter 1
|
||||
&hh -> nc, zd, vs, kq, fm | -> gt
|
||||
|
||||
%nc -> hj, hh | <- hh, broadcast
|
||||
%hj -> lk, hh
|
||||
%lk -> zd, hh
|
||||
%zd -> fm | <- hh
|
||||
%fm -> kq | <- hh
|
||||
%kq -> pp | <- hh
|
||||
%pp -> vs, hh
|
||||
%vs -> bp | <- hh
|
||||
%bp -> rv, hh
|
||||
%rv -> rk, hh
|
||||
%rk -> hr, hh
|
||||
%hr -> hh
|
||||
|
||||
111101000111(2) = 3911
|
||||
|
||||
|
||||
Counter 2
|
||||
&ck -> tf, mr, rg, tp, pc, tg | -> vr
|
||||
|
||||
%tf -> tx, ck | <- broadcast, ck
|
||||
%tx -> mr, ck
|
||||
%mr -> rg | <- ck
|
||||
%rg -> tp | <- ck
|
||||
%tp -> pc | <- ck
|
||||
%pc -> vh | <- ck
|
||||
%vh -> tg, ck
|
||||
%tg -> cc | <- ck
|
||||
%cc -> rj, ck
|
||||
%rj -> sc, ck
|
||||
%sc -> vb, ck
|
||||
%vb -> ck
|
||||
|
||||
111101000011(2) = 3907
|
||||
|
||||
|
||||
Counter 3
|
||||
&kz -> zn, nh, vx, df, zf | -> nl
|
||||
|
||||
%zn -> fv, kz | <- broadcast, kz
|
||||
%fv -> nh, kz
|
||||
%nh -> vx | <- kz
|
||||
%vx -> df | <- kz
|
||||
%df -> gf | <- kz
|
||||
%gf -> zf, kz
|
||||
%zf -> qf | <- kz
|
||||
%qf -> tn, kz
|
||||
%tn -> lt, kz
|
||||
%lt -> ls, kz
|
||||
%ls -> hc, kz
|
||||
%hc -> kz
|
||||
|
||||
111110100011(2) = 4003
|
||||
|
||||
|
||||
Counter 4
|
||||
&ns -> pb, br, fp, gp, gv, jl | -> lr
|
||||
|
||||
%br -> gv, ns | <- broadcast
|
||||
%gv -> jl
|
||||
%jl -> fp
|
||||
%fp -> rb
|
||||
%rb -> mf, ns
|
||||
%mf -> gp, ns
|
||||
%gp -> pb
|
||||
%pb -> xv
|
||||
%xv -> kh, ns
|
||||
%kh -> jz, ns
|
||||
%jz -> lj, ns
|
||||
%lj -> ns
|
||||
|
||||
111100110001(2) = 3889
|
||||
|
||||
The broadcast node drives all the counters
|
||||
broadcaster -> nc, tf, zn, br
|
||||
|
||||
Period of rx (same as first activation) is LCM of periods of all counters
|
||||
LCM = 237878264003759
|
||||
|
||||
|
||||
|
213
day20/src/main_oop.rs
Normal file
213
day20/src/main_oop.rs
Normal file
@@ -0,0 +1,213 @@
|
||||
use std::cmp;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
// Object-oriented, polymorphic way of implementing it,
|
||||
// does less than main_sane.rs (only part 1) with more lines of code
|
||||
|
||||
struct Pulse {
|
||||
src: u16,
|
||||
dest: u16,
|
||||
high: bool,
|
||||
}
|
||||
|
||||
trait Module {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>);
|
||||
fn add_input(&mut self, id: u16);
|
||||
fn add_output(&mut self, id: u16);
|
||||
}
|
||||
|
||||
struct ModuleBase {
|
||||
inputs: Vec<u16>,
|
||||
outputs: Vec<u16>,
|
||||
id: u16,
|
||||
}
|
||||
|
||||
impl ModuleBase {
|
||||
fn new(id: u16) -> ModuleBase {
|
||||
ModuleBase {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.inputs.push(id);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.outputs.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct BroadcastModule {
|
||||
base: ModuleBase,
|
||||
}
|
||||
|
||||
impl BroadcastModule {
|
||||
fn new(id: u16) -> BroadcastModule {
|
||||
BroadcastModule {
|
||||
base: ModuleBase::new(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for BroadcastModule {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
queue.extend(self.base.outputs.iter().map(
|
||||
|&id| Pulse { src: self.base.id, dest: id, high: pulse.high }));
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.base.add_input(id);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.base.add_output(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct FlipFlopModule {
|
||||
base: ModuleBase,
|
||||
on: bool,
|
||||
}
|
||||
|
||||
impl FlipFlopModule {
|
||||
fn new(id: u16) -> FlipFlopModule {
|
||||
FlipFlopModule {
|
||||
base: ModuleBase::new(id),
|
||||
on: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for FlipFlopModule {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
if !pulse.high {
|
||||
self.on = !self.on;
|
||||
queue.extend(self.base.outputs.iter().map(
|
||||
|&id| Pulse { src: self.base.id, dest: id, high: self.on }));
|
||||
}
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.base.add_input(id);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.base.add_output(id);
|
||||
}
|
||||
}
|
||||
|
||||
struct ConjunctionModule {
|
||||
base: ModuleBase,
|
||||
memory: Vec<bool>,
|
||||
}
|
||||
|
||||
impl ConjunctionModule {
|
||||
fn new(id: u16) -> ConjunctionModule {
|
||||
ConjunctionModule {
|
||||
base: ModuleBase::new(id),
|
||||
memory: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Module for ConjunctionModule {
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
if let Some(pos) = self.base.inputs.iter().position(|&id| id == pulse.src) {
|
||||
self.memory[pos] = pulse.high;
|
||||
let out_high = !self.memory.iter().all(|&v| v);
|
||||
queue.extend(self.base.outputs.iter().map(
|
||||
|&id| Pulse { src: self.base.id, dest: id, high: out_high }));
|
||||
}
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.base.add_input(id);
|
||||
self.memory.push(false);
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.base.add_output(id);
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_module_name(name: &str) -> u16 {
|
||||
let bytes = &name.as_bytes()[0..cmp::min(name.as_bytes().len(), 3)];
|
||||
let mut acc = 0u16;
|
||||
for &c in bytes {
|
||||
acc = acc * 26 + (c - b'a') as u16;
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut modules: HashMap<u16, Box<dyn Module>> = HashMap::new();
|
||||
// let rx_id = encode_module_name("rx");
|
||||
// modules.insert(rx_id, Box::new(FlipFlopModule::new(rx_id)));
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let name = split_whitespace.next().unwrap();
|
||||
let new_module: Box<dyn Module>;
|
||||
let id = encode_module_name(&name[1..]);
|
||||
match name.as_bytes()[0] {
|
||||
b'%' => new_module = Box::new(FlipFlopModule::new(id)),
|
||||
b'&' => new_module = Box::new(ConjunctionModule::new(id)),
|
||||
_ => new_module = Box::new(BroadcastModule::new(id))
|
||||
}
|
||||
modules.insert(id, new_module);
|
||||
}
|
||||
for line in input_str.lines() {
|
||||
let mut split = line.split([' ', ',']).
|
||||
filter(|&v| !v.is_empty());
|
||||
let name = split.next().unwrap();
|
||||
let in_id = encode_module_name(&name[1..]);
|
||||
split.next();
|
||||
while let Some(name) = split.next() {
|
||||
let id = encode_module_name(name);
|
||||
modules.get_mut(&in_id).unwrap().add_output(id);
|
||||
match modules.get_mut(&id) {
|
||||
None => {}
|
||||
Some(in_module) => {
|
||||
in_module.add_input(in_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let broadcast_id = encode_module_name("roadcast");
|
||||
let mut low_pulses = 0u64;
|
||||
let mut high_pulses = 0u64;
|
||||
let mut queue: VecDeque<Pulse> = VecDeque::new();
|
||||
for _ in 0..1000 {
|
||||
let mut low_pulses_step = 0;
|
||||
let mut high_pulses_step = 0;
|
||||
queue.push_back(Pulse {src: u16::MAX, dest: broadcast_id, high: false});
|
||||
while !queue.is_empty() {
|
||||
let pulse = queue.pop_front().unwrap();
|
||||
match pulse.high {
|
||||
true => high_pulses_step += 1,
|
||||
false => low_pulses_step += 1
|
||||
}
|
||||
match modules.get_mut(&pulse.dest) {
|
||||
None => {}
|
||||
Some(module) => {
|
||||
module.handle_pulse(pulse, &mut queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
low_pulses += low_pulses_step;
|
||||
high_pulses += high_pulses_step;
|
||||
}
|
||||
let result1 = low_pulses * high_pulses;
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Result1: {}", result1);
|
||||
}
|
192
day20/src/main_sane.rs
Normal file
192
day20/src/main_sane.rs
Normal file
@@ -0,0 +1,192 @@
|
||||
use std::cmp;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
use num::integer::lcm;
|
||||
|
||||
struct Pulse {
|
||||
src: u16,
|
||||
dest: u16,
|
||||
high: bool,
|
||||
}
|
||||
|
||||
enum ModuleKind {
|
||||
Broadcast,
|
||||
FlipFlop(bool),
|
||||
Conjunction(Vec<bool>),
|
||||
}
|
||||
|
||||
struct Module {
|
||||
inputs: Vec<u16>,
|
||||
outputs: Vec<u16>,
|
||||
id: u16,
|
||||
kind: ModuleKind,
|
||||
}
|
||||
|
||||
impl Module {
|
||||
fn new(id: u16, kind: ModuleKind) -> Module {
|
||||
Module {
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
id,
|
||||
kind,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_broadcast(id: u16) -> Module {
|
||||
Module::new(id, ModuleKind::Broadcast)
|
||||
}
|
||||
|
||||
fn new_flipflop(id: u16) -> Module {
|
||||
Module::new(id, ModuleKind::FlipFlop(false))
|
||||
}
|
||||
|
||||
fn new_conjunction(id: u16) -> Module {
|
||||
Module::new(id, ModuleKind::Conjunction(vec![]))
|
||||
}
|
||||
|
||||
fn add_input(&mut self, id: u16) {
|
||||
self.inputs.push(id);
|
||||
match self.kind {
|
||||
ModuleKind::Conjunction(ref mut memory) => {
|
||||
memory.push(false);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_output(&mut self, id: u16) {
|
||||
self.outputs.push(id);
|
||||
}
|
||||
|
||||
fn handle_pulse(&mut self, pulse: Pulse, queue: &mut VecDeque<Pulse>) {
|
||||
match self.kind {
|
||||
ModuleKind::Broadcast => {
|
||||
queue.extend(self.outputs.iter().map(
|
||||
|&id| Pulse { src: self.id, dest: id, high: pulse.high }));
|
||||
}
|
||||
ModuleKind::FlipFlop(ref mut on) => {
|
||||
if !pulse.high {
|
||||
*on = !*on;
|
||||
queue.extend(self.outputs.iter().map(
|
||||
|&id| Pulse { src: self.id, dest: id, high: *on }));
|
||||
}
|
||||
}
|
||||
ModuleKind::Conjunction(ref mut memory) => {
|
||||
if let Some(pos) = self.inputs.iter().position(|&id| id == pulse.src) {
|
||||
memory[pos] = pulse.high;
|
||||
let out_high = !memory.iter().all(|&v| v);
|
||||
queue.extend(self.outputs.iter().map(
|
||||
|&id| Pulse { src: self.id, dest: id, high: out_high }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_module_name(name: &str) -> u16 {
|
||||
let bytes = &name.as_bytes()[0..cmp::min(name.as_bytes().len(), 3)];
|
||||
let mut acc = 0u16;
|
||||
for &c in bytes {
|
||||
acc = acc * 26 + (c - b'a') as u16;
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut modules: HashMap<u16, Module> = HashMap::new();
|
||||
// let rx_id = encode_module_name("rx");
|
||||
// modules.insert(rx_id, Module::new_flipflop(rx_id));
|
||||
for line in input_str.lines() {
|
||||
let mut split_whitespace = line.split_whitespace();
|
||||
let name = split_whitespace.next().unwrap();
|
||||
let new_module: Module;
|
||||
let id = encode_module_name(&name[1..]);
|
||||
match name.as_bytes()[0] {
|
||||
b'%' => new_module = Module::new_flipflop(id),
|
||||
b'&' => new_module = Module::new_conjunction(id),
|
||||
_ => new_module = Module::new_broadcast(id)
|
||||
}
|
||||
modules.insert(id, new_module);
|
||||
}
|
||||
for line in input_str.lines() {
|
||||
let mut split = line.split([' ', ',']).
|
||||
filter(|&v| !v.is_empty());
|
||||
let name = split.next().unwrap();
|
||||
let in_id = encode_module_name(&name[1..]);
|
||||
split.next();
|
||||
while let Some(name) = split.next() {
|
||||
let id = encode_module_name(name);
|
||||
modules.get_mut(&in_id).unwrap().add_output(id);
|
||||
match modules.get_mut(&id) {
|
||||
None => {}
|
||||
Some(in_module) => {
|
||||
in_module.add_input(in_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Part 1
|
||||
let broadcast_id = encode_module_name("roadcast");
|
||||
let mut low_pulses = 0u64;
|
||||
let mut high_pulses = 0u64;
|
||||
let mut queue: VecDeque<Pulse> = VecDeque::new();
|
||||
for _ in 0..1000 {
|
||||
let mut low_pulses_step = 0;
|
||||
let mut high_pulses_step = 0;
|
||||
queue.push_back(Pulse { src: u16::MAX, dest: broadcast_id, high: false });
|
||||
while !queue.is_empty() {
|
||||
let pulse = queue.pop_front().unwrap();
|
||||
match pulse.high {
|
||||
true => high_pulses_step += 1,
|
||||
false => low_pulses_step += 1
|
||||
}
|
||||
match modules.get_mut(&pulse.dest) {
|
||||
None => {}
|
||||
Some(module) => {
|
||||
module.handle_pulse(pulse, &mut queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
low_pulses += low_pulses_step;
|
||||
high_pulses += high_pulses_step;
|
||||
}
|
||||
let result1 = low_pulses * high_pulses;
|
||||
// Part 2
|
||||
// Use the knowledge of the network, that it is that broadcast drives a series of counters
|
||||
let mut counter_periods: Vec<u64> = vec![];
|
||||
for &node in &modules.get(&broadcast_id).unwrap().outputs {
|
||||
let mut period = 0u16;
|
||||
let mut current_node = node;
|
||||
let mut bits = 0;
|
||||
loop {
|
||||
bits += 1;
|
||||
let mut next_id = current_node;
|
||||
period >>= 1;
|
||||
let outputs = &modules.get(¤t_node).unwrap().outputs;
|
||||
for &output_id in outputs {
|
||||
match modules.get(&output_id).unwrap().kind {
|
||||
ModuleKind::Conjunction(_) => period |= 0x8000,
|
||||
_ => next_id = output_id
|
||||
}
|
||||
}
|
||||
if next_id == current_node {
|
||||
break;
|
||||
} else {
|
||||
current_node = next_id;
|
||||
}
|
||||
}
|
||||
period >>= 16 - bits;
|
||||
counter_periods.push(period as u64);
|
||||
}
|
||||
let result2 = counter_periods.iter().fold(1u64, |acc, &v| lcm(acc, v));
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Result1: {}", result1);
|
||||
println!("Result2: {}", result2);
|
||||
}
|
7
day21/Cargo.lock
generated
Normal file
7
day21/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day21"
|
||||
version = "0.1.0"
|
8
day21/Cargo.toml
Normal file
8
day21/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day21"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
131
day21/input.txt
Normal file
131
day21/input.txt
Normal file
@@ -0,0 +1,131 @@
|
||||
...................................................................................................................................
|
||||
.#........#.#.........#................##.#.............#....................#....#....#.#...#.......#..........#........#.........
|
||||
....#......#.....................##...#.#....#.#..#...#.......................#.....#..........##....#..#........#.##..#..#...#....
|
||||
.#.....#.............#.#...............#...........#.#.#................#...........#.#.....#.......##......#........#.#...........
|
||||
.....#...........#.......##.#.#..........#....#....#..#.#..................................#....##...#.#.....#..#.......#...#...#..
|
||||
...#....##............#...#..#.....#....##....#....##...........#...............#..##..#..............#..#......#.....#............
|
||||
..##....#.........#.......#..#...#...........................................#.....#.#........#...#.......................#.....#..
|
||||
..##.#........#..........#......#...#.....#..#.......#........................#..........##......#...#.#..............#......#.....
|
||||
........#....##.................................#.##.........#.......#........#...#..#.....................#.#.##....#.........#...
|
||||
.#...............#....#..........#....#.#...........................................................#.#.....#...#...#.........#....
|
||||
..#........#.##..............#...##.....#..#...#....................................#..##......#..#.......#........................
|
||||
...........................................#.................#.#..................#..#..#..#....#..#................#..........#...
|
||||
.....#...#...#.#......#.....#.#.....#.#..#........................#..#.##...................#.................................#.#..
|
||||
......#...........#.........##....#.#.#....#..............#........#....................#.............#..##...#.............#......
|
||||
..#...........##....#......#..#........................#.#........#..#...#...........#............................#.#............#.
|
||||
.#....#..#......#..........................#.......................#....#...........#......#.......#...............................
|
||||
....#.#...##....#.........#....#...#.#..#............................#.......#...............................................#..#..
|
||||
.......#..........##......#..#...#.....#............#...#...................#...............#..#..................#.....#..#...#...
|
||||
..................#.........#....#.#....#..#....................#..................................................................
|
||||
.#.##.................#....#..#.......##.#.................#.#............#...#..........#.#...#.........##.#...............#......
|
||||
..#........#.....#.#.........#.#.....#..#........#...#.....#....#....#.....................##....#...............................#.
|
||||
..#...#....#.#.............#..#..#...............##.......##.........#.....................................#....###.....##....#....
|
||||
....#..####.....#....................#................#.......#.............#..#..#..........##......##.......#...........#........
|
||||
..........##..#........#.......#..............#.#......#..#....#.............#...#................#......##...#..#......#..........
|
||||
......#....#...#........#.............................##..#.....#..............#.#......................................##.#...#...
|
||||
.#..........................................#.......#...#.##..#............#.......................#.#...##........................
|
||||
............#.#...........#.....#....................##...#...#....#.................#.#.........#......#........#......#...#......
|
||||
.#.....##.#..#..........#....##............#...........#.#.....#.......#............#.#............#...............................
|
||||
.........#........#...#.###.....#.........#.#...##.##....##..........#................................#..........#...##...#........
|
||||
...........#.........##...#.#..................................................#.........#..................#.........#.......#....
|
||||
....##...#..#.#..#.......................#....#......#............#....#.........###......#..............#.......#...#..........#..
|
||||
...........#.......#......#...............................#.....#.......#..#...............#.........##........#.#.........#.......
|
||||
......#....#.................#..............#..#..........#...#........................##..............#.........................#.
|
||||
.###.##...#.##........#........................#.#.###................#...#.#....#...........#...............##.........#..........
|
||||
...........................................#.........#..##.................#...#.#.#..##..#............#.#.#.....##.....#..........
|
||||
.#............................................#..#............#....#...#...#......#.#..........................#....#.#..........#.
|
||||
...........#...........#................#........#..........#........#...........#..............#.........#....##....#....#...##.#.
|
||||
................#............................#...#......#.....................#..............#.........................##..#...#...
|
||||
...#....#.............................................#..................#.....#.#..#.....#................#.......#....#..........
|
||||
.#....##..#.#.......#.............#..............#...#..#....................#..#........#.#.......................................
|
||||
.#...#.......................................................#..........#.........#.......##...#.#.#............###............#.#.
|
||||
.....#.....#......#..............#.#...............#....#.....................#......#....#.#........#.........#....#.........#....
|
||||
............#.#.###.......................................................#...................#....#...#.......##............#.....
|
||||
.#......#..............................#..........#....#....#.#.#........#............#.....#........................#......#......
|
||||
................#......................##.......#.......#..#..............##...................#...#...#...........................
|
||||
.#...#..................#.......................#...#...#..........#.......#.......#...................##...................#......
|
||||
........#...............#...#....................#..#.......................#.............#.#.#..........#..........###........#.#.
|
||||
.#..##...#..#............#.....#.....................#......#..............#......#..#..............#.....................#........
|
||||
....#...###.....................###..........#....#....#..............#................#.#.......#.#....##............#......#.#...
|
||||
......#.....................#.......#.#.#...#....#...#.#.....#..#........##.#..#..#......##........................................
|
||||
.......#.#............#...........#........#..............#....##..##..................##..........#...........#.......#..#..#...#.
|
||||
..#..#......................#..................................#....#......#...#............##......#......................##...#..
|
||||
.#...............................#.#.........#.....................###.#..................##.#...#.......#....................#..#.
|
||||
......##................#.........#......#................#........#.....#....#.#.##..#..#...##...#.#...........#................#.
|
||||
..#..#.........#...............##..................#........................................#........#......##.....................
|
||||
...................#....#......#...................#.#.....#..............#....##................#......#...#......#.........#.....
|
||||
....#...........#.......#......#..........#.....................#..#.........##.....##...........###......##.......................
|
||||
.................#..#....#..##.........................................#......#..........#............#..#....#.................#..
|
||||
.............#..#........#..#..#.#.......#..........#...........#..#.........#.#...................###.....#.......................
|
||||
..#............#..#..#..#..................#.##.#...#.#...#............###......#........................#.........#..#.........#..
|
||||
...........#..##.#..#.............#...#.............#.........#.....#.......#..................#...##..##......#...#..#............
|
||||
..............#...#...#.....##....#.#........#................#.....#.....#......#.......##....#.....#......#..#....#..............
|
||||
.............#....#..##..#.................#....#.#......#.#......#...##.....#....###.......#.......#..............................
|
||||
............................#..........#.......#................#....#.........#.......#.#..................#......................
|
||||
..........#...#.......#......................................##..........#..#......#............#..............#.....#..#..........
|
||||
.................................................................S.................................................................
|
||||
................#.........#.....#........#......................#....#.#.............#....#...#.............#...........#..........
|
||||
.........................................#......#............#...........#.......#......#..##.........##.............#.............
|
||||
........#................#.......#..........#.....#..........#........#.................##......#.............#.....#.....#........
|
||||
........#........#......#.......#....#...##.....................#.........#.....#.........#.................#..#...................
|
||||
.............#............................#.......#......#...##.........##...#......#.....#.#...#....................#.............
|
||||
..................................................#......#.......................#..##..#...##........#.#........#.................
|
||||
.#...........#..#.......#.....#...............#...#.....#..........#...#.#.#.......#.#..........................#.#................
|
||||
.####...............#...........#......#..#...................#....#....#...........#...#...................#.................#.#..
|
||||
...............#......#.##...............##..#..#........#..........#.#.............##......#............#...#.....#............#..
|
||||
.......................#.....###..#....#..#........................................#.#.............#...#........#..................
|
||||
.....................##....#...............#.........#....#.####...#......#.................#.#...........#......##..........#.#...
|
||||
..................#.................###...#............................#.#...##..#.#.#..#...#.................................#..#.
|
||||
....................#..........#..............#............................#.......#.........................#................#....
|
||||
.#..#...............#.........#..#..........#...#..........##.......##.##.....#....#...#.#......#...##.#...........................
|
||||
....#...............#....#.............................#.....#.........#..............#......#..............#............#.......#.
|
||||
........................#...........#..........#...#............#...#.#....#.............##..............##.#...................#..
|
||||
...#..................#.#...#...#.........#...........#.....#...#.##........#.#....#..........#.......##...........................
|
||||
.........#.#..........##.#....................#....#................#..#.#.....#...........#.........####.............#.......##...
|
||||
.#......#...................#........#.......#........#...#..#..........#..##..#..........#........................................
|
||||
.....#....#..#................##.....#......#.........................#.###...................#..#................#..#......#......
|
||||
..............#..........................................#.........#.....##.###............#...##.....................##...........
|
||||
..#......#..#.#.#.........#...#....................#.........#.........#......#...#.....................................#..........
|
||||
.......#...#.................#..........................#...##..#...#.#.........##............#..................#...............#.
|
||||
....#.........#.............#.......#.#..........#................#..##.#.#.#...................#.....#............#.....##....#...
|
||||
.###...............................#.........#..............#.#......#......#.....##.#.#.......#................#.#..............#.
|
||||
...#........#......#........................#.......#.##...#.........#........#...#.......#..##....#...........#....#..##..........
|
||||
......#.......#........#.......#..#...#....#.......#....#.#..........##........#..#...............#.......................##..#....
|
||||
...................#....#..........#........#.............#...#...##...#..........#.......#...#............#..........##...........
|
||||
.#........##......#.#................#.....#..........#....###................#.....#.......###...............#...#..........#..#..
|
||||
...#.........#...#....#............#..................##....#......#.....#.......#..........#...#...........#.....#..#.......#.....
|
||||
........#.................#........#.........#...............#...........#.##...##.......#..................#.......#....##........
|
||||
.###......#.....#......#.....................##..#...#........#........#....#................................#....#.....#.#........
|
||||
...........##..............................#..#...........#....#...#......#.#..#......#...............#............................
|
||||
.....#.#..#.........#............................#.....#.#.##......#.#.........#.....#.#...........................#...##......#.#.
|
||||
..............#.#.#.....#.#.............#..#.#.....#....#..#.#....#.................#....................#..........#........#.....
|
||||
..........#.....##.......#................#....................................#..#......#.........#..............#...#......##....
|
||||
.##.#......###..............#.#...............###......#.................#.......#......#.............................#....#.#.....
|
||||
..#..#...#............#....##.............#........................#.#..................................#......................#...
|
||||
......#.....#.............#...#............#....#.......#.....#.................................#..##...#.#..............#.........
|
||||
...........#..........#..#.#..................##...........#.......#........#....#.............#....................#.....#........
|
||||
....#...........#........##........................................#.#...............#.............#.#...##...#........#...........
|
||||
...#..#..............................................................#...#.#...#..#...........#..#..#....#..#..#.......#..#........
|
||||
...................#.#.....##...........................#................#.#...#...........#.............................#.........
|
||||
.....###.........#.....#...#...##...#..#........###.....#..#..............#.....#...................#...#...........#...#..........
|
||||
..............#......................................#..#....#.........##....##..#.......#.......................#.....##..........
|
||||
..#...................#...........#................................#.....#.#.#..........................#....#......#......#.......
|
||||
..#......#....#..##..#....#............#...........###........................#.........#........#........#............#.........#.
|
||||
...................#.##...........#....#..##............#...................#.........#........##........#...........#.#...........
|
||||
...#.#......#....#........#.......#....................................#.##..#.........#....#.#.....#.........................#..#.
|
||||
....#.#...#...........................................#...#..#....#....#..............#.........................#.....#......#..#..
|
||||
......#..................#..........#..#....#.......................#...............#...........#..............#....#.#............
|
||||
.#..............#........##......#...#....#...#.#................................................#.....##....#...##...#.#........#.
|
||||
.........#.............#..#..#...........................#.............#...........................#....##............#............
|
||||
..........#...#.....#..#...#...........#.#.......#........#.....................#.....#.....#...#.#..#......#....#....#...#..#.....
|
||||
.#........#............##.................##...............#.....................#.##.................#........#......#............
|
||||
....#........##....#..#.#.........#................................#................#.#.....#.............#..#....##.#....##.......
|
||||
........#.#.....#.......#.#..##..............##...................#...................#..#....................#..#.......#...#.##..
|
||||
.....#.#.........#.#....###..#..#.......#.....#................#....#........#.....................#.###.....#...........#......#..
|
||||
......#...#................#..#...##............#......#...................#............................#.........#....##...##.....
|
||||
..........#...##.....#....#...........#.....#......#..#.......................##...#.##.....#...#..##...#...#..#..#..........#...#.
|
||||
......#............#...........#.#..#...............#.............................#..#.......#...#.................#.......#....#..
|
||||
..............#........#............#....#.....##...#.###...................#............#..#.#..................#.............#...
|
||||
.............#....#.......#..#......#....#...#..#.......##.............#.##...#.........#..........................#.#...........#.
|
||||
.#..............#...#......#.......#..#................#.#.............#....#...............#.......#..............................
|
||||
...................................................................................................................................
|
267
day21/src/main.rs
Normal file
267
day21/src/main.rs
Normal file
@@ -0,0 +1,267 @@
|
||||
use std::mem;
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
// Solution to part 1 and helper for part 2
|
||||
fn count_options_basic(layout: &Vec<&[u8]>, start_pos: (i32, i32), steps: i32) -> u64 {
|
||||
count_options_basic_cont(layout, start_pos, steps, false)
|
||||
}
|
||||
|
||||
// Like count_options_basic but can begin as if we're already on an odd number
|
||||
fn count_options_basic_cont(layout: &Vec<&[u8]>, start_pos: (i32, i32), steps: i32, count_odd: bool) -> u64 {
|
||||
if steps < 0 {
|
||||
return 0;
|
||||
}
|
||||
let modulo_equal = (steps + if count_odd { 1 } else { 0 }) % 2;
|
||||
let width = layout[0].len();
|
||||
let height = layout.len();
|
||||
let mut visited: Vec<Vec<bool>> = vec![vec![false; width]; height];
|
||||
let mut tile_queue: Vec<(i32, i32)> = vec![start_pos];
|
||||
visited[start_pos.1 as usize][start_pos.0 as usize] = true;
|
||||
let mut sum = (1 - modulo_equal) as u64;
|
||||
let mut next_tile_queue: Vec<(i32, i32)> = vec![];
|
||||
for step in 1..=steps {
|
||||
let mut try_tile = |x: i32, y: i32| {
|
||||
if layout[y as usize][x as usize] != b'#' {
|
||||
if !visited[y as usize][x as usize] {
|
||||
visited[y as usize][x as usize] = true;
|
||||
next_tile_queue.push((x, y));
|
||||
if step % 2 == modulo_equal {
|
||||
sum += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
for &(x, y) in &tile_queue {
|
||||
if x > 0 {
|
||||
try_tile(x - 1, y);
|
||||
}
|
||||
if x < width as i32 - 1 {
|
||||
try_tile(x + 1, y);
|
||||
}
|
||||
if y > 0 {
|
||||
try_tile(x, y - 1);
|
||||
}
|
||||
if y < height as i32 - 1 {
|
||||
try_tile(x, y + 1);
|
||||
}
|
||||
}
|
||||
if next_tile_queue.is_empty() {
|
||||
break;
|
||||
}
|
||||
tile_queue.clear();
|
||||
mem::swap(&mut tile_queue, &mut next_tile_queue);
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
// Not used in the end but helped figure out the better solution, also has commented visualisation
|
||||
fn count_options_infinite_naive(layout: &Vec<&[u8]>, start_pos: (i32, i32), steps: i32) -> u64 {
|
||||
if steps < 0 {
|
||||
return 0;
|
||||
}
|
||||
let modulo_equal = steps % 2;
|
||||
// Assuming square
|
||||
let chunk_width = layout.len() as i32;
|
||||
let chunk_reach = (steps + chunk_width / 2) / chunk_width + 1;
|
||||
#[derive(Clone)]
|
||||
struct Chunk {
|
||||
visited: Vec<Vec<bool>>,
|
||||
solution: i32,
|
||||
}
|
||||
impl Chunk {
|
||||
fn new(width: usize, height: usize) -> Chunk {
|
||||
Chunk {
|
||||
visited: vec![vec![false; width]; height],
|
||||
solution: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
let chunk_offset = chunk_reach - 1;
|
||||
let chunks_size = chunk_reach * 2 - 1;
|
||||
let mut chunks: Vec<Vec<Chunk>> = vec![vec![Chunk::new(chunk_width as usize, chunk_width as usize); chunks_size as usize]; chunks_size as usize];
|
||||
let mut tile_queue: Vec<(i32, i32)> = vec![start_pos];
|
||||
let mut sum = 0;
|
||||
let mut next_tile_queue: Vec<(i32, i32)> = vec![];
|
||||
for step in 1..=steps {
|
||||
let mut try_tile = |x: i32, y: i32| {
|
||||
let mut chunk_x = if x < 0 { (x - chunk_width + 1) / chunk_width } else { x / chunk_width };
|
||||
let mut chunk_y = if y < 0 { (y - chunk_width + 1) / chunk_width } else { y / chunk_width };
|
||||
let inside_x = (x - chunk_x * chunk_width) as usize;
|
||||
let inside_y = (y - chunk_y * chunk_width) as usize;
|
||||
chunk_x += chunk_offset;
|
||||
chunk_y += chunk_offset;
|
||||
if chunk_x < 0 || chunk_y < 0 || chunk_x >= chunks_size || chunk_y >= chunks_size {
|
||||
// println!("Out of bounds");
|
||||
return;
|
||||
}
|
||||
let chunk = &mut chunks[chunk_y as usize][chunk_x as usize];
|
||||
if layout[inside_y][inside_x] != b'#' {
|
||||
if !chunk.visited[inside_y][inside_x] {
|
||||
chunk.visited[inside_y][inside_x] = true;
|
||||
next_tile_queue.push((x, y));
|
||||
if step % 2 == modulo_equal {
|
||||
sum += 1;
|
||||
chunk.solution += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
for &(x, y) in &tile_queue {
|
||||
try_tile(x - 1, y);
|
||||
try_tile(x + 1, y);
|
||||
try_tile(x, y - 1);
|
||||
try_tile(x, y + 1);
|
||||
}
|
||||
tile_queue.clear();
|
||||
mem::swap(&mut tile_queue, &mut next_tile_queue);
|
||||
}
|
||||
// for row in &chunks {
|
||||
// println!("{:?}", row.iter().map(|chunk| chunk.solution).collect::<Vec<_>>());
|
||||
// }
|
||||
sum
|
||||
}
|
||||
|
||||
// Solution to part 2, makes an assumption that the starting row and column are empty
|
||||
fn count_options_infinite(layout: &Vec<&[u8]>, steps: i32) -> u64 {
|
||||
// Assuming square
|
||||
let chunk_width = layout.len() as i32;
|
||||
// Assuming the start is in the middle of chunk (it is so in the input)
|
||||
let start_pos = chunk_width / 2;
|
||||
// How many chunks in line from the start would the search reach
|
||||
let chunk_reach = (steps + chunk_width / 2) / chunk_width + 1;
|
||||
let chunk_reach_diag = (steps - 1) / chunk_width + 1;
|
||||
// Used to get solutions for various kinds of edge garden repetitions of the reachable region
|
||||
let count_options_adjusted = |start_pos: (i32, i32), steps_to_edge: i32| {
|
||||
let remaining_steps = steps - steps_to_edge;
|
||||
count_options_basic(layout, start_pos, remaining_steps)
|
||||
};
|
||||
// Order: N, W, S, E
|
||||
let edges_straight_closer = [
|
||||
count_options_adjusted(
|
||||
(start_pos, chunk_width - 1),
|
||||
start_pos + 1 + (chunk_reach - 3) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(0, start_pos),
|
||||
start_pos + 1 + (chunk_reach - 3) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(start_pos, 0),
|
||||
start_pos + 1 + (chunk_reach - 3) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(chunk_width - 1, start_pos),
|
||||
start_pos + 1 + (chunk_reach - 3) * chunk_width)
|
||||
];
|
||||
let edges_straight_further = [
|
||||
count_options_adjusted(
|
||||
(start_pos, chunk_width - 1),
|
||||
start_pos + 1 + (chunk_reach - 2) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(0, start_pos),
|
||||
start_pos + 1 + (chunk_reach - 2) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(start_pos, 0),
|
||||
start_pos + 1 + (chunk_reach - 2) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(chunk_width - 1, start_pos),
|
||||
start_pos + 1 + (chunk_reach - 2) * chunk_width)
|
||||
];
|
||||
// Order: NE, NW, SW, SE
|
||||
let edges_diagonal_closer = [
|
||||
count_options_adjusted(
|
||||
(chunk_width - 1, chunk_width - 1),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 3) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(0, chunk_width - 1),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 3) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(0, 0),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 3) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(chunk_width - 1, 0),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 3) * chunk_width)
|
||||
];
|
||||
let edges_diagonal_further = [
|
||||
count_options_adjusted(
|
||||
(chunk_width - 1, chunk_width - 1),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 2) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(0, chunk_width - 1),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 2) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(0, 0),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 2) * chunk_width),
|
||||
count_options_adjusted(
|
||||
(chunk_width - 1, 0),
|
||||
2 * (start_pos + 1) + (chunk_reach_diag - 2) * chunk_width)
|
||||
];
|
||||
let mut sum: u64 = 0;
|
||||
if chunk_reach_diag < 3 {
|
||||
// If the reach is small, compute the central chunk
|
||||
sum += count_options_basic(layout, (start_pos, start_pos), steps);
|
||||
}
|
||||
if chunk_reach >= 2 {
|
||||
// Fill the corners (of the rotated square)
|
||||
sum += edges_straight_further.iter().sum::<u64>();
|
||||
}
|
||||
if chunk_reach_diag >= 2 {
|
||||
// Fill the outer edges
|
||||
sum += edges_diagonal_further.iter().sum::<u64>() * (chunk_reach_diag - 1) as u64;
|
||||
}
|
||||
if chunk_reach >= 3 {
|
||||
// Fill the inner corners (of the rotated square)
|
||||
sum += edges_straight_closer.iter().sum::<u64>();
|
||||
}
|
||||
if chunk_reach_diag >= 3 {
|
||||
// Fill the space where we know chunks will be fully filled
|
||||
let full_even = count_options_basic_cont(
|
||||
layout, (start_pos, start_pos), 2 * chunk_width, false);
|
||||
let full_odd = count_options_basic_cont(
|
||||
layout, (start_pos, start_pos), 2 * chunk_width, true);
|
||||
let r = chunk_reach_diag as u64;
|
||||
let quadratic1 = r * r + 4 - 4 * r;
|
||||
let quadratic2 = r * r - 2 * r - 3;
|
||||
if (chunk_reach_diag + steps) % 2 == 0 {
|
||||
sum += full_even * quadratic2;
|
||||
sum += full_odd * quadratic1;
|
||||
} else {
|
||||
sum += full_even * quadratic1;
|
||||
sum += full_odd * quadratic2;
|
||||
}
|
||||
// Fill the inner edges
|
||||
sum += edges_diagonal_closer.iter().sum::<u64>() * (chunk_reach_diag - 2) as u64;
|
||||
// Fill the extension of central shape if the corners stick out more
|
||||
if chunk_reach > chunk_reach_diag {
|
||||
sum += 4 * if chunk_reach_diag % 2 == 0 { full_even } else {full_odd};
|
||||
}
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut start_pos: (i32, i32) = (0, 0);
|
||||
let mut layout: Vec<&[u8]> = vec![];
|
||||
for line in input_str.lines() {
|
||||
let bytes = line.as_bytes();
|
||||
match bytes.iter().position(|&c| c == b'S') {
|
||||
Some(pos) => {
|
||||
start_pos = (pos as i32, layout.len() as i32);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
layout.push(bytes);
|
||||
}
|
||||
// Part 1
|
||||
let sum1 = count_options_basic(&layout, start_pos, 64);
|
||||
// part 2
|
||||
// let sum2 = count_options_infinite_naive(&layout, start_pos, 500);
|
||||
let sum2 = count_options_infinite(&layout, 26501365);
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
7
day22/Cargo.lock
generated
Normal file
7
day22/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day22"
|
||||
version = "0.1.0"
|
8
day22/Cargo.toml
Normal file
8
day22/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day22"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
1485
day22/input.txt
Normal file
1485
day22/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
119
day22/src/main.rs
Normal file
119
day22/src/main.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
use std::cmp;
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
struct Brick {
|
||||
supports: Vec<u16>,
|
||||
supported_by: Vec<u16>,
|
||||
pos1: (u16, u16, u16),
|
||||
pos2: (u16, u16, u16),
|
||||
}
|
||||
|
||||
impl Brick {
|
||||
fn new(pos1: (u16, u16, u16), pos2: (u16, u16, u16)) -> Brick {
|
||||
Brick { supports: vec![], supported_by: vec![], pos1, pos2 }
|
||||
}
|
||||
}
|
||||
|
||||
// Part 1
|
||||
fn can_be_taken_out(bricks: &Vec<Brick>, brick: &Brick) -> bool {
|
||||
for &other_brick_id in &brick.supports {
|
||||
let other_brick = &bricks[other_brick_id as usize];
|
||||
if other_brick.supported_by.len() < 2 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
// Part 2
|
||||
fn count_fallen(bricks: &Vec<Brick>, index: usize) -> u16 {
|
||||
// Counting how many supports have been already removed from each brick
|
||||
let mut taken_supports: Vec<u16> = vec![0; bricks.len()];
|
||||
// Result counter
|
||||
let mut taken_bricks = 0;
|
||||
// Bricks that are going to disappear
|
||||
let mut to_take: Vec<u16> = vec![index as u16];
|
||||
loop {
|
||||
if let Some(id) = to_take.pop() {
|
||||
// Increase taken counter for each brick that is supported by current
|
||||
// If taken supports is equal to amount of supports, that brick will fall too
|
||||
let brick = &bricks[id as usize];
|
||||
for &supported_id in &brick.supports {
|
||||
let supported_brick = &bricks[supported_id as usize];
|
||||
taken_supports[supported_id as usize] += 1;
|
||||
if taken_supports[supported_id as usize] == supported_brick.supported_by.len() as u16 {
|
||||
to_take.push(supported_id);
|
||||
taken_bricks += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
taken_bricks
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let mut bricks: Vec<Brick> = vec![];
|
||||
for line in input_str.lines() {
|
||||
let mut split = line.split([',', '~']).map(|s| s.parse::<u16>().unwrap());
|
||||
bricks.push(Brick::new((split.next().unwrap(), split.next().unwrap(), split.next().unwrap()),
|
||||
(split.next().unwrap(), split.next().unwrap(), split.next().unwrap())));
|
||||
}
|
||||
// Sort by their vertical position so we can easily process them retaining falling precedence
|
||||
bricks.sort_by(|a, b| a.pos1.2.cmp(&b.pos1.2));
|
||||
// View from above containing id of the topmost brick on each x, y
|
||||
let max_x = bricks.iter().fold(0, |acc, brick| cmp::max(acc, brick.pos2.0));
|
||||
let max_y = bricks.iter().fold(0, |acc, brick| cmp::max(acc, brick.pos2.1));
|
||||
let mut from_above = vec![vec![u16::MAX; (max_x + 1) as usize]; (max_y + 1) as usize];
|
||||
// Make the bricks fall and create a support graph
|
||||
for i in 0..bricks.len() {
|
||||
let (below, rest) = bricks.split_at_mut(i);
|
||||
let brick = &mut rest[0];
|
||||
// Check how low the brick can go
|
||||
let mut target_z = 0;
|
||||
for y in brick.pos1.1..=brick.pos2.1 {
|
||||
for x in brick.pos1.0..=brick.pos2.0 {
|
||||
let &other_brick_id = &from_above[y as usize][x as usize];
|
||||
if other_brick_id != u16::MAX {
|
||||
let other_brick = &below[other_brick_id as usize];
|
||||
target_z = cmp::max(target_z, other_brick.pos2.2 + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Shift it below
|
||||
let z_drop = brick.pos1.2 - target_z;
|
||||
brick.pos1.2 -= z_drop;
|
||||
brick.pos2.2 -= z_drop;
|
||||
// Create support graph connections in bricks, update view from above
|
||||
for y in brick.pos1.1..=brick.pos2.1 {
|
||||
for x in brick.pos1.0..=brick.pos2.0 {
|
||||
let &other_brick_id = &from_above[y as usize][x as usize];
|
||||
if other_brick_id != u16::MAX {
|
||||
let other_brick = &mut below[other_brick_id as usize];
|
||||
if other_brick.pos2.2 + 1 == target_z {
|
||||
if !brick.supported_by.contains(&other_brick_id) {
|
||||
brick.supported_by.push(other_brick_id);
|
||||
other_brick.supports.push(i as u16);
|
||||
}
|
||||
}
|
||||
}
|
||||
from_above[y as usize][x as usize] = i as u16;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Part 1
|
||||
let sum1 = bricks.iter().filter(|&brick| can_be_taken_out(&bricks, brick)).count();
|
||||
// Part 2
|
||||
let sum2 = (0..bricks.len()).map(|i| count_fallen(&bricks, i) as u32).sum::<u32>();
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
7
day23/Cargo.lock
generated
Normal file
7
day23/Cargo.lock
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "day23"
|
||||
version = "0.1.0"
|
8
day23/Cargo.toml
Normal file
8
day23/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "day23"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
141
day23/input.txt
Normal file
141
day23/input.txt
Normal file
@@ -0,0 +1,141 @@
|
||||
#.###########################################################################################################################################
|
||||
#.#.................#...#...#...###.....#####...#.....###...#...###...#.......#.....#...#...###...###...#...###...###...#...#.....#...#.....#
|
||||
#.#.###############.#.#.#.#.#.#.###.###.#####.#.#.###.###.#.#.#.###.#.#.#####.#.###.#.#.#.#.###.#.###.#.#.#.###.#.###.#.#.#.#.###.#.#.#.###.#
|
||||
#.#...#.............#.#...#.#.#...#.#...#.....#.#...#...#.#...#.#...#.#.....#...#...#.#.#.#.#...#.###.#.#.#.#...#.....#.#.#.#...#...#.#...#.#
|
||||
#.###.#.#############.#####.#.###.#.#.###.#####.###.###.#.#####.#.###.#####.#####.###.#.#.#.#.###.###.#.#.#.#.#########.#.#.###.#####.###.#.#
|
||||
#.#...#.....#...#...#...#...#.#...#.#...#.....#.#...#...#...#...#...#.#...#...#...###.#.#.#.#...#.#...#.#.#.#.#.........#.#.#...#.....#...#.#
|
||||
#.#.#######.#.#.#.#.###.#.###.#.###.###.#####.#.#.###.#####.#.#####.#.#.#.###.#.#####.#.#.#.###.#.#.###.#.#.#.#.#########.#.#.###.#####.###.#
|
||||
#.#.#.......#.#.#.#.#...#...#.#...#.#...#.....#.#...#.#...#.#...>.>.#...#.#...#.>.>.#.#.#.#.###.#.#.#...#.#.#.#.###.....#.#.#.#...#...#.#...#
|
||||
#.#.#.#######.#.#.#.#.#####.#.###.#.#.###.#####.###.#.#.#.#.#####v#######.#.#####v#.#.#.#.#.###.#.#.#.###.#.#.#.###.###.#.#.#.#.###.#.#.#.###
|
||||
#.#.#...#...#.#.#.#.#...#...#.#...#.#.###.....#...#.#.#.#.#.....#.......#.#...###.#.#.#.#.#...#.#...#...#.#.#.#.>.>.#...#.#.#.#.#...#.#.#...#
|
||||
#.#.###v#.#.#.#.#.#.###.#.###.#.###.#.#######.###.#.#.#.#.#####.#######.#.###.###.#.#.#.#.###.#.#######.#.#.#.###v###.###.#.#.#.#.###.#.###.#
|
||||
#...###.>.#.#.#.#.#.#...#...#.#.#...#...###...#...#.#.#.#.......#...#...#.....#...#...#.#...#.#.#.......#.#...#...#...#...#.#.#...#...#.#...#
|
||||
#######v###.#.#.#.#.#.#####.#.#.#.#####.###.###.###.#.#.#########.#.#.#########.#######.###.#.#.#.#######.#####.###.###.###.#.#####.###.#.###
|
||||
#.....#...#.#.#.#.#.#.....#.#.#.#...#...#...###...#.#...#...#.....#...###...#...###.....#...#...#.....#...#.....###...#...#.#.#.....#...#...#
|
||||
#.###.###.#.#.#.#.#.#####.#.#.#.###.#.###.#######.#.#####.#.#.###########.#.#.#####.#####.###########.#.###.#########.###.#.#.#.#####.#####.#
|
||||
#...#.....#...#.#.#...#...#.#.#.#...#.>.>.#...#...#.#...#.#.#.........###.#.#.....#.....#.........###.#.###.......#...#...#.#.#.....#.#.....#
|
||||
###.###########.#.###.#.###.#.#.#.#####v###.#.#.###.#.#.#.#.#########.###.#.#####.#####.#########.###.#.#########.#.###.###.#.#####.#.#.#####
|
||||
###.....#...###...###.#.#...#.#...#...#.....#.#.....#.#...#.....#...#.....#.#.....###...#...#.....#...#...###...#.#...#.#...#.#.....#.#.....#
|
||||
#######.#.#.#########.#.#.###.#####.#.#######.#######.#########.#.#.#######.#.#######.###.#.#.#####.#####.###.#.#.###.#.#.###.#.#####.#####.#
|
||||
#.......#.#.........#.#.#...#...#...#...#.....###.....#.......#...#...#.....#.......#.#...#.#.....#.#.....#...#.#...#.#.#...#.#.#...#.#.....#
|
||||
#.#######.#########.#.#.###.###.#.#####.#.#######.#####.#####.#######.#.###########.#.#.###.#####.#.#.#####.###.###.#.#.###.#.#.#.#.#.#.#####
|
||||
#.#.....#.#.........#.#.###.#...#.....#...###.....#.....#####.......#.#.#...........#...###.#.....#...###...###...#.#.#...#...#...#...#.....#
|
||||
#.#.###.#.#.#########.#.###.#.#######.#######.#####.###############.#.#.#.#################.#.###########.#######.#.#.###.#################.#
|
||||
#.#.#...#.#.........#.#.#...#.#.....#.......#.......#...............#...#.................#.#.#.....#.....#...###...#.....###...............#
|
||||
#.#.#.###.#########.#.#.#.###.#.###.#######.#########.###################################.#.#.#.###.#.#####.#.###############.###############
|
||||
#...#...#.#.......#.#...#.....#...#.........#.....#...#.................#.......#...#.....#...#...#.#...###.#...#...#...###...#.........#...#
|
||||
#######.#.#.#####.#.#############.###########.###.#.###.###############.#.#####.#.#.#.###########.#.###.###.###.#.#.#.#.###.###.#######.#.#.#
|
||||
#...###...#.....#...###...###...#.........#...#...#.....#####...#...#...#.#...#...#.#...#.........#...#.....#...#.#...#...#.....###...#...#.#
|
||||
#.#.###########v#######.#.###.#.#########.#.###.#############.#.#.#.#.###.#.#.#####.###.#.###########.#######.###.#######.#########.#.#####.#
|
||||
#.#...........#.>.###...#.#...#...........#...#...#...#...#...#...#...###...#.....#.....#.......#...#.......#.###.#.......#...#.....#.....#.#
|
||||
#.###########.#v#.###.###.#.#################.###.#.#.#.#.#.#####################.#############.#.#.#######.#.###.#.#######.#.#.#########.#.#
|
||||
#...........#...#.#...#...#...........###...#.#...#.#.#.#.#...#...#...###...#...#.#...#.....###...#.#...###...#...#...#...#.#.#.........#...#
|
||||
###########.#####.#.###.#############.###.#.#.#.###.#.#.#.###.#.#.#.#.###.#.#.#.#.#.#.#.###.#######.#.#.#######.#####.#.#.#.#.#########.#####
|
||||
#.........#.....#.#...#.#...###.......#...#...#.#...#.#.#.#...#.#.#.#...#.#...#...#.#.#...#.....###...#...#...#...#...#.#.#.#.#...#.....#...#
|
||||
#.#######.#####.#.###.#.#.#.###.#######.#######.#.###.#.#.#.###.#.#.###.#.#########.#.###.#####.#########.#.#.###.#.###.#.#.#.#.#.#v#####.#.#
|
||||
#.......#.#.....#.#...#.#.#...#...#...#.......#.#.#...#.#.#...#.#.#...#.#.....###...#...#.....#.#...#.....#.#...#.#...#.#.#.#...#.>.#...#.#.#
|
||||
#######.#.#.#####.#.###.#.###.###v#.#.#######.#.#.#.###.#.###v#.#.###.#.#####v###.#####.#####.#.#.#.#.#####.###.#.###.#.#.#.#######v#.#.#.#.#
|
||||
#.......#.#.....#.#.###...#...#.>.>.#...#...#.#.#.#.#...#...>.>.#...#.#...#.>.>.#...#...#...#.#.#.#.#...###...#...###.#.#.#.......#.#.#...#.#
|
||||
#.#######.#####.#.#.#######.###.#v#####.#.#.#.#.#.#.#.#######v#####.#.###.#.#v#.###.#.###.#.#.#.#.#.###v#####.#######.#.#.#######.#.#.#####.#
|
||||
#.......#.#.....#.#.......#.....#...#...#.#.#.#.#.#...#####...#####.#.###...#.#.#...#...#.#.#.#...#...>.>...#.......#...#.#...#...#.#.#.....#
|
||||
#######.#.#.#####.#######.#########.#.###.#.#.#.#.#########.#######.#.#######.#.#.#####.#.#.#.#########v###.#######.#####.#.#.#.###.#.#.#####
|
||||
#.......#...#...#.....#...###...#...#.#...#.#.#.#.....#.....#.....#.#.#.......#.#.....#...#.#.###...#...#...#.......#.....#.#.#.#...#.#.....#
|
||||
#.###########.#.#####.#.#####.#.#.###.#.###.#.#.#####.#.#####.###.#.#.#.#######.#####.#####.#.###.#.#.###.###.#######.#####.#.#.#.###.#####.#
|
||||
#.............#.....#...###...#...###...###...#.#.....#.......#...#...#.......#.#.....#.....#.#...#...###...#.......#.....#.#...#.....#.....#
|
||||
###################.#######.###################.#.#############.#############.#.#.#####.#####.#.###########.#######.#####.#.###########.#####
|
||||
#.........#.....#...###...#.....#.....#...#...#.#.#.......#...#.....#...#...#.#...#...#...#...#.....###...#.#.....#.....#...###...#...#.....#
|
||||
#.#######.#.###.#.#####.#.#####.#.###.#.#.#.#.#.#.#.#####.#.#.#####.#.#.#.#.#.#####.#.###.#.#######.###.#.#.#.###.#####.#######.#.#.#.#####.#
|
||||
#...#...#...###...#...#.#.#.....#.#...#.#...#.#...#.....#...#.......#.#.#.#.#.#...#.#.###.#.#...###.....#.#...###...#...#.......#...#.......#
|
||||
###.#.#.###########.#.#.#.#.#####.#.###.#####.#########.#############.#.#.#.#.#.#.#.#.###.#.#.#.#########.#########.#.###.###################
|
||||
#...#.#.#...#...###.#.#.#.#.......#...#.#.....#.....###.......#.....#.#...#.#...#...#...#.#.#.#.........#.........#.#.###...#...#...........#
|
||||
#.###.#.#.#.#.#.###.#.#.#.###########.#.#.#####.###.#########.#.###.#.#####.###########.#.#.#.#########.#########.#.#.#####.#.#.#.#########.#
|
||||
#.....#...#...#...#.#...#.#...#.......#.#...#...#...#...#.....#...#.#.....#.............#...#.#.....###...........#.#.#...#...#...#.........#
|
||||
#################.#.#####.#.#.#.#######.###.#.###.###.#.#.#######.#.#####.###################.#.###.###############.#.#.#.#########.#########
|
||||
#.......#.........#.#.....#.#.#.#...#...#...#...#...#.#.#...#...#.#.#...#.......#.....###...#...###.........#.....#...#.#.###.....#.#.....###
|
||||
#.#####.#.#########.#.#####.#.#v#.#.#.###.#####.###.#.#.###.#.#.#.#.#.#.#######.#.###.###.#.###############.#.###.#####.#.###.###.#.#.###.###
|
||||
#.....#.#.......#...#.#...#.#.>.>.#...#...#...#.#...#.#.###.#.#.#.#...#.#.......#.#...#...#.###.............#...#...#...#.#...#...#...###...#
|
||||
#####.#.#######.#.###.#.#.#.###v#######.###.#.#.#.###.#.###v#.#.#.#####.#.#######.#.###.###.###.###############.###.#.###.#.###.###########.#
|
||||
#...#.#.........#...#.#.#.#.###.......#...#.#.#.#...#.#.#.>.>.#.#.....#.#.......#.#...#...#...#.............#...#...#...#.#...#.#...#.......#
|
||||
#.#.#.#############.#.#.#.#.#########.###.#.#.#.###.#.#.#.#v###.#####.#.#######.#.###.###.###.#############.#.###.#####.#.###.#.#.#.#.#######
|
||||
#.#...#.....#...#...#...#...#.........###.#.#.#.###...#.#.#.###.#...#.#.#.......#.#...###.#...#...#.........#...#.#...#.#.###.#.#.#.#.....###
|
||||
#.#####.###.#.#.#.###########.###########.#.#.#.#######.#.#.###.#.#.#.#.#.#######.#.#####.#.###.#.#v###########.#.#.#.#.#.###.#.#.#.#####.###
|
||||
#.......###.#.#.#...........#...#.......#.#.#.#.......#.#.#...#.#.#.#.#.#.....###.#...#...#.#...#.>.>.#...#...#.#.#.#.#.#...#.#.#.#.#...#...#
|
||||
###########v#.#.###########.###.#.#####.#.#.#.#######.#.#.###.#.#.#.#.#.#####v###.###.#.###.#.#####v#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.###.#
|
||||
#.........#.>.#.#...#.....#.#...#.#.....#...#...#...#.#.#.#...#...#...#...#.>.>...#...#...#...#.....#.#.#.#.#.#.#.#.#.#...#.#.#.#.#.#.#.#...#
|
||||
#.#######.#v###.#.#.#.###.#.#.###.#.###########.#.#.#.#.#.#.#############.#.#v#####.#####.#####.#####.#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#v###
|
||||
#.....#...#.#...#.#...###.#.#...#.#.......#####.#.#.#.#...#.....###...###.#.#...#...#...#.....#.#...#...#.#.#...#.#.#...#.#.#.#.#.#.#.#.>.###
|
||||
#####.#.###.#.###.#######.#.###.#.#######.#####.#.#.#.#########.###.#.###.#.###.#.###.#.#####.#.#.#.#####.#.#####.#.###.#.#.#.#.#.#.#.###v###
|
||||
#.....#.....#...#.......#...###...#.....#.....#...#.#.#.........#...#...#.#.#...#.....#.#.....#...#.#.....#.....#.#...#...#.#.#...#.#.#...###
|
||||
#.#############.#######.###########.###.#####.#####.#.#.#########.#####.#.#.#.#########.#.#########.#.#########.#.###.#####.#.#####.#.#.#####
|
||||
#.............#.#.....#.....###...#...#.......#...#...#...........#.....#...#...#.....#...#.........#...#...#...#.#...#.....#.....#...#.....#
|
||||
#############.#.#.###.#####.###.#.###.#########.#.#################.###########.#.###.#####.###########.#.#.#.###.#.###.#########.#########.#
|
||||
#.............#...###.....#.#...#.###.#.........#.....#.......#...#.....###.....#.#...#...#...........#...#.#.###.#...#.#...#.....###...#...#
|
||||
#.#######################.#.#.###.###.#.#############.#.#####.#.#.#####.###.#####.#.###.#.###########.#####.#.###.###.#.#.#.#.#######.#.#.###
|
||||
#.#...#...###.........###...#...#.....#.#.............#.....#...#.......#...#...#.#...#.#.....#.......#...#.#...#.#...#...#...###...#.#...###
|
||||
#.#.#.#.#.###.#######.#########.#######.#.#################.#############.###.#.#.###.#.#####.#.#######.#.#.###.#.#.#############.#.#.#######
|
||||
#...#...#.....#.....#...#.....#...#.....#.#.....#...#.....#.#...#...#...#...#.#.#.#...#.#.....#.#...###.#.#.#...#...#...#...#...#.#.#...#####
|
||||
###############.###.###.#.###.###.#.#####.#.###.#.#.#.###.#.#.#.#.#.#.#.###.#.#.#.#.###.#.#####.#.#.###.#.#.#.#######.#.#.#.#.#.#.#.###.#####
|
||||
###.........#...###.....#...#.....#.#.....#.#...#.#...#...#...#...#...#.#...#.#...#...#.#.....#...#...#.#.#...#...#...#.#.#.#.#.#.#.###.....#
|
||||
###.#######.#.#############.#######.#.#####.#.###.#####.###############.#.###.#######.#.#####.#######.#.#.#####.#.#.###.#.#.#.#.#.#.#######.#
|
||||
#...#.....#...###...###...#.........#.....#.#...#...#...#...#...###.....#.....#...###...#.....#...#...#.#.#...#.#.#...#.#.#.#.#.#.#.#...#...#
|
||||
#.###.###.#######.#.###.#.###############.#.###.###.#.###.#.#.#.###v###########.#.#######.#####.#.#v###.#.#.#.#.#.###.#.#.#.#.#.#.#.#v#.#.###
|
||||
#.....###.......#.#...#.#.#...#.....#.....#...#...#.#...#.#...#...>.>.#####...#.#.###...#.#...#.#.>.>...#...#.#.#.#...#.#.#.#.#.#.#.>.#...###
|
||||
###############.#.###.#.#.#.#.#.###.#.#######.###.#.###.#.#########v#.#####.#.#.#.###.#.#v#.#.#.###v#########.#.#.#.###.#.#.#.#.#.###v#######
|
||||
#.......#.......#.#...#.#...#...#...#.....###...#.#.#...#...#.......#...#...#.#.#.#...#.>.>.#.#.###...#.....#.#.#.#...#.#.#.#.#.#.###.......#
|
||||
#.#####.#v#######.#.###.#########.#######.#####.#.#.#.#####.#.#########.#.###.#.#.#.#####v###.#.#####.#.###.#.#.#.###.#.#.#.#.#.#.#########.#
|
||||
#.....#.#.>.#...#.#...#.........#...#...#.#.....#...#.......#.......###...###.#.#...#.....###...#...#.#.#...#...#.#...#...#.#.#...###...#...#
|
||||
#####.#.#v#.#.#.#.###.#########.###.#.#.#.#.#######################.#########.#.#####.###########.#.#.#.#.#######.#.#######.#.#######.#.#.###
|
||||
###...#...#.#.#.#...#.#...#...#.#...#.#.#.#.........###...#.......#.#...#...#...###...#...###.....#.#...#...#...#.#.......#...#...#...#...###
|
||||
###.#######.#.#.###.#.#.#.#.#.#.#.###.#.#v#########.###.#.#.#####.#.#.#.#.#.#######.###.#.###.#####.#######.#.#.#.#######.#####.#.#.#########
|
||||
#...#.....#...#...#.#.#.#.#.#.#.#...#.#.>.>.#...#...#...#.#.....#.#...#...#...#...#.....#.....#.....#...###...#.#.#.......#.....#...###.....#
|
||||
#.###.###.#######.#.#.#.#.#.#.#.###.#.###v#.#.#.#.###.###.#####.#.###########.#.#.#############.#####.#.#######.#.#.#######.###########.###.#
|
||||
#...#...#...#...#...#.#.#.#.#.#.#...#.#...#...#...###...#.#...#.#.#...#...#...#.#...#...#.......###...#.........#...#...###...#...#...#.#...#
|
||||
###.###.###.#.#.#####.#.#.#.#.#.#.###.#.###############.#.#.#.#.#.#.#.#.#.#.###.###.#.#.#.#########.#################.#.#####.#.#.#.#.#.#.###
|
||||
#...#...###...#.....#.#.#.#.#...#.#...#.......#.........#...#.#.#...#...#.#...#...#...#...#...#.....#.................#...#...#.#.#.#.#.#.###
|
||||
#.###.#############.#.#.#.#.#####.#.#########.#.#############.#.#########.###.###.#########.#.#.#####.###################.#.###.#.#.#.#.#.###
|
||||
#.#...#...........#.#...#...###...#...#.......#...#.....#.....#.....#.....#...#...#...#.....#.#.......#...###.............#...#.#...#...#...#
|
||||
#.#.###.#########.#.###########.#####.#.#########.#.###.#.#########.#.#####.###.###.#.#.#####.#########.#.###.###############.#.###########.#
|
||||
#.#.###.........#.#.#.....#...#.......#.......###...#...#.....#...#.#.#...#...#.....#...#.....#.........#.#...#.....#...#...#...#...#...#...#
|
||||
#.#.###########.#.#.#.###.#.#.###############.#######.#######.#.#.#.#.#.#.###.###########.#####.#########.#.###.###.#.#.#.#.#####.#.#.#.#.###
|
||||
#...#...........#...#.#...#.#.#...#...........#.....#.......#.#.#...#...#.#...###...#.....#...#.........#.#.....#...#.#.#.#.#.....#.#.#.#.###
|
||||
#####.###############.#.###.#.#.#.#.###########.###.#######.#.#.#########.#.#####.#.#.#####.#.#########.#.#######.###.#.#.#.#.#####.#.#.#.###
|
||||
#.....#.........#...#.#...#.#.#.#.#...........#...#.###.....#.#...#...###...#...#.#.#.......#.....#.....#...#.....###.#.#.#.#.....#...#...###
|
||||
#.#####.#######.#.#.#.###.#.#.#.#.###########.###.#.###.#####.###.#.#.#######.#.#.#.#############.#.#######.#.#######.#.#.#.#####v###########
|
||||
#.#.....#.......#.#.#.#...#.#.#.#.###.........#...#.....#...#.....#.#.#.....#.#.#.#...#.....#.....#.......#.#...###...#.#.#...#.>.###...#...#
|
||||
#.#.#####.#######.#.#.#.###.#.#.#.###v#########.#########.#.#######.#.#.###.#.#.#.###.#.###.#.###########.#.###.###.###.#.###.#.#v###.#.#.#.#
|
||||
#...#...#.#...###.#.#.#.#...#.#.#...>.>.......#.........#.#.###...#.#.#.#...#.#.#.#...#...#...#...###...#.#.#...#...###...#...#.#.#...#...#.#
|
||||
#####.#.#.#.#v###.#.#.#.#.###.#.#####v#######.#########.#.#.###.#.#.#.#.#.###.#.#.#.#####v#####.#.###.#.#.#.#v###.#########.###.#.#.#######.#
|
||||
###...#...#.#.>.#.#.#.#.#.###.#.#.....#.......#...#...#.#.#.....#...#.#.#.#...#.#.#.#...>.>.#...#.#...#.#.#.>.>.#...#.......#...#...#.......#
|
||||
###.#######.#v#.#.#.#.#.#.###.#.#.#####.#######.#.#.#.#v#.###########.#.#.#.###.#.#.#.###v#.#.###.#.###.#.###v#.###.#.#######.#######.#######
|
||||
#...#...#...#.#.#.#.#.#.#...#...#.....#...#...#.#.#.#.>.>.#...###.....#.#.#...#.#.#.#.#...#...###.#.#...#.#...#.#...#.....#...#.....#.......#
|
||||
#.###.#.#.###.#.#.#.#.#.###.#########.###.#.#.#.#.#.###v###.#.###.#####.#.###.#.#.#.#.#.#########.#.#.###.#.###.#.#######.#.###.###.#######.#
|
||||
#.....#...#...#...#.#.#...#...#.......###.#.#.#.#.#.###.#...#...#.....#.#.#...#...#...#.........#.#.#...#.#...#.#.....###...###...#.........#
|
||||
###########.#######.#.###.###.#.#########.#.#.#.#.#.###.#.#####.#####.#.#.#.###################.#.#.###.#.###.#.#####.###########.###########
|
||||
#...#.......#####...#.###.#...#.........#...#.#.#.#...#.#.#.....#...#...#...#...#.......#.......#...###...#...#...#...#...........#...#.....#
|
||||
#.#.#.###########.###.###.#.###########.#####.#.#.###.#.#.#.#####.#.#########.#.#.#####.#.#################.#####.#.###.###########.#.#.###.#
|
||||
#.#.#...........#.#...###...#...........#...#.#.#.#...#.#.#.......#.......#...#...#...#...#...#...###.......#...#...#...#.........#.#.#.#...#
|
||||
#.#.###########.#.#.#########.###########.#.#.#.#.#.###.#.###############.#.#######.#.#####.#.#.#.###.#######.#.#####.###.#######.#.#.#.#.###
|
||||
#.#.............#...###.......#.........#.#.#...#.#.###...###...#...#...#.#.........#.......#...#...#...#...#.#.....#.....#.......#.#...#...#
|
||||
#.#####################.#######.#######.#.#.#####.#.#########.#.#.#.#.#.#.#########################.###.#.#.#.#####.#######.#######.#######.#
|
||||
#...#.............#...#...#.....#.......#.#.###...#...#.......#...#...#.#...###...###...#.......#...###...#...#...#.......#.......#.#.......#
|
||||
###.#.###########.#.#.###.#.#####.#######.#.###.#####.#.###############.###.###.#.###.#.#.#####.#.#############.#.#######.#######.#.#.#######
|
||||
###...#...........#.#...#...#...#.........#...#.......#...............#.....#...#...#.#...#...#...#####...#...#.#.........###.....#.#.#...###
|
||||
#######.###########.###.#####.#.#############.#######################.#######.#####.#.#####.#.#########.#.#.#.#.#############.#####.#.#.#.###
|
||||
#.......#...#...###...#.#.....#.......#.......#...#...................###...#...#...#.......#...#...#...#.#.#.#.........#.....#.....#...#...#
|
||||
#.#######.#.#.#.#####.#.#.###########.#.#######.#.#.#####################.#.###.#.#############.#.#.#.###.#.#.#########.#.#####.###########.#
|
||||
#...#.....#...#...#...#.#...........#...#.....#.#.#.................#.....#.....#.#.............#.#.#.#...#.#...#.....#.#.......#...........#
|
||||
###.#.###########.#.###.###########.#####.###.#.#.#################.#.###########.#.#############.#.#.#.###v###.#.###.#.#########.###########
|
||||
#...#.#...........#...#.###.....###...###...#.#.#...#...#...#.......#...........#.#.......#...#...#...#.#.>.>.#...#...#.#.....###...........#
|
||||
#.###.#.#############.#.###.###.#####.#####.#.#.###.#.#.#.#.#.#################.#.#######.#.#.#.#######.#.###.#####.###.#.###.#############.#
|
||||
#...#.#...........#...#...#...#.#.....#...#.#.#.#...#.#.#.#.#.###...#.....#.....#...#...#.#.#.#.......#.#.#...#...#.....#...#...#####.......#
|
||||
###.#.###########.#.#####.###.#.#.#####.#.#.#.#.#.###.#.#.#.#v###.#.#.###.#.#######.#.#.#.#.#.#######.#.#.#.###.#.#########.###.#####.#######
|
||||
#...#.#...........#...#...###.#.#...#...#.#.#...#.#...#.#.#.>.>.#.#.#.#...#.....#...#.#.#.#.#.#...#...#...#...#.#...###...#...#...#...#...###
|
||||
#.###.#.#############.#.#####.#.###.#.###.#.#####.#.###.#.#####.#.#.#.#.#######.#.###.#.#v#.#.#.#.#.#########.#.###.###.#.###.###.#.###.#.###
|
||||
#.#...#.......###...#.#.#...#.#.###.#...#.#.....#.#.#...#.....#.#.#.#.#.....#...#.#...#.>.>.#.#.#.#.......###...###...#.#.#...#...#...#.#...#
|
||||
#.#.#########.###.#.#.#.#.#.#.#.###v###.#.#####.#.#.#.#######.#.#.#.#.#####.#.###.#.#########.#.#.#######.###########.#.#.#.###.#####.#.###.#
|
||||
#...#...#.....#...#.#.#.#.#.#.#.#.>.>.#.#.#...#.#.#.#.....#...#...#.#.#.....#.#...#...###.....#.#...#...#.#...........#.#.#.#...#...#...#...#
|
||||
#####.#.#.#####.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#####.#.#######.#.#.#####.#.#####.###.#####.###.#.#.#.#.###########.#.#.#.###.#.#####v###
|
||||
#.....#...#...#.#...#.#.#.#.#.#.#.#...#.#.#.#.#.#.#.#.....#.......#.#.#...#...#.#...#...#.....#...#.#.#.#.#.#...#.....#.#.#.#...#.#...#.>.###
|
||||
#.#########.#.#.#.###.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.###########.#.#.###.#.###.#.#.###.#####.###.#.#.#.#.#.#.#.#.###.#.#.#.###.#.###.#.#v###
|
||||
#...........#...#.....#...#...#...#.....#...#...#...#.............#...###...###...#.....#####.....#...#...#...#...###...#...###...###...#...#
|
||||
###########################################################################################################################################.#
|
281
day23/src/main.rs
Normal file
281
day23/src/main.rs
Normal file
@@ -0,0 +1,281 @@
|
||||
use std::cmp;
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
enum Direction {
|
||||
Left = 0,
|
||||
Right = 1,
|
||||
Up = 2,
|
||||
Down = 3,
|
||||
}
|
||||
|
||||
const ALL_DIRECTIONS: [Direction; 4] = [Direction::Left, Direction::Right, Direction::Up, Direction::Down];
|
||||
const OPPOSITE_DIRECTION: [Direction; 4] = [Direction::Right, Direction::Left, Direction::Down, Direction::Up];
|
||||
const DIRECTION_OFFSET: [(i32, i32); 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)];
|
||||
|
||||
// Tries to find the longest path while parsing input on the fly, slow
|
||||
fn find_longest_walk_naive(layout: &[&[u8]], slopes: bool) -> i32 {
|
||||
let start_x = layout[0].iter().position(|&c| c == b'.').unwrap() as i32;
|
||||
find_longest_walk_naive_inner(layout, slopes, (start_x, 0), Direction::Down, HashSet::new())
|
||||
}
|
||||
|
||||
// Inner recursive function for find_longest_walk_naive, takes a set of already visited junctions
|
||||
fn find_longest_walk_naive_inner(layout: &[&[u8]], slopes: bool, mut pos: (i32, i32), mut dir: Direction,
|
||||
mut visited_junctions: HashSet<(i32, i32)>) -> i32 {
|
||||
let last_row = layout.len() - 1;
|
||||
let mut steps = 0;
|
||||
let mut longest_alternative = 0;
|
||||
let mut options: Vec<((i32, i32), Direction)> = vec![];
|
||||
loop {
|
||||
if pos.1 == 0 {
|
||||
pos.1 += 1;
|
||||
dir = Direction::Down;
|
||||
steps += 1;
|
||||
} else if pos.1 == last_row as i32 {
|
||||
return cmp::max(steps, longest_alternative);
|
||||
} else {
|
||||
if visited_junctions.contains(&pos) {
|
||||
return longest_alternative;
|
||||
}
|
||||
let mut add_direction_option = |new_dir: Direction| {
|
||||
let offset = DIRECTION_OFFSET[new_dir as usize];
|
||||
let new_pos = (pos.0 + offset.0, pos.1 + offset.1);
|
||||
if layout[new_pos.1 as usize][new_pos.0 as usize] == b'#' {
|
||||
return;
|
||||
}
|
||||
options.push((new_pos, new_dir));
|
||||
};
|
||||
let mut add_all_options = || {
|
||||
for new_dir in ALL_DIRECTIONS {
|
||||
if new_dir == OPPOSITE_DIRECTION[dir as usize] {
|
||||
continue;
|
||||
}
|
||||
add_direction_option(new_dir);
|
||||
}
|
||||
};
|
||||
if slopes {
|
||||
match layout[pos.1 as usize][pos.0 as usize] {
|
||||
b'<' => add_direction_option(Direction::Left),
|
||||
b'>' => add_direction_option(Direction::Right),
|
||||
b'^' => add_direction_option(Direction::Up),
|
||||
b'v' => add_direction_option(Direction::Down),
|
||||
_ => add_all_options()
|
||||
}
|
||||
} else {
|
||||
add_all_options();
|
||||
}
|
||||
|
||||
if options.is_empty() {
|
||||
// Dead end, doesn't happen but i put it for the sake of completeness
|
||||
return longest_alternative;
|
||||
}
|
||||
if options.len() > 1 {
|
||||
visited_junctions.insert(pos);
|
||||
}
|
||||
for (i, &(new_pos, new_dir)) in options.iter().enumerate() {
|
||||
if i > 0 {
|
||||
let alternative = find_longest_walk_naive_inner(
|
||||
layout, slopes, new_pos, new_dir, visited_junctions.clone());
|
||||
longest_alternative = cmp::max(longest_alternative, steps + alternative);
|
||||
} else {
|
||||
pos = new_pos;
|
||||
dir = new_dir;
|
||||
steps += 1;
|
||||
}
|
||||
}
|
||||
options.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Each element is one node, which is an array of (neighbour index, distance)
|
||||
type HikingGraph = Vec<Vec<(u32, u32)>>;
|
||||
|
||||
// Transforms the input map into a graph of junctions, with edges being distances
|
||||
// First element is the start and last element is the end
|
||||
fn get_hiking_graph(layout: &[&[u8]], slopes: bool) -> HikingGraph {
|
||||
let start_x = layout[0].iter().position(|&c| c == b'.').unwrap() as i32;
|
||||
let last_row = layout.len() - 1;
|
||||
let mut options: Vec<((i32, i32), Direction)> = vec![];
|
||||
let mut junction_node_mapping: HashMap<(i32, i32), u32> = HashMap::new();
|
||||
let mut graph: HikingGraph = vec![];
|
||||
graph.push(vec![]);
|
||||
let mut edge_finding_stack: Vec<(u32, (i32, i32), Direction)> = vec![];
|
||||
edge_finding_stack.push((0, (start_x, 1), Direction::Down));
|
||||
let mut end_node: u32 = 0;
|
||||
const DIR_SLOPES: [u8; 4] = [b'<', b'>', b'^', b'v'];
|
||||
loop {
|
||||
if let Some((id, mut pos, mut dir)) = edge_finding_stack.pop() {
|
||||
let mut steps = 1;
|
||||
let mut possible_forward = true;
|
||||
let mut possible_backward = true;
|
||||
loop {
|
||||
if pos.1 == 0 {
|
||||
pos.1 += 1;
|
||||
dir = Direction::Down;
|
||||
steps += 1;
|
||||
} else if pos.1 == last_row as i32 {
|
||||
let new_id = graph.len() as u32;
|
||||
junction_node_mapping.insert(pos, new_id);
|
||||
if possible_forward {
|
||||
graph[id as usize].push((new_id, steps));
|
||||
}
|
||||
if possible_backward {
|
||||
graph.push(vec![(id, steps)]);
|
||||
} else {
|
||||
graph.push(vec![]);
|
||||
}
|
||||
end_node = new_id;
|
||||
break;
|
||||
} else {
|
||||
match junction_node_mapping.get(&pos) {
|
||||
None => {}
|
||||
Some(&other_id) => {
|
||||
if !graph[id as usize].iter().any(|(that_id, _)| *that_id == other_id) {
|
||||
if possible_forward {
|
||||
graph[id as usize].push((other_id, steps));
|
||||
}
|
||||
if possible_backward {
|
||||
graph[other_id as usize].push((id, steps));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mut add_direction_option = |new_dir: Direction| {
|
||||
let offset = DIRECTION_OFFSET[new_dir as usize];
|
||||
let new_pos = (pos.0 + offset.0, pos.1 + offset.1);
|
||||
if layout[new_pos.1 as usize][new_pos.0 as usize] == b'#' {
|
||||
return;
|
||||
}
|
||||
options.push((new_pos, new_dir));
|
||||
};
|
||||
let mut add_all_options = || {
|
||||
for new_dir in ALL_DIRECTIONS {
|
||||
if new_dir == OPPOSITE_DIRECTION[dir as usize] {
|
||||
continue;
|
||||
}
|
||||
add_direction_option(new_dir);
|
||||
}
|
||||
};
|
||||
add_all_options();
|
||||
if options.is_empty() {
|
||||
// Dead end, doesn't happen but i put it for the sake of completeness
|
||||
break;
|
||||
}
|
||||
if options.len() == 1 {
|
||||
let &(new_pos, new_dir) = &options[0];
|
||||
if slopes {
|
||||
if layout[pos.1 as usize][pos.0 as usize]
|
||||
== DIR_SLOPES[dir as usize] {
|
||||
possible_backward = false;
|
||||
} else if layout[pos.1 as usize][pos.0 as usize]
|
||||
== DIR_SLOPES[OPPOSITE_DIRECTION[dir as usize] as usize] {
|
||||
possible_forward = false;
|
||||
}
|
||||
}
|
||||
pos = new_pos;
|
||||
dir = new_dir;
|
||||
steps += 1;
|
||||
options.clear();
|
||||
} else {
|
||||
let new_id = graph.len() as u32;
|
||||
junction_node_mapping.insert(pos, new_id);
|
||||
if possible_forward {
|
||||
graph[id as usize].push((new_id, steps));
|
||||
}
|
||||
if possible_backward {
|
||||
graph.push(vec![(id, steps)]);
|
||||
} else {
|
||||
graph.push(vec![]);
|
||||
}
|
||||
for &(new_pos, new_dir) in options.iter() {
|
||||
edge_finding_stack.push((new_id, new_pos, new_dir));
|
||||
}
|
||||
options.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Swaps the end node with the last in array node
|
||||
let last_node = graph.len() as u32 - 1;
|
||||
graph.swap(end_node as usize, last_node as usize);
|
||||
for node in graph.iter_mut() {
|
||||
node.iter_mut().for_each(|to_node|
|
||||
if to_node.0 == end_node {
|
||||
to_node.0 = last_node;
|
||||
} else if to_node.0 == last_node {
|
||||
to_node.0 = end_node;
|
||||
});
|
||||
};
|
||||
graph
|
||||
}
|
||||
|
||||
// Finds the longest path in a graph in a general case
|
||||
fn find_longest_walk_graph(graph: &HikingGraph, node_from: u32, node_to: u32) -> i32 {
|
||||
let visited = vec![false; graph.len()];
|
||||
find_longest_walk_graph_inner(graph, node_from, node_to, visited)
|
||||
}
|
||||
|
||||
// Recursive helper for find_longest_walk_graph, has a set (vec) of visited nodes
|
||||
fn find_longest_walk_graph_inner(graph: &HikingGraph, mut node_from: u32, node_to: u32,
|
||||
mut visited: Vec<bool>) -> i32 {
|
||||
let mut length = 0;
|
||||
let mut longest_alternative = -1;
|
||||
loop {
|
||||
if node_from == node_to {
|
||||
return cmp::max(length, longest_alternative);
|
||||
} else {
|
||||
if visited[node_from as usize] {
|
||||
return longest_alternative;
|
||||
}
|
||||
let connections = &graph[node_from as usize];
|
||||
if connections.is_empty() {
|
||||
// Dead end, doesn't happen but i put it for the sake of completeness
|
||||
return longest_alternative;
|
||||
}
|
||||
visited[node_from as usize] = true;
|
||||
let mut connections_iter = connections.iter();
|
||||
let &(first_node, first_edge) = connections_iter.next().unwrap();
|
||||
for &(new_node, edge) in connections_iter {
|
||||
let new_length = length + edge as i32;
|
||||
let alternative = find_longest_walk_graph_inner(
|
||||
graph, new_node, node_to, visited.clone());
|
||||
if alternative != -1 {
|
||||
longest_alternative = cmp::max(longest_alternative, new_length + alternative);
|
||||
}
|
||||
}
|
||||
node_from = first_node;
|
||||
length += first_edge as i32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finds the longest path with given input by building the graph of junctions and finding
|
||||
// the longest path
|
||||
fn find_longest_walk(layout: &[&[u8]], slopes: bool) -> i32 {
|
||||
let graph = get_hiking_graph(layout, slopes);
|
||||
find_longest_walk_graph(&graph, 0, graph.len() as u32 - 1)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let layout: Vec<&[u8]> = input_str.lines().map(|s| s.as_bytes()).collect();
|
||||
let result1 = find_longest_walk(&layout, true);
|
||||
let result2 = find_longest_walk(&layout, false);
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Result1: {}", result1);
|
||||
println!("Result2: {}", result2);
|
||||
}
|
92
day24/Cargo.lock
generated
Normal file
92
day24/Cargo.lock
generated
Normal file
@@ -0,0 +1,92 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "day24"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
9
day24/Cargo.toml
Normal file
9
day24/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "day24"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
num = "0.4.1"
|
300
day24/input.txt
Normal file
300
day24/input.txt
Normal file
@@ -0,0 +1,300 @@
|
||||
200027938836082, 135313515251542, 37945458137479 @ 133, 259, 506
|
||||
285259862606823, 407476720802151, 448972585175416 @ 12, -120, -241
|
||||
329601664688534, 370686722303193, 178908568819244 @ -133, -222, 168
|
||||
224985900829298, 214925632111185, 149368039079818 @ 77, 81, 242
|
||||
296437806379588, 68696864488553, 9964503372160 @ 34, 338, 300
|
||||
232239129106374, 223028585546926, 246426150966661 @ 89, 147, 48
|
||||
271805776381363, 498745349607170, 241968934263498 @ -70, -773, 21
|
||||
334618297909998, 287662575776141, 307715065462604 @ -33, 80, -24
|
||||
209686250664760, 187819441819935, 272042848835366 @ 52, -231, -357
|
||||
277500761149058, 333431119693601, 114011249139706 @ 44, 41, 206
|
||||
312118668181768, 495014609197265, 186766093899598 @ 16, -106, 119
|
||||
299683250085970, 97849820660305, 270011660400330 @ -44, 330, -5
|
||||
229720558256611, 150910727673562, 243270833145468 @ -68, 117, -77
|
||||
304248494909992, 219767581530113, 254465655656873 @ -137, 38, -6
|
||||
246750940858792, 233990979047981, 210953288389140 @ -62, -168, 120
|
||||
233067759142206, 198113631860301, 199711852215930 @ 32, 61, 145
|
||||
194273010182062, 231126869346983, 175766437001790 @ 147, 25, 191
|
||||
422437581013498, 520681737761805, 551376558156718 @ -149, -221, -336
|
||||
213621024566196, 152714072145937, 231042606220912 @ -54, -74, -76
|
||||
196857076420466, 257330625183425, 151562284105578 @ 149, -379, 427
|
||||
369318041141350, 320601489876785, 404752437430854 @ -56, 62, -122
|
||||
177717686542186, 261386998367960, 271529522712591 @ 189, -59, -46
|
||||
262701995382254, 313552465631125, 382611373509334 @ -24, -189, -324
|
||||
170297191018136, 178309134118657, 225360885518954 @ 212, 142, 69
|
||||
227622713436232, 154353931514341, 280415902687702 @ 58, 204, -81
|
||||
314948926503302, 408416248916028, 453190315236620 @ -39, -143, -265
|
||||
293223113430502, 423607642677073, 319619656107050 @ -38, -266, -99
|
||||
252020827135166, 156505968362865, 310375343290926 @ -136, 126, -386
|
||||
263439342121787, 301341574163972, 252713891021320 @ 38, 17, 35
|
||||
198791366653612, 97037164135423, 237475860248930 @ 148, 643, -135
|
||||
265515753922082, 77028908701403, 372580955540610 @ -67, 431, -383
|
||||
244122754125607, 216118441735598, 251141183508785 @ -32, -55, -34
|
||||
368405242763362, 487076527780613, 257997522712470 @ -63, -141, 40
|
||||
255316322983682, 108881920473485, 223486097050440 @ -67, 344, 70
|
||||
248202087006514, 332313273894033, 299629715190090 @ 79, 48, -5
|
||||
242526038555392, 172309277470091, 281968246773090 @ 38, 177, -55
|
||||
377029210698079, 355128725572901, 168339101770659 @ -44, 50, 136
|
||||
195247088386282, 207400901771393, 179202560974770 @ 176, -444, 446
|
||||
305350369740094, 318546425948691, 359769376111386 @ 7, 49, -83
|
||||
220238585738990, 301135827650157, 178425231826166 @ 92, -75, 168
|
||||
293134188318610, 455585245138889, 178821007816418 @ 25, -103, 132
|
||||
296805282994282, 477461073094877, 160305288302868 @ 33, -84, 146
|
||||
551484833298770, 430831686261581, 415123879556900 @ -235, -40, -120
|
||||
264263487126684, 475446609663063, 234719810787824 @ 62, -107, 68
|
||||
208118421230229, 186370297031592, 162445108177304 @ 102, 51, 303
|
||||
379457876720978, 470069791102841, 319907054392598 @ -115, -196, -54
|
||||
307081543504480, 345947348356843, 333126004018988 @ -26, -47, -84
|
||||
275592475604044, 268751187599757, 291577264394906 @ -26, -20, -67
|
||||
223538882701191, 241874529688322, 236884948735720 @ 66, -49, 35
|
||||
217306880344022, 228332316074413, 132327655645815 @ 105, 114, 226
|
||||
288613631151179, 344112266171307, 264129986825655 @ 44, 60, 40
|
||||
391925053763340, 380982015060763, 513639079473102 @ -90, -17, -257
|
||||
317349509030790, 434745366987169, 209235218174754 @ -76, -270, 103
|
||||
265019875952157, 100779004627568, 193342693392940 @ -52, 353, 159
|
||||
239497638093832, 145125270103727, 21043699168434 @ 8, 221, 713
|
||||
235688079024824, 236070451305047, 249110777938228 @ 24, -55, -6
|
||||
254338369110232, 284989404572389, 149097978418136 @ 58, 60, 182
|
||||
170962227947302, 78199807246080, 77886341913974 @ 193, 379, 377
|
||||
188700869304678, 17975326303209, 364531904960094 @ 144, 384, -56
|
||||
188146734972721, 198414310422359, 31503292875758 @ 154, 152, 417
|
||||
209859086224528, 126699646051391, 242207571947277 @ 87, 280, -22
|
||||
339514053892582, 305669314514513, 358205645006730 @ -92, -10, -139
|
||||
364239230823630, 134872902901983, 261941454368215 @ -79, 268, 30
|
||||
224460476321604, 296552716035239, 275414144435650 @ 11, -568, -195
|
||||
87643762120749, 180316544924259, 270813136963950 @ 264, 216, 25
|
||||
396704525151872, 86365100440993, 193863226488620 @ -60, 318, 110
|
||||
287579264392312, 541282922916881, 310697373167610 @ 18, -266, -35
|
||||
219115359852829, 425077073845073, 255652122856596 @ 92, -362, 7
|
||||
345130946591991, 463544251720861, 528954166317265 @ -24, -86, -250
|
||||
211798361516338, 169917478027707, 240060316499404 @ 37, -71, -84
|
||||
234073712530041, 208961882726755, 261193905624604 @ 24, 16, -49
|
||||
260673598074478, 273125896519813, 303569550514920 @ 25, 18, -65
|
||||
234225942126142, 334594973868557, 249357715571756 @ -47, -814, -73
|
||||
194503280378341, 83543670520014, 234685741733095 @ 142, 349, 60
|
||||
256825512968734, 217098465735509, 281163376366062 @ 20, 99, -38
|
||||
206903429582962, 285693092592113, 419158418070570 @ 101, -460, -845
|
||||
249311051976182, 213020513000653, 83458884867380 @ -7, 34, 471
|
||||
330368645477374, 263338996885345, 221100829139928 @ -89, 46, 82
|
||||
236262398273986, 184664223382601, 209185855979298 @ -49, -11, 136
|
||||
298064517145996, 438537394814861, 176088036632055 @ 31, -46, 130
|
||||
295490246929342, 397446098278553, 339376231881390 @ 32, -8, -42
|
||||
254324790454585, 336889283238461, 196599761151279 @ 16, -174, 134
|
||||
182262064412882, 206007569681201, 374257893209674 @ 158, 167, -133
|
||||
223426344993655, 424185113242685, 393301531410891 @ 110, -14, -86
|
||||
320760904752983, 184993183332542, 87890558602034 @ -36, 197, 269
|
||||
283961007648219, 176128474236562, 79127578720829 @ -40, 177, 374
|
||||
301136921143282, 385966081948625, 343703516477226 @ 33, 22, -38
|
||||
341468210661298, 388247589073361, 257419541423082 @ -23, -10, 43
|
||||
222094532764222, 104419022560328, 149419156083345 @ -39, 455, 630
|
||||
225621024483212, 179835009574931, 225426472393282 @ -52, -103, 41
|
||||
180590209225432, 174387449432793, 273841337539820 @ 235, 30, -201
|
||||
279247881380594, 520526120105281, 153622924992218 @ -43, -596, 231
|
||||
273158965208722, 315710335804973, 173971146323010 @ -83, -279, 219
|
||||
267979293363034, 227311776608853, 274876632996975 @ -179, -182, -170
|
||||
273267030106312, 298860128841353, 250487127745100 @ 46, 74, 48
|
||||
197562635430598, 271758220363921, 190988479076304 @ 139, -74, 154
|
||||
165710284540612, 156670111374815, 125338936908300 @ 248, 179, 400
|
||||
317944886562946, 216904763352419, 309117144349596 @ -131, 77, -116
|
||||
546731571529402, 506707788552983, 357821666355380 @ -215, -103, -54
|
||||
286105887874482, 276472328823817, 289923386450858 @ -67, -69, -79
|
||||
235388770625038, 237793394137259, 342120134173245 @ 25, -60, -290
|
||||
477732253201002, 251586033009398, 395444643202490 @ -195, 131, -123
|
||||
204705827128732, 308629152997013, 302605879848540 @ 123, -110, -93
|
||||
376997830155931, 369071431413774, 285168848102309 @ -74, -5, 8
|
||||
311831859199679, 310731690408100, 346529249203462 @ 24, 99, -39
|
||||
255467223349492, 135838974808586, 248643090053601 @ 63, 267, 48
|
||||
264148672257454, 174903319987529, 153123286013378 @ -20, 164, 243
|
||||
316205705123896, 286786590620183, 277768052454294 @ -209, -192, -87
|
||||
280868990296682, 274007307501593, 307012157851570 @ -9, 20, -69
|
||||
201753536198032, 242396991020453, 245568548141010 @ 128, -56, 9
|
||||
328051439833898, 434546576899369, 249510611786626 @ -24, -99, 48
|
||||
264640019914610, 227935465050577, 245725553705994 @ -58, -20, 7
|
||||
352390492484930, 534651025917425, 264313956967042 @ -33, -166, 36
|
||||
533833867672880, 553611320645473, 476050170268652 @ -274, -242, -228
|
||||
251119099939790, 304280134982224, 248772419744767 @ 41, -41, 32
|
||||
283071362253322, 364191219048673, 310190393003530 @ 16, -56, -43
|
||||
356295539800102, 392581665802868, 314502430364895 @ -23, 13, -10
|
||||
227633359450920, 191503364565333, 214102076185962 @ -120, -312, 133
|
||||
269699389153161, 105374462482562, 184661370796480 @ -88, 347, 195
|
||||
295865488902134, 146498506936395, 370232632173154 @ 39, 259, -63
|
||||
247392543884764, 337636443014113, 281040486310450 @ -128, -882, -255
|
||||
326411290618424, 365653413141261, 422264849974398 @ -9, 10, -143
|
||||
258418426189826, 121673030731129, 300829489051738 @ -49, 295, -169
|
||||
307292563519186, 377127442654401, 392722234592218 @ -245, -603, -526
|
||||
205781583202267, 265470269558019, 197731337175253 @ 88, -804, 254
|
||||
249711429057846, 265531095717107, 268515984071116 @ 35, 5, -12
|
||||
165360322069199, 134996423563510, 157235516730598 @ 296, 241, 377
|
||||
171467775968482, 219947616561893, 195539332516370 @ 181, 122, 125
|
||||
292438097454242, 374099369566833, 283127011356330 @ 20, -24, 7
|
||||
285218340510922, 293119294141957, 338864183316494 @ -197, -365, -378
|
||||
176387437668760, 162256430098307, 145987632841698 @ 240, 119, 417
|
||||
258595198656378, 238121490933883, 284046844008568 @ 9, 43, -52
|
||||
332209231670784, 442465418130361, 510375408965104 @ -90, -254, -406
|
||||
142029660870022, 199302722044401, 48566760894860 @ 223, 166, 350
|
||||
178734727735972, 283277301976333, 330773939663279 @ 163, 58, -72
|
||||
373166187989528, 283639478033222, 517458307841330 @ -169, 5, -435
|
||||
328013730776722, 356434964469173, 313551231751230 @ -11, 20, -21
|
||||
227260751593414, 267181552851329, 315951113497524 @ 91, 62, -64
|
||||
324116670655010, 269566969541385, 71656400088674 @ -9, 115, 254
|
||||
203495944150856, 292645522720043, 254019521387110 @ 122, -247, -25
|
||||
173036351405092, 151745787866063, 201246206335080 @ 224, 195, 146
|
||||
231766047638707, 247936662684443, 190672789320870 @ 40, -76, 169
|
||||
215754528047932, 173734978906403, 241928569107300 @ 78, 115, 6
|
||||
251992212847102, 120693415221781, 40186447363282 @ 28, 291, 447
|
||||
208441458326038, 331856061497789, 152732438943885 @ 97, -598, 370
|
||||
229223718072877, 200402768463953, 200257259587870 @ -20, -106, 185
|
||||
197147995569574, 379602113606061, 228459288583312 @ 139, -248, 66
|
||||
291172692753310, 372021072514745, 352834309835310 @ 34, 12, -60
|
||||
217546833794162, 191290040026161, 253501313407626 @ 53, -15, -71
|
||||
249400409134386, 300702178134668, 313455739745512 @ 69, 53, -37
|
||||
215236809500751, 131312078498914, 165853238519326 @ -16, 237, 609
|
||||
438453432810582, 255940860832443, 411360000299370 @ -165, 117, -155
|
||||
206755963901242, 211675935561037, 110793997188122 @ 103, -99, 569
|
||||
236951124070132, 297466048455277, 256754962609874 @ 58, -68, 9
|
||||
148871580460682, 208977260642833, 283796479792374 @ 233, 118, -41
|
||||
337533398001784, 127917348501766, 371069630077386 @ -41, 277, -107
|
||||
231076785232567, 316464170169778, 303962794692535 @ 82, -33, -54
|
||||
295230931636387, 148283307864483, 231544980136845 @ 16, 252, 70
|
||||
286684562586450, 418045752689857, 311412130974136 @ 21, -98, -34
|
||||
195325542326857, 296413361574293, 180152830662495 @ 142, -46, 160
|
||||
293562234234353, 253195050605080, 258263678125607 @ -28, 61, 18
|
||||
216627802440430, 191786233378484, 218670118900485 @ 9, -205, 90
|
||||
212444194265086, 242160041952083, 408504771540078 @ 99, -37, -433
|
||||
399468503044708, 237747966985439, 380022351954012 @ -114, 141, -114
|
||||
203034431104332, 153584219202793, 169732345813245 @ 123, 190, 250
|
||||
336522604758118, 378765298159913, 115634023739946 @ -46, -52, 221
|
||||
411855682188620, 289560020485619, 168044857741446 @ -90, 107, 139
|
||||
239686437684766, 146178719042051, 247333702720794 @ 31, 229, 13
|
||||
328763578487386, 275729337950797, 210598159374158 @ -191, -96, 107
|
||||
267869747483902, 305658162631193, 241953404455310 @ 19, -22, 47
|
||||
233945494232562, 163881852595793, 235975835715210 @ -130, -7, -44
|
||||
210963216216681, 173665593303812, 207386955753599 @ 90, 95, 132
|
||||
211774017429793, 221451657767448, 198694845256484 @ 100, 13, 143
|
||||
201122974777881, 173694931503961, 187410525515336 @ 114, -530, 639
|
||||
371613372690436, 483053706628323, 446474143269594 @ -284, -587, -467
|
||||
380537549453506, 427500787123361, 332068790285034 @ -120, -143, -73
|
||||
199833661019450, 230482885690417, 270628811830218 @ 134, -254, -179
|
||||
359597808018575, 202976442100239, 275153144455668 @ -90, 172, 7
|
||||
190311437668434, 54253328484833, 255169066295072 @ 149, 398, 26
|
||||
427211286234874, 320791580106737, 186751692997740 @ -111, 70, 120
|
||||
182156336120309, 90705213353086, 152603736579205 @ 212, 439, 380
|
||||
272080371889046, 200763090252365, 472710661392650 @ 42, 185, -235
|
||||
250649446980406, 276179305667147, 269492258715691 @ 25, -40, -22
|
||||
255098527784527, 200845917950958, 258384224425040 @ -56, 25, -49
|
||||
340406502141208, 486235039883213, 318910309653471 @ -125, -382, -98
|
||||
482001492375650, 263042397221697, 446541180443914 @ -145, 144, -139
|
||||
250747569743782, 478592698602593, 289346846111970 @ 62, -214, -13
|
||||
240995947673902, 145335091170113, 81413838485376 @ 43, 238, 388
|
||||
378259953533280, 143771322077729, 377459699176962 @ -124, 254, -143
|
||||
295822845200538, 441223847533342, 333556471981606 @ 29, -63, -39
|
||||
290337153909832, 257774418382218, 290984778864545 @ -17, 61, -34
|
||||
251648926041376, 62269949471439, 128010029337696 @ 55, 376, 223
|
||||
192425556641514, 176775297492433, 211659510716286 @ 231, -362, 184
|
||||
247773132592477, 263236520189528, 103420788870610 @ -68, -295, 573
|
||||
216098157036706, 190834023680381, 366267177502218 @ 105, 167, -171
|
||||
219949293285996, 207455129378943, 224159150767575 @ 71, 28, 70
|
||||
217743395935322, 90553240327633, 283457993611458 @ -22, 598, -476
|
||||
262647153477247, 347326523342993, 206953249958700 @ 42, -42, 103
|
||||
236510128651939, 170111053460876, 285079651867944 @ 32, 159, -97
|
||||
232424660720782, 236304039993632, 238777501370190 @ 33, -59, 25
|
||||
194098673191672, 179897551477442, 251357502719184 @ 163, 11, -77
|
||||
215590056284422, 169708095720473, 210174049374090 @ -30, -168, 181
|
||||
389953474749235, 325106002770038, 285108735092688 @ -150, -17, -13
|
||||
75073384713112, 25765351030553, 131958661160370 @ 276, 394, 185
|
||||
201493678702066, 196383295909937, 323040563757738 @ 129, 89, -198
|
||||
339871829605604, 301592523784752, 287903705946757 @ -73, 21, -16
|
||||
264880646188178, 271635837320233, 237667407273658 @ -51, -132, 33
|
||||
443396947040705, 345039086220391, 242759916727681 @ -106, 64, 62
|
||||
259698470412892, 280522544679548, 120491314920210 @ -65, -231, 413
|
||||
202040412653747, 278867613094134, 208069614860446 @ 128, -99, 113
|
||||
250301573762772, 306866454590713, 227347657873710 @ 20, -126, 67
|
||||
156475137204672, 230116653452939, 187571542343518 @ 218, 77, 147
|
||||
257455927978132, 145886897028596, 309692837822862 @ -17, 229, -151
|
||||
209164030957770, 209515060839558, 201556717502513 @ 77, -227, 194
|
||||
189737946436922, 173014891184393, 204877857300010 @ 207, -52, 189
|
||||
166598000701104, 268840955423078, 92160355769345 @ 179, 83, 260
|
||||
226193194431032, 160418199680023, 223236421200320 @ -102, -21, 50
|
||||
184919377653217, 233255517014513, 167626425491515 @ 256, -586, 506
|
||||
316454485542526, 346799816876993, 313798741982334 @ -26, -22, -44
|
||||
368059091363419, 367009944722297, 307598255425446 @ -164, -146, -71
|
||||
232588322065552, 229873185432965, 234896095782339 @ 43, -6, 42
|
||||
226614096902854, 205663209347485, 250203858638726 @ 46, 21, -16
|
||||
256892558569042, 284768449724121, 227553246645242 @ -47, -221, 59
|
||||
311747525787082, 246161647148318, 337709030604120 @ -35, 99, -93
|
||||
230806682829532, 287176556008133, 212773336187434 @ 58, -112, 101
|
||||
173288955408256, 245810645263947, 138653412983474 @ 190, 25, 257
|
||||
244082013066922, 265815839450393, 308535371620330 @ 52, 23, -79
|
||||
142898137072258, 256462610679739, 193948445233226 @ 277, -48, 149
|
||||
244168244022010, 251871427985033, 238530905276730 @ 41, 18, 45
|
||||
261012816944908, 197858407057909, 409255846642198 @ -86, 24, -597
|
||||
212041885321831, 210916662732545, 209276504516264 @ 16, -538, 183
|
||||
297787953120938, 257896976480377, 335508835863582 @ -21, 72, -98
|
||||
205969343213662, 124866770359418, 191246958410595 @ 41, 313, 520
|
||||
185495105794072, 182028900956453, 314125834857813 @ 223, -62, -502
|
||||
246335901706586, 333469921797527, 335790374869608 @ 65, -25, -86
|
||||
392960680861072, 347343247331323, 211544205935330 @ -65, 52, 93
|
||||
261644860722838, 485350956642647, 177657432845388 @ 31, -315, 154
|
||||
270920640787087, 227132466169943, 221561809993320 @ -186, -172, 75
|
||||
358923751946616, 301992328806047, 300783553351302 @ -66, 59, -17
|
||||
224485337894317, 154469205163707, 223102145017560 @ -62, 60, 55
|
||||
450561343198590, 487035149479378, 407239521511251 @ -135, -107, -116
|
||||
299853372809677, 48476745323603, 467390546598000 @ -32, 408, -325
|
||||
298830936266626, 291798749626433, 485433904501176 @ -131, -162, -626
|
||||
277523562889083, 300234195516429, 337092559332891 @ 56, 106, -32
|
||||
248653804580626, 262874295779045, 238924886386478 @ -11, -124, 27
|
||||
255806245934219, 318844142777107, 367636284715854 @ -34, -296, -359
|
||||
223522959259682, 395910120888177, 285125525425450 @ 108, -8, 15
|
||||
228730009573754, 222519263517397, 323173430025654 @ 99, 165, -38
|
||||
229946667709342, 192117214961330, 253579791283212 @ -47, -113, -121
|
||||
257628032013062, 217468286014509, 232678437185618 @ 38, 129, 63
|
||||
271556835748734, 345202992463693, 259465434800126 @ 51, 28, 39
|
||||
336487836502395, 186878758409691, 85301935620388 @ -36, 204, 251
|
||||
251528770085594, 333887777405675, 260994552338240 @ 65, 5, 30
|
||||
219577653809182, 154577029498943, 237951868111020 @ -13, 73, -54
|
||||
279821188982786, 312453345647441, 288836815141338 @ 9, -10, -23
|
||||
496808769097352, 529365960101157, 515544025043822 @ -382, -420, -429
|
||||
316511122733995, 110486632399634, 356160985833744 @ -56, 305, -137
|
||||
219514532695492, 195113648040579, 276500143560306 @ 43, -36, -179
|
||||
282196269411606, 249000919840789, 317500292685298 @ -16, 57, -93
|
||||
203148590203482, 94672313021233, 87023850261610 @ 123, 382, 509
|
||||
221765864569372, 198750765619828, 121797493795120 @ 55, 21, 435
|
||||
180230161063155, 162295810490995, 227824230142053 @ 294, -8, 16
|
||||
365112164680882, 478434372728993, 227392357304970 @ -31, -71, 77
|
||||
193967007526857, 360109286768802, 136183490676803 @ 158, -683, 428
|
||||
178928293374594, 133840610798121, 252427548622158 @ 177, 264, 16
|
||||
313972661483208, 430389904970724, 474830430199696 @ -189, -579, -637
|
||||
243671340770666, 239787962003561, 378942374151308 @ -39, -166, -544
|
||||
330942104453366, 294562372023097, 197426796741198 @ -100, -20, 124
|
||||
219569261003863, 280342381340302, 195266824989205 @ 64, -263, 170
|
||||
314991842177074, 258058199380545, 362245986975742 @ -155, -50, -273
|
||||
228170987436690, 216833054656631, 274746095171817 @ 101, 176, 22
|
||||
359722074153721, 183065145941027, 231068416031061 @ -44, 216, 72
|
||||
300699721344811, 296229362436594, 258818598634950 @ -20, 21, 25
|
||||
175246559001112, 239018771951603, 234733961773215 @ 199, -20, 44
|
||||
195503841965434, 292822135129676, 126595482391086 @ 141, -15, 249
|
||||
210122253097426, 117663667622183, 64139386471206 @ 117, 293, 331
|
||||
267858396535087, 183865771984128, 276078152981305 @ -26, 145, -48
|
||||
238651110653899, 159691722304274, 353384593960029 @ 82, 235, -92
|
||||
227633012565742, 286842156678083, 183847230586950 @ 105, 116, 121
|
||||
333288134138558, 310005440370059, 289513720020993 @ -55, 20, -14
|
||||
364060312830814, 275331776026907, 404235609101853 @ -95, 72, -172
|
||||
285036868217538, 195280797866981, 290058103457564 @ -99, 92, -108
|
||||
212639762301738, 360074885372545, 71706946494338 @ 116, -36, 284
|
||||
336830103228052, 364902277732998, 208265007312401 @ -77, -87, 102
|
||||
326239698790313, 163971514061130, 208364532591176 @ -28, 231, 99
|
||||
331845161397556, 300298732568051, 283094203334462 @ -20, 77, 11
|
||||
228533587686617, 202201370353503, 235991282914435 @ 32, 12, 26
|
||||
246667455209470, 195051752027597, 192733032724350 @ -165, -156, 255
|
||||
306304636512517, 223742266948043, 444396004495350 @ -54, 108, -311
|
||||
296039899934322, 145129329948113, 402362269082890 @ 5, 254, -159
|
||||
202999771762228, 146240051943681, 237753178134706 @ 82, -50, -231
|
||||
382805429868506, 336410075463609, 440218611480970 @ -198, -101, -315
|
||||
408884926032706, 202770803758919, 369957487852320 @ -179, 165, -140
|
||||
187454478565317, 171799851968911, 251734618819341 @ 218, -24, -134
|
||||
209476850606455, 145318450089827, 235058218661112 @ 26, 72, -93
|
||||
237143661838570, 267500655008013, 319742257387126 @ 55, -17, -126
|
||||
264297070549015, 252770344735044, 261027553674786 @ 22, 61, 13
|
||||
223813420961976, 158033971202187, 224609305596604 @ -34, 61, 48
|
||||
247955936421811, 430129512657056, 185221232669868 @ 74, -95, 127
|
||||
196439322869622, 266185955942518, 344761596267147 @ 153, -497, -614
|
190
day24/src/main.rs
Normal file
190
day24/src/main.rs
Normal file
@@ -0,0 +1,190 @@
|
||||
use std::fs::read_to_string;
|
||||
use std::time::Instant;
|
||||
|
||||
fn get_numbers_in_line_split_iter<T: std::str::FromStr>(str: &str) -> impl Iterator<Item=T> + '_ {
|
||||
str.split([' ', ',']).filter_map(|substr| substr.parse::<T>().ok())
|
||||
}
|
||||
|
||||
struct Hailstone {
|
||||
pos: (i64, i64, i64),
|
||||
vel: (i64, i64, i64),
|
||||
}
|
||||
|
||||
enum LineIntersection<T: PartialOrd> {
|
||||
// Has position of intersection
|
||||
Intersects((T, T)),
|
||||
// Has coefficient of the line (a, b, c), with line being ax + bx + c = 0
|
||||
Colinear((T, T, T)),
|
||||
None,
|
||||
}
|
||||
|
||||
// lXpY = line X point Y
|
||||
fn xy_intersection<T>(l1p1: (T, T), l1p2: (T, T), l2p1: (T, T), l2p2: (T, T)) -> LineIntersection<T>
|
||||
where T: PartialOrd + std::ops::Neg<Output=T> + std::ops::Sub<Output=T> + num::Zero,
|
||||
for<'a> &'a T: std::ops::Sub<Output=T> + std::ops::Mul<Output=T> + std::ops::Div<Output=T>
|
||||
{
|
||||
let l1xdiff = &l1p1.0 - &l1p2.0;
|
||||
let l1ydiff = &l1p1.1 - &l1p2.1;
|
||||
let l2xdiff = &l2p1.0 - &l2p2.0;
|
||||
let l2ydiff = &l2p1.1 - &l2p2.1;
|
||||
let denom = &l1xdiff * &l2ydiff - &l1ydiff * &l2xdiff;
|
||||
if denom == T::zero() {
|
||||
let proj1 = &l1p1.0 * &l1ydiff - &l1p1.1 * &l1xdiff;
|
||||
let proj2 = &l2p1.0 * &l1ydiff - &l2p1.1 * &l1xdiff;
|
||||
if &proj1 - &proj2 == T::zero() {
|
||||
return LineIntersection::Colinear((l1xdiff, -l1ydiff, -proj1));
|
||||
} else {
|
||||
return LineIntersection::None;
|
||||
}
|
||||
}
|
||||
let l1det = (&l1p1.0 * &l1p2.1) - (&l1p1.1 * &l1p2.0);
|
||||
let l2det = (&l2p1.0 * &l2p2.1) - (&l2p1.1 * &l2p2.0);
|
||||
let detx = &l1det * &l2xdiff - &l2det * &l1xdiff;
|
||||
let dety = &l1det * &l2ydiff - &l2det * &l1ydiff;
|
||||
LineIntersection::Intersects((&detx / &denom, &dety / &denom))
|
||||
}
|
||||
|
||||
fn vec_add<T>(v1: (T, T, T), v2: (T, T, T)) -> (T, T, T)
|
||||
where T: std::ops::Add<Output=T> {
|
||||
(v1.0 + v2.0, v1.1 + v2.1, v1.2 + v2.2)
|
||||
}
|
||||
|
||||
fn cross_prod<T>(v1: (T, T, T), v2: (T, T, T)) -> (T, T, T)
|
||||
where T: std::ops::Sub<T, Output=T>, for<'a> &'a T: std::ops::Mul<&'a T, Output=T> {
|
||||
(&v1.1 * &v2.2 - &v1.2 * &v2.1, &v1.2 * &v2.0 - &v1.0 * &v2.2, &v1.0 * &v2.1 - &v1.1 * &v2.0)
|
||||
}
|
||||
|
||||
|
||||
// Get integer intersecting line at the right timeframes: (x, y, z), (vx, vy, vz)
|
||||
fn get_intersecting_line(hailstones: &[Hailstone]) -> ((i64, i64, i64), (i64, i64, i64)) {
|
||||
// Moving the frame of reference to hailstones[0] so we can compute the rest around origin
|
||||
// With one line being reduced to start (0, 0, 0) and velocity (0, 0, 0) it'll be simpler
|
||||
let map_pos = hailstones[0].pos;
|
||||
let map_vel = hailstones[0].vel;
|
||||
let hails = hailstones[1..=2].iter().map(
|
||||
|hail| {
|
||||
let pos = ((hail.pos.0 - map_pos.0) as i128, (hail.pos.1 - map_pos.1) as i128, (hail.pos.2 - map_pos.2) as i128);
|
||||
let vel = ((hail.vel.0 - map_vel.0) as i128, (hail.vel.1 - map_vel.1) as i128, (hail.vel.2 - map_vel.2) as i128);
|
||||
(pos, vel)
|
||||
}
|
||||
).collect::<Vec<_>>();
|
||||
// cross product of vectors from origin to two points of the first other line
|
||||
let plane1 = cross_prod(hails[0].0, vec_add(hails[0].0, hails[0].1));
|
||||
// cross product of vectors from origin to two points of the second other line
|
||||
let plane2 = cross_prod(hails[1].0, vec_add(hails[1].0, hails[1].1));
|
||||
// cross product of thw two planes to reduce the space to a single line
|
||||
let line = cross_prod(plane1, plane2);
|
||||
// The line now represents a good direction with potentially wrong length (not a problem),
|
||||
// and potentially wrong sign (a problem)
|
||||
// find the smallest possible vel using gcd
|
||||
let gcd = [line.0, line.1, line.2].iter()
|
||||
.fold(0i128, |acc, &elem| num::integer::gcd(acc, elem));
|
||||
let mut vel = (line.0 / gcd, line.1 / gcd, line.2 / gcd);
|
||||
// We need to find the start point
|
||||
// We know of one line at (0, 0, 0) due to mapping, we'll use it with another line to figure
|
||||
// out the exact starting position (mapped)
|
||||
// start + t0 * vel = 0 - the line at 0
|
||||
// start + t1 * vel = p1 + t1*vel1 - the other line
|
||||
// becomes
|
||||
// start = p1 + t1 * (vel1 - vel)
|
||||
// start = -t0 * vel
|
||||
// get rid of start
|
||||
// t0 * vel + t1 * (vel1 - vel) = -p1 - the vectors are 3 dimensional and we have 2 variables
|
||||
// solve system of just taking the x and y from vectors
|
||||
let mut det = vel.0 * (hails[1].1.1 - vel.1) - vel.1 * (hails[1].1.0 - vel.0);
|
||||
let mut t0 = -hails[1].0.0 * (hails[1].1.1 - vel.1) / det + hails[1].0.1 * (hails[1].1.0 - vel.0) / det;
|
||||
let mut start = (-t0 * vel.0, -t0 * vel.1, -t0 * vel.2);
|
||||
// check on other 2 hailstones if the answer is consistent, otherwise flip sign
|
||||
let mut wrong = false;
|
||||
let rock_pos = [start.0, start.1, start.2];
|
||||
let rock_vel = [vel.0, vel.1, vel.2];
|
||||
'outer: for i in 0..2 {
|
||||
let mut last_solution: Option<i128> = None;
|
||||
let hail_pos = [hails[i].0.0, hails[i].0.1, hails[i].0.2];
|
||||
let hail_vel = [hails[i].1.0, hails[i].1.1, hails[i].1.2];
|
||||
for j in 0..3 {
|
||||
let denom = rock_vel[j] - hail_vel[j];
|
||||
if denom != 0 {
|
||||
let new_solution = (hail_pos[j] - rock_pos[j]) / denom;
|
||||
if new_solution < 0 {
|
||||
wrong = true;
|
||||
break 'outer;
|
||||
}
|
||||
match last_solution {
|
||||
None => last_solution = Some(new_solution),
|
||||
Some(s) => {
|
||||
if s != new_solution {
|
||||
wrong = true;
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// flip the sign
|
||||
if wrong {
|
||||
vel = (-vel.0, -vel.1, -vel.2);
|
||||
det = vel.0 * (hails[1].1.1 - vel.1) - vel.1 * (hails[1].1.0 - vel.0);
|
||||
t0 = -hails[1].0.0 * (hails[1].1.1 - vel.1) / det + hails[1].0.1 * (hails[1].1.0 - vel.0) / det;
|
||||
start = (-t0 * vel.0, -t0 * vel.1, -t0 * vel.2);
|
||||
}
|
||||
let start_unmapped = (start.0 as i64 + map_pos.0, start.1 as i64 + map_pos.1, start.2 as i64 + map_pos.2);
|
||||
let vel_unmapped = (vel.0 as i64 + map_vel.0, vel.1 as i64 + map_vel.1, vel.2 as i64 + map_vel.2);
|
||||
(start_unmapped, vel_unmapped)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
// Shift the interval to be centered around 0, avoids numerical errors
|
||||
const COORD_SHIFT: i64 = -3e14 as i64;
|
||||
const MIN_POS: f64 = -1e14;
|
||||
const MAX_POS: f64 = 1e14;
|
||||
let hailstones = input_str.lines().map(|line| {
|
||||
let mut it = get_numbers_in_line_split_iter::<i64>(line);
|
||||
Hailstone {
|
||||
pos: (it.next().unwrap() + COORD_SHIFT, it.next().unwrap() + COORD_SHIFT, it.next().unwrap() + COORD_SHIFT),
|
||||
vel: (it.next().unwrap(), it.next().unwrap(), it.next().unwrap()),
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
// Part 1
|
||||
let mut count1 = 0;
|
||||
for (i, h1) in hailstones.iter().enumerate() {
|
||||
for h2 in hailstones[i + 1..].iter() {
|
||||
let l1p1 = (h1.pos.0 as f64, h1.pos.1 as f64);
|
||||
let l1p2 = ((h1.pos.0 + h1.vel.0) as f64, (h1.pos.1 + h1.vel.1) as f64);
|
||||
let l2p1 = (h2.pos.0 as f64, h2.pos.1 as f64);
|
||||
let l2p2 = ((h2.pos.0 + h2.vel.0) as f64, (h2.pos.1 + h2.vel.1) as f64);
|
||||
match xy_intersection(l1p1, l1p2, l2p1, l2p2) {
|
||||
LineIntersection::Intersects((x, y)) => {
|
||||
// Check if it's not in the past, thankfully velocity components are never 0
|
||||
if (x - h1.pos.0 as f64) / h1.vel.0 as f64 >= 0.
|
||||
&& (x - h2.pos.0 as f64) / h2.vel.0 as f64 >= 0. {
|
||||
if x >= MIN_POS && x <= MAX_POS && y >= MIN_POS && y <= MAX_POS {
|
||||
count1 += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
LineIntersection::Colinear((_, _, _)) => {
|
||||
// Seems this case isn't used
|
||||
// otherwise I'd have to check if they go in the same direction
|
||||
}
|
||||
LineIntersection::None => {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Part 2
|
||||
let (start, vel) = get_intersecting_line(&hailstones);
|
||||
let corrected_start = (start.0 - COORD_SHIFT, start.1 - COORD_SHIFT, start.2 - COORD_SHIFT);
|
||||
let summed_coords = corrected_start.0 + corrected_start.1 + corrected_start.2;
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Count1: {}", count1);
|
||||
println!("Start: {:?}, vel: {:?}", corrected_start, vel);
|
||||
println!("Summed start coords: {:?}", summed_coords);
|
||||
}
|
75
day25/Cargo.lock
generated
Normal file
75
day25/Cargo.lock
generated
Normal file
@@ -0,0 +1,75 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "day25"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
9
day25/Cargo.toml
Normal file
9
day25/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "day25"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
rand = "0.8.5"
|
1262
day25/input.txt
Normal file
1262
day25/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
151
day25/src/main.rs
Normal file
151
day25/src/main.rs
Normal file
@@ -0,0 +1,151 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{BTreeSet, HashMap};
|
||||
use std::fs::read_to_string;
|
||||
use std::mem;
|
||||
use std::time::Instant;
|
||||
|
||||
// Returns the weight of minimum cut
|
||||
// and a vector containing node indices of one of the resulting graphs after the cut
|
||||
fn stoer_wagner_cut(graph: &Vec<Vec<u16>>) -> (u16, Vec<u16>) {
|
||||
if graph.len() < 2 {
|
||||
return (0, vec![]);
|
||||
}
|
||||
// the original graph with added edge weight values
|
||||
let mut modified_graph: Vec<Vec<(u16, u16)>> = graph.iter()
|
||||
.map(|neighbours| neighbours.iter()
|
||||
.map(|&elem| (elem, 1u16))
|
||||
.collect::<Vec<_>>()
|
||||
).collect::<Vec<_>>();
|
||||
// The node indices that haven't been removed through merging yet
|
||||
let mut remaining_nodes: Vec<u16> = (0..modified_graph.len() as u16).collect();
|
||||
// Min cut weight so far and node that was cut off during it
|
||||
let mut best_cut_weight: u16 = u16::MAX;
|
||||
let mut best_cut_node: u16 = 0;
|
||||
// priority queue for finding the most tightly connected node, the highest value is next
|
||||
// the keys are graph_size * weight + index, so there's no collision for the same weights
|
||||
// a fibonacci heap could be better but not strictly needed and I'd rather minimize imports
|
||||
let graph_size = modified_graph.len() as u32;
|
||||
let mut search_candidates_queue: BTreeSet<u32> = BTreeSet::new();
|
||||
// keeping track of priority queue indices so it can be removed and re added
|
||||
let mut search_candidates_keys: Vec<u32> = vec![u32::MAX; remaining_nodes.len()];
|
||||
// keeping track of what nodes were merged with what
|
||||
let mut merge_tree: Vec<Vec<u16>> = vec![vec![]; modified_graph.len()];
|
||||
while remaining_nodes.len() > 1 {
|
||||
// the nodes that are cut second to last and last, weight of their cut
|
||||
let mut s = remaining_nodes[0];
|
||||
let mut t = s;
|
||||
let mut cut_of_the_phase = 0;
|
||||
// min cut phase - preparing the queue
|
||||
for &idx in &remaining_nodes[1..remaining_nodes.len()] {
|
||||
let weight = match modified_graph[remaining_nodes[0] as usize].iter().find(
|
||||
|&(edge_to, _)| *edge_to == idx) {
|
||||
None => 0,
|
||||
Some(&(_, edge_weight)) => edge_weight
|
||||
};
|
||||
let key = graph_size * weight as u32 + idx as u32;
|
||||
search_candidates_keys[idx as usize] = key;
|
||||
search_candidates_queue.insert(key);
|
||||
}
|
||||
// min cut phase
|
||||
while !search_candidates_queue.is_empty() {
|
||||
let max_key = search_candidates_queue.pop_last().unwrap();
|
||||
let idx = (max_key % graph_size) as u16;
|
||||
let max_weight = (max_key / graph_size) as u16;
|
||||
search_candidates_keys[idx as usize] = u32::MAX;
|
||||
s = t;
|
||||
t = idx;
|
||||
cut_of_the_phase = max_weight;
|
||||
for &(that_idx, that_weight) in modified_graph[idx as usize].iter() {
|
||||
let mut new_key = search_candidates_keys[that_idx as usize];
|
||||
if new_key != u32::MAX {
|
||||
search_candidates_queue.remove(&new_key);
|
||||
new_key += graph_size * that_weight as u32;
|
||||
search_candidates_queue.insert(new_key);
|
||||
search_candidates_keys[that_idx as usize] = new_key;
|
||||
}
|
||||
}
|
||||
}
|
||||
// store information that t was merged into s
|
||||
merge_tree[s as usize].push(t);
|
||||
// remove the last node
|
||||
let mut t_node = vec![];
|
||||
mem::swap(&mut t_node, &mut modified_graph[t as usize]);
|
||||
remaining_nodes.retain(|&idx| idx != t);
|
||||
// merge s and t into s, update other nodes connecting to s or t
|
||||
for &(edge_to, edge_weight) in t_node.iter() {
|
||||
if edge_to == s {
|
||||
modified_graph[edge_to as usize].retain(|(to, _)| *to != t);
|
||||
continue;
|
||||
}
|
||||
match modified_graph[s as usize].iter().position(|&(edge_to2, _)| edge_to2 == edge_to) {
|
||||
None => {
|
||||
modified_graph[s as usize].push((edge_to, edge_weight));
|
||||
modified_graph[edge_to as usize].iter_mut().find(|(to, _)| *to == t).unwrap().0 = s;
|
||||
}
|
||||
Some(pos) => {
|
||||
modified_graph[s as usize][pos].1 += edge_weight;
|
||||
modified_graph[edge_to as usize].retain(|(to, _)| *to != t);
|
||||
modified_graph[edge_to as usize].iter_mut().find(|(to, _)| *to == s).unwrap().1 += edge_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if this cut was the best so far, remember it
|
||||
if cut_of_the_phase < best_cut_weight {
|
||||
best_cut_weight = cut_of_the_phase;
|
||||
best_cut_node = t;
|
||||
}
|
||||
}
|
||||
// gather all nodes that were merged into the best cut node and return them
|
||||
fn add_branch(merge_tree: &Vec<Vec<u16>>, result_nodes: &mut Vec<u16>, idx: u16) {
|
||||
result_nodes.push(idx);
|
||||
for &v in &merge_tree[idx as usize] {
|
||||
add_branch(merge_tree, result_nodes, v);
|
||||
}
|
||||
}
|
||||
let mut result_nodes = vec![];
|
||||
add_branch(&merge_tree, &mut result_nodes, best_cut_node);
|
||||
(best_cut_weight, result_nodes)
|
||||
}
|
||||
|
||||
// returns a graph in form of edge list for each node and a map of node names to indices
|
||||
fn parse_graph(input_str: &str) -> (Vec<Vec<u16>>, HashMap<String, u16>) {
|
||||
let mut node_index: HashMap<String, u16> = HashMap::new();
|
||||
let graph: RefCell<Vec<Vec<u16>>> = RefCell::new(vec![]);
|
||||
let mut get_node_index = |name: &str| -> u16 {
|
||||
match node_index.entry(name.parse().unwrap()) {
|
||||
std::collections::hash_map::Entry::Occupied(occupied_entry) => {
|
||||
return *occupied_entry.get();
|
||||
}
|
||||
std::collections::hash_map::Entry::Vacant(vacant_entry) => {
|
||||
let new_index = graph.borrow().len() as u16;
|
||||
graph.borrow_mut().push(vec![]);
|
||||
vacant_entry.insert(new_index);
|
||||
return new_index;
|
||||
}
|
||||
}
|
||||
};
|
||||
for line in input_str.lines() {
|
||||
let mut iter = line.split([' ', ':']).filter(|&s| !s.is_empty());
|
||||
let first = get_node_index(iter.next().unwrap());
|
||||
for other_name in iter {
|
||||
let other = get_node_index(other_name);
|
||||
graph.borrow_mut()[first as usize].push(other);
|
||||
graph.borrow_mut()[other as usize].push(first);
|
||||
}
|
||||
}
|
||||
(graph.into_inner(), node_index)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let time_start = Instant::now();
|
||||
let input_str = read_to_string("input.txt").unwrap();
|
||||
let time_start_no_io = Instant::now();
|
||||
let (graph, _node_mapping) = parse_graph(&input_str);
|
||||
let (_cut_weight, cut_nodes) = stoer_wagner_cut(&graph);
|
||||
let multiplied_split = cut_nodes.len() * (graph.len() - cut_nodes.len());
|
||||
let elapsed = time_start.elapsed().as_micros();
|
||||
let elapsed_no_io = time_start_no_io.elapsed().as_micros();
|
||||
println!("Time: {}us", elapsed);
|
||||
println!("Time without file i/o: {}us", elapsed_no_io);
|
||||
println!("Cut into {}, {}, multiplied: {}", cut_nodes.len(), graph.len() - cut_nodes.len(), multiplied_split);
|
||||
}
|
@@ -2,7 +2,16 @@
|
||||
name = "day9"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
default-run = "main"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
||||
[[bin]]
|
||||
name = "main"
|
||||
path= "src/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "newton"
|
||||
path= "src/main_newton.rs"
|
||||
|
57
day9/src/main_newton.rs
Normal file
57
day9/src/main_newton.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
use std::fs::read_to_string;
|
||||
|
||||
fn get_numbers_in_line_iter<T: std::str::FromStr>(str: &str) -> impl Iterator<Item=T> + '_ {
|
||||
str.split_whitespace().filter_map(|substr| substr.parse::<T>().ok())
|
||||
}
|
||||
|
||||
fn polynomial_value(coeff: &Vec<f64>, x: f64) -> f64 {
|
||||
let mut result: f64 = 0.;
|
||||
let mut x_power: f64 = 1.;
|
||||
for &c in coeff {
|
||||
result += c * x_power;
|
||||
x_power *= x;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn newton_interpolation(x: &Vec<f64>, y: &Vec<f64>) -> Vec<f64> {
|
||||
let degree = std::cmp::min(x.len(), y.len());
|
||||
if degree == 0 {
|
||||
return vec![];
|
||||
}
|
||||
let mut result: Vec<f64> = Vec::with_capacity(degree);
|
||||
let mut w: Vec<f64> = Vec::with_capacity(degree);
|
||||
result.push(y[0]);
|
||||
w.push(x[0]);
|
||||
for i in 1..degree {
|
||||
w.push(1.);
|
||||
for j in 0..i {
|
||||
let xj = x[j];
|
||||
w.push(0.);
|
||||
for k in (0..=j).rev() {
|
||||
w[k + 1] += w[k];
|
||||
w[k] *= -xj;
|
||||
}
|
||||
}
|
||||
let a = (y[i] - polynomial_value(&result, x[i])) / polynomial_value(&w, x[i]);
|
||||
for j in 0..i {
|
||||
result[j] += a * w[j];
|
||||
}
|
||||
result.push(a * w[i]);
|
||||
w.clear();
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn main() {let mut sum1 = 0;
|
||||
let mut sum2 = 0;
|
||||
for line in read_to_string("input.txt").unwrap().lines() {
|
||||
let y = get_numbers_in_line_iter::<f64>(line).collect::<Vec<_>>();
|
||||
let x = (0..y.len()).map(|x| x as f64).collect::<Vec<_>>();
|
||||
let coeff = newton_interpolation(&x, &y);
|
||||
sum1 += polynomial_value(&coeff, y.len() as f64).round() as i32;
|
||||
sum2 += polynomial_value(&coeff, -1.).round() as i32;
|
||||
}
|
||||
println!("Sum1: {}", sum1);
|
||||
println!("Sum2: {}", sum2);
|
||||
}
|
Reference in New Issue
Block a user