This commit is contained in:
Drew Galbraith 2023-12-12 23:59:19 -08:00
parent 4df00cc74d
commit 1bc006c82e
3 changed files with 1146 additions and 0 deletions

1000
input/day12.txt Normal file

File diff suppressed because it is too large Load Diff

143
src/day12.rs Normal file
View File

@ -0,0 +1,143 @@
use std::collections::HashMap;
use std::io;
use std::io::Read;
type Cache = HashMap<(usize, u32, usize), u64>;
fn try_get_consume(
remaining_str: &[u8],
curr_run: u32,
remaining_spec: &[u32],
cache: &mut Cache,
) -> u64 {
let cache_key = (remaining_str.len(), curr_run, remaining_spec.len());
if cache.contains_key(&cache_key) {
return *cache.get(&(cache_key)).unwrap();
}
let result = try_consume(remaining_str, curr_run, remaining_spec, cache);
cache.insert(cache_key, result);
return result;
}
fn try_consume(
remaining_str: &[u8],
curr_run: u32,
remaining_spec: &[u32],
cache: &mut Cache,
) -> u64 {
if !remaining_spec.is_empty()
&& (remaining_spec.iter().sum::<u32>() + remaining_spec.len() as u32 - 1)
> (remaining_str.len() as u32 + curr_run)
{
return 0;
}
if remaining_str.is_empty() {
if curr_run != 0 {
if remaining_spec.len() != 1 || curr_run != remaining_spec[0] {
return 0;
}
return 1;
}
// No current run, check that the remaining spec is empty.
if remaining_spec.is_empty() {
return 1;
}
return 0;
}
if remaining_spec.is_empty() && curr_run > 0 {
return 0;
}
match remaining_str[0] {
b'.' => {
if curr_run == 0 {
return try_get_consume(&remaining_str[1..], 0, &remaining_spec, cache);
} else if curr_run == remaining_spec[0] {
return try_get_consume(&remaining_str[1..], 0, &remaining_spec[1..], cache);
} else {
return 0;
}
}
b'#' => {
return try_get_consume(&remaining_str[1..], curr_run + 1, remaining_spec, cache);
}
b'?' => {
if remaining_spec.is_empty() {
// This must be a .
return try_get_consume(&remaining_str[1..], 0, &remaining_spec, cache);
} else if curr_run == remaining_spec[0] {
// This must be a .
return try_get_consume(&remaining_str[1..], 0, &remaining_spec[1..], cache);
} else if curr_run > 0 {
// This must be a #
return try_get_consume(&remaining_str[1..], curr_run + 1, &remaining_spec, cache);
} else {
// Try both
let dot_cnt = try_get_consume(&remaining_str[1..], 0, &remaining_spec, cache);
let hash_cnt = try_get_consume(&remaining_str[1..], 1, &remaining_spec, cache);
/*
println!(
"String: {:?}\nSpec: {:?}\nDot: {}, Hash: {}",
std::str::from_utf8(remaining_str),
remaining_spec,
dot_cnt,
hash_cnt
);
*/
return dot_cnt + hash_cnt;
}
}
_ => panic!("Unexpected character"),
}
}
fn check_record(record: &(Vec<u8>, Vec<u32>)) -> u64 {
let mut cache: Cache = HashMap::new();
try_consume(&record.0, 0, &record.1, &mut cache)
}
fn check_records(records: Vec<(Vec<u8>, Vec<u32>)>) -> u64 {
records.iter().fold(0, |acc, r| acc + check_record(r))
}
pub fn sum_arrangements(duplicate: bool) -> u64 {
let mut buffer = Vec::new();
io::stdin().read_to_end(&mut buffer).unwrap();
let lines = buffer.split(|c| *c == b'\n');
let mut records: Vec<(Vec<u8>, Vec<u32>)> = Vec::new();
for line in lines {
if line.len() == 0 {
continue;
}
let mut linesplit = line.split(|c| *c == b' ');
let springs = linesplit.next().unwrap();
let configs: Vec<_> = linesplit
.next()
.unwrap()
.split(|c| *c == b',')
.map(|n| std::str::from_utf8(n).expect("").parse().expect(""))
.collect();
let spring_vec = if duplicate {
let mut vec = Vec::new();
for _ in 0..5 {
vec.extend_from_slice(springs);
vec.push(b'?');
}
vec.pop();
vec
} else {
springs.to_vec()
};
let config_vec = if duplicate {
let mut vec = Vec::new();
for _ in 0..5 {
vec.extend_from_slice(&configs);
}
vec
} else {
configs.to_vec()
};
records.push((spring_vec, config_vec));
}
check_records(records)
}

View File

@ -3,6 +3,7 @@ use std::env;
mod day1;
mod day10;
mod day11;
mod day12;
mod day2;
mod day3;
mod day4;
@ -41,6 +42,8 @@ fn main() {
"day10b" => println!("Contains: {}", day10::num_steps().1),
"day11a" => println!("Sum: {}", day11::sum_lengths(1)),
"day11b" => println!("Sum: {}", day11::sum_lengths(999999)),
"day12a" => println!("Sum: {}", day12::sum_arrangements(false)),
"day12b" => println!("Sum: {}", day12::sum_arrangements(true)),
_ => println!("Unrecognized day: {}", args[1]),
}
}