stole code and now it works
This commit is contained in:
parent
cafdfd324c
commit
e69bf8e9ff
File diff suppressed because it is too large
Load diff
1006
day_12/input.txt
1006
day_12/input.txt
File diff suppressed because it is too large
Load diff
|
@ -1,76 +1,71 @@
|
||||||
use std::{thread::{self, JoinHandle}, time::Instant};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
// i could just figure out a proper way but bruteforce is funnier
|
fn cache_key(cur: &String, instructions: &Vec<i32>) -> String {
|
||||||
// but also its still way too slow so ill fix it tomorrow maybe
|
return format!("{}:{:?}", cur, instructions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this approach is entirely stolen from github, i just rewrote it in rust
|
||||||
|
// i'm not in a state to make my braincells operate at the level required for this task
|
||||||
|
// was enough of a challenge to even get this to work at all because rust is a fucking nuisance with basic tasks
|
||||||
|
// https://github.com/jsgrosman/advent-code-challenges/blob/main/advent2023/advent12.ts <3
|
||||||
|
fn count_valid(in_str: &String, instructions: &Vec<i32>, cache: &mut HashMap<String, i64>) -> i64 {
|
||||||
|
if cache.contains_key(&cache_key(&in_str, &instructions)) {
|
||||||
|
return *cache.get(&cache_key(&in_str, &instructions)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let cur = Regex::new("(^\\.+)|(\\.+$)").unwrap().replace_all(&in_str, "");
|
||||||
|
|
||||||
|
let index_q = cur.chars().position(|c| c == '?');
|
||||||
|
let index_dot = cur.chars().position(|c| c == '.');
|
||||||
|
let index_hash = cur.chars().position(|c| c == '#');
|
||||||
|
|
||||||
|
if instructions.len() == 0 && index_q.is_none() && index_hash.is_none() {
|
||||||
|
return 1;
|
||||||
|
} else if instructions.len() == 0 && (index_q.unwrap_or(0) > 0 || index_hash.unwrap_or(0) > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if index_q.unwrap_or(cur.len()) < index_dot.unwrap_or(cur.len()) {
|
||||||
|
let with_hash = cur.replacen("?", "#", 1);
|
||||||
|
let with_dot = cur.replacen("?", ".", 1);
|
||||||
|
|
||||||
|
let val_with_hash = count_valid(&with_hash, instructions, cache);
|
||||||
|
let val_with_dot = count_valid(&with_dot, instructions, cache);
|
||||||
|
|
||||||
|
cache.insert(cache_key(&with_hash, &instructions), val_with_hash);
|
||||||
|
cache.insert(cache_key(&with_dot, &instructions), val_with_dot);
|
||||||
|
|
||||||
|
return val_with_hash + val_with_dot;
|
||||||
|
} else {
|
||||||
|
if instructions.len() > 0 && index_dot.unwrap_or(cur.len()) == *instructions.first().unwrap() as usize {
|
||||||
|
let next_pos = index_dot.unwrap_or(cur.len()) + 1;
|
||||||
|
return count_valid(&cur.chars().skip(next_pos).collect::<String>(), &instructions[1..].to_vec(), cache);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let start = Instant::now();
|
let input = include_str!("../../input.txt").lines();
|
||||||
let input_orig = include_str!("../../input.txt").lines();
|
let mut result: i64 = 0;
|
||||||
let mut inputs: Vec<Vec<&str>> = vec![];
|
|
||||||
|
|
||||||
let threads = input_orig.clone().count();
|
for line in input {
|
||||||
for i in 0..threads {
|
let mut cache: HashMap<String, i64> = HashMap::new();
|
||||||
let lines = input_orig.clone().skip(i).step_by(threads).collect::<Vec<&str>>();
|
|
||||||
inputs.push(lines);
|
// i fucking hate rusts lifetime garbage fuck this ownership garbage what is this
|
||||||
|
let mut parts = line.split(" ");
|
||||||
|
let field_in = parts.next().unwrap();
|
||||||
|
let field = format!("{field_in}?{field_in}?{field_in}?{field_in}?{field_in}");
|
||||||
|
let instructions_in = parts.next().unwrap();
|
||||||
|
let instructions_str = format!("{instructions_in},{instructions_in},{instructions_in},{instructions_in},{instructions_in}");
|
||||||
|
let instructions = instructions_str.split(",").map(|i| i.parse::<i32>().unwrap()).collect::<Vec<i32>>();
|
||||||
|
|
||||||
|
let res = count_valid(&field, &instructions, &mut cache);
|
||||||
|
println!("{res} - {field}");
|
||||||
|
result += res;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut handles: Vec<JoinHandle<i128>> = vec![];
|
println!("Result: {result}");
|
||||||
for input in inputs {
|
|
||||||
let handle = thread::spawn(|| {
|
|
||||||
let thread_start = Instant::now();
|
|
||||||
let mut result = 0;
|
|
||||||
let regex = Regex::new("#+").unwrap();
|
|
||||||
|
|
||||||
for line in input {
|
|
||||||
let mut parts = line.split(" ");
|
|
||||||
|
|
||||||
// i fucking hate rust fuck this ownership garbage what is this
|
|
||||||
let field_in = parts.next().unwrap();
|
|
||||||
let field_str = format!("{field_in}?{field_in}?{field_in}?{field_in}?{field_in}");
|
|
||||||
let instructions_in = parts.next().unwrap();
|
|
||||||
let instructions_str = format!("{instructions_in},{instructions_in},{instructions_in},{instructions_in},{instructions_in}");
|
|
||||||
let field = field_str.split("").filter(|i| i.len() > 0).collect::<Vec<&str>>();
|
|
||||||
let instructions = instructions_str.split(",").map(|i| i.parse::<i128>().unwrap()).collect::<Vec<i128>>();
|
|
||||||
|
|
||||||
// println!("{:?} {:?}", field, instructions);
|
|
||||||
|
|
||||||
let unknown_count = field.iter().filter(|i| i == &&"?").count();
|
|
||||||
for i in 0..i128::pow(2, unknown_count as u32) {
|
|
||||||
let mut current_field = field.clone();
|
|
||||||
let mut pos = 0;
|
|
||||||
|
|
||||||
for (j, spring) in current_field.clone().iter().enumerate() {
|
|
||||||
if spring == &"?" {
|
|
||||||
current_field[j] = if i & 1 << pos > 0 { "#" } else { "." };
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let field_str = current_field.join("");
|
|
||||||
let pairs = regex
|
|
||||||
.find_iter(field_str.as_str())
|
|
||||||
.map(|m| m.as_str().len() as i128)
|
|
||||||
.collect::<Vec<i128>>();
|
|
||||||
|
|
||||||
if pairs.len() == instructions.len() && pairs.iter().zip(&instructions).filter(|(a, b)| a != b).count() == 0 {
|
|
||||||
result += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Thread result: {result} (Thread finished in {} seconds)", thread_start.elapsed().as_secs());
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
handles.push(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut res = 0;
|
|
||||||
for handle in handles {
|
|
||||||
res += handle.join().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Final result: {} (After {} seconds)", res, start.elapsed().as_secs());
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue