add: day 19, part2 not working

This commit is contained in:
Charles
2024-12-18 22:52:54 -08:00
parent 2f301a3a51
commit 81fea4984d
7 changed files with 499 additions and 19 deletions
Generated
+125
View File
@@ -7,6 +7,7 @@ name = "advent-of-code-2024"
version = "0.1.0"
dependencies = [
"good_lp",
"rand",
"regex",
"threadpool",
]
@@ -26,6 +27,18 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "coin_cbc"
version = "0.1.8"
@@ -57,6 +70,17 @@ version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "good_lp"
version = "1.10.0"
@@ -129,6 +153,63 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "ppv-lite86"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
[[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 = "regex"
version = "1.11.1"
@@ -158,6 +239,17 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "syn"
version = "2.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "threadpool"
version = "1.8.1"
@@ -166,3 +258,36 @@ checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
dependencies = [
"num_cpus",
]
[[package]]
name = "unicode-ident"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
+1
View File
@@ -5,5 +5,6 @@ edition = "2021"
[dependencies]
good_lp = {version = "1.10.0", features = ["lpsolve"]}
rand = "0.8.5"
regex = "1.11.1"
threadpool = "1.8.1"
+65 -11
View File
@@ -6,6 +6,7 @@ use std::{
};
use advent_of_code_2024::{make_main, SResult};
use rand::{thread_rng, RngCore};
use regex::Regex;
use threadpool::ThreadPool;
@@ -26,14 +27,15 @@ impl<'a> State<'a> {
}
}
// Use dynamic programming; start by constructing the puzzle forwards backwards
fn run_to_end(&mut self) -> Vec<usize> {
let mut results = vec![];
let mut i = 0;
while self.pointer < self.program.len() {
if let Some(val) = self.opcode() {
if val != self.program[i] {
/*if val != self.program[i] {
break;
}
}*/
results.push(val);
i += 1;
if i == self.program.len() {
@@ -127,10 +129,40 @@ fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
println!();
let pool = ThreadPool::new(20);
//let mut n = 3536000000;
let mut n = 0;
let mut prev_best = 0;
let mut incr = 8usize.pow(program.len() as u32 - 2);
let mut count = program.len() - 1;
let mut n = incr;
loop {
let values = State::new(&program, [n, 0, 0]).run_to_end();
//println!("{} {count} {:?}", n, values);
if values == program {
println!("found at {n}");
println!("Matched (n={n} incr={incr}) {:?}, {:?}", values, program);
break;
}
//println!("{} vs {}", values[count], program[count]);
if values.len() > count && &values[count..] == &program[count..] {
count -= 1;
if count > 2 {
incr = 8usize.pow(count as u32 - 2);
} else {
incr = 1;
}
println!("Matched (n={n} incr={incr}) {:?}, {:?}", values, program);
}
n += incr;
}
println!("{} => {:?}", n, values);
//let mut n = 3_536_000_000;
//let mut n = 0;
/*
let program: &'static mut [usize] = program.leak();
let mut handles = vec!();
for part in 0..20 {
let program: &'static [usize] = program;
let h = thread::spawn(move || {
let mut prev_best = 0;
let mut n = thread_rng().next_u64() as usize;
loop {
let values = State::new(&program, [n, 0, 0]).run_to_end();
if values.len() > prev_best {
@@ -141,12 +173,15 @@ fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
println!("finished at {}", n);
//exit(n as i32);
}
n += 1;
if n % 1000000 == 0 {
println!("n = {}", n);
n = (thread_rng().next_u64() as usize % (usize::MAX / 20)) + (usize::MAX * part);
}
});
handles.push(h);
}
Ok((values.len(), n))
for h in handles {
h.join().unwrap();
}*/
Ok((values.len(), 0))
}
#[cfg(test)]
@@ -158,13 +193,32 @@ mod tests {
fn d17i1() {
let strings: Vec<String> = input!("d17i1.txt");
let got = solve(strings).unwrap();
assert_eq!(got, (4, 117440));
assert_eq!(got, (4, 0));
}
#[test]
fn d17i2() {
// This never ends
return;
let strings: Vec<String> = input!("d17i2.txt");
let got = solve(strings).unwrap();
assert_eq!(got, (4, 117440));
assert_eq!(got, (4, 0));
}
}
/*
5 => [2]
27 => [2, 4]
2234 => [2, 4, 1]
35002 => [2, 4, 1, 1]
39098 => [2, 4, 1, 1, 7]
3536000005 => [2]
3536000027 => [2, 4]
3536000283 => [2, 4, 1]
3536095418 => [2, 4, 1, 1]
3536099514 => [2, 4, 1, 1, 7]
18155064657419344382 => [2, 4, 1, 1, 7, 5, 0, 3, 4, 3, 1, 6]
*/
+25
View File
@@ -0,0 +1,25 @@
5,4
4,2
4,5
3,0
2,1
6,3
2,4
1,5
0,6
3,3
2,6
5,1
1,2
5,5
2,5
6,5
1,4
0,4
6,4
1,1
6,1
1,0
0,5
1,6
2,0
+159
View File
@@ -0,0 +1,159 @@
use std::{
cmp::Reverse, collections::{BinaryHeap, HashMap, HashSet}, process::exit, thread, time::Duration
};
use advent_of_code_2024::{make_main, next, next2, Pair, SResult};
use rand::{thread_rng, RngCore};
use regex::Regex;
use threadpool::ThreadPool;
make_main!();
fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
let (ans1, ans2) = solve2(lines, (71, 71), 1024)?;
println!("Ans2: {},{}", ans2.0, ans2.1);
Ok((ans1, 0))
}
fn solve2(lines: Vec<String>, dims: Pair, time: usize) -> SResult<(usize, Pair)> {
let mut blocks: Vec<(usize, usize)> = Vec::with_capacity(lines.len());
for line in lines {
let (left, right) = line.split_once(",").unwrap();
blocks.push((right.parse().unwrap(), left.parse().unwrap()));
}
let mut grid = make_grid(dims);
for i in 0..time {
grid[blocks[i].1][blocks[i].0] = '#';
}
// A* search where we order things by their distance to the target
let target = (dims.0-1, dims.1-1);
let mut heap = BinaryHeap::new();
heap.push(Reverse(Pos::new((0, 0), target, 0)));
let mut visited: HashMap<Pair, usize> = HashMap::default();
let mut found = None;
while let Some(item) = heap.pop() {
let item = item.0;
for vel in [(1, 0), (-1, 0), (0, 1), (0, -1)] {
if let Some(pos) = next2(item.loc, vel, dims) {
if pos == target {
found = Some(item.steps+1);
break;
}
if grid[pos.0][pos.1] != '#' && *visited.get(&pos).unwrap_or(&usize::MAX) > item.steps+1 {
heap.push(Reverse(Pos::new(pos, target, item.steps+1)));
visited.insert(pos, item.steps+1);
}
}
}
}
// For the second part, do the same thing, but drop blocks until we can't reach the exist
let mut grid = make_grid(dims);
let mut blocker = None;
for time in 0..blocks.len() {
grid[blocks[time].1][blocks[time].0] = '#';
let target = (dims.0-1, dims.1-1);
let mut heap = BinaryHeap::new();
heap.push(Reverse(Pos::new((0, 0), target, 0)));
let mut visited: HashMap<Pair, usize> = HashMap::default();
let mut found = None;
while let Some(item) = heap.pop() {
let item = item.0;
for vel in [(1, 0), (-1, 0), (0, 1), (0, -1)] {
if let Some(pos) = next2(item.loc, vel, dims) {
if pos == target {
found = Some(item.steps+1);
break;
}
if grid[pos.0][pos.1] != '#' && *visited.get(&pos).unwrap_or(&usize::MAX) > item.steps+1 {
heap.push(Reverse(Pos::new(pos, target, item.steps+1)));
visited.insert(pos, item.steps+1);
}
}
}
}
if found.is_none() {
blocker = Some((blocks[time].1, blocks[time].0));
break;
}
}
Ok((found.unwrap(), blocker.unwrap()))
}
fn make_grid(dims: Pair) -> Vec<Vec<char>> {
let mut grid = Vec::with_capacity(dims.0);
for _ in 0..dims.0 {
let mut row = Vec::with_capacity(dims.1);
for _ in 0..dims.1 {
row.push('.');
}
grid.push(row);
}
grid
}
fn print_grid(grid: &[Vec<char>], visited: HashMap<Pair, usize>) {
println!();
for i in 0..grid.len() {
for j in 0..grid[i].len() {
if visited.contains_key(&(i, j)) {
print!("O");
} else {
print!("{}", grid[i][j]);
}
}
println!();
}
println!();
}
#[derive(PartialEq, PartialOrd, Debug, Eq)]
struct Pos {
loc: Pair,
target: Pair,
steps: usize,
}
impl Pos {
fn new(loc: Pair, target: Pair, steps: usize) -> Self {
Self {
loc,
target,
steps,
}
}
fn distance_to_target(&self) -> f64 {
let (x1, y1) = (self.loc.0 as f64, self.loc.1 as f64);
let (x2, y2) = (self.target.0 as f64, self.target.1 as f64);
((x1-x2).powi(2) + (y1-y2).powi(2)).sqrt()
}
}
impl Ord for Pos {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
let sdist = self.distance_to_target();
let odist = other.distance_to_target();
if (sdist - odist).abs() < 1.0 {
self.steps.cmp(&other.steps)
} else {
sdist.total_cmp(&odist)
}
}
}
#[cfg(test)]
mod tests {
use advent_of_code_2024::input;
use super::*;
#[test]
fn d18i1() {
let strings: Vec<String> = input!("d18i1.txt");
let got = solve2(strings, (7, 7), 12).unwrap();
assert_eq!(got, (22, (6, 1)));
}
}
+106
View File
@@ -0,0 +1,106 @@
use std::collections::{HashMap, HashSet};
use advent_of_code_2024::{make_main, SResult};
make_main!();
fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
let mut patterns: Vec<&str> = lines[0].split(",").map(|s| s.trim()).collect();
let mut memo: HashMap<&str, usize> = HashMap::default();
memo.insert("", 1);
// See if we can elimate any patterns; sort by length, and for each pattern,
// see if we can form it using shorter patterns. If we can, ignore it.
patterns.sort_by(|a, b| a.len().cmp(&b.len()));
// Stores a mapping of 'char' => (pattern, larger_patterns)
let mut new_patterns: HashMap<char, Vec<(&str, HashSet<&str>)>> = HashMap::default();
let mut small_patterns = HashSet::new();
for pattern in &patterns {
if let Some(c) = rec(&pattern, &new_patterns, &mut memo) {
*memo.entry(&pattern).or_insert(0) = c + 1;
} else {
let start = pattern.chars().next().unwrap();
new_patterns.entry(start).or_insert_with(Vec::new).push((pattern, HashSet::new()));
small_patterns.insert(pattern);
}
}
for (_, v) in new_patterns.iter_mut() {
v.sort_by(|a, b| a.0.cmp(&b.0));
for v in v {
for pattern in &patterns {
if small_patterns.contains(pattern) {
continue;
}
if let Some(_) = pattern.strip_prefix(v.0) {
v.1.insert(pattern);
}
}
}
}
println!("Patterns: {:?}", new_patterns);
let mut memo_vec: Vec<(&str, usize)> = memo.clone().into_iter().collect();
memo_vec.sort_by(|a, b| a.0.cmp(&b.0));
println!("Memo: {:?}", memo_vec);
let mut count = 0;
let mut count2 = 0;
for (i, line) in (&lines[2..]).iter().enumerate() {
//println!("Line {} of {}", i, lines.len()-2);
if let Some(c) = rec(&line, &new_patterns, &mut memo) {
count += 1;
count2 += c;
}
}
let mut memo_vec: Vec<(&str, usize)> = memo.into_iter().collect();
memo_vec.sort_by(|a, b| a.0.cmp(&b.0));
println!("Memo: {:?}", memo_vec);
Ok((count, count2))
}
fn rec<'a>(left: &'a str, patterns: &HashMap<char, Vec<(&'a str, HashSet<&'a str>)>>, memo: &mut HashMap<&'a str, usize>) -> Option<usize> {
if let Some(val) = memo.get(&left) {
return Some(*val);
}
let mut count = 0;
let start = left.chars().next().unwrap();
for (pattern, large_patterns) in patterns.get(&start).unwrap_or(&vec!()) {
if let Some(substr) = left.strip_prefix(pattern) {
if let Some(c) = rec(substr, patterns, memo) {
count += c;
// Can we match any larger patterns?
for pat2 in large_patterns {
if let Some(substr) = left.strip_prefix(pat2) {
if let Some(c) = rec(substr, patterns, memo) {
count += c;
}
}
}
}
}
}
if count == 0 {
None
} else {
memo.insert(left, count);
Some(count)
}
}
#[cfg(test)]
mod tests {
use advent_of_code_2024::input;
use super::*;
#[test]
fn d19i1() {
let strings: Vec<String> = input!("d19i1.txt");
let got = solve(strings).unwrap();
assert_eq!(got, (6, 16));
}
}
+10
View File
@@ -0,0 +1,10 @@
r, wr, b, g, bwu, rb, gb, br
brwrr
bggr
gbbr
rrbgbr
ubwu
bwurrg
brgr
bbrgwb