optimized day 19
This commit is contained in:
parent
b319e46483
commit
b2744f9a7b
|
@ -19,24 +19,23 @@ bbrgwb",
|
||||||
|
|
||||||
pub fn run(input: &str) -> i64 {
|
pub fn run(input: &str) -> i64 {
|
||||||
let (towels, to_make) = input.split_once("\n\n").unwrap();
|
let (towels, to_make) = input.split_once("\n\n").unwrap();
|
||||||
let towels = towels.split(", ").map(|x| x.bytes().collect::<Vec<u8>>()).collect::<FxHashSet<Vec<u8>>>();
|
let towels = towels.split(", ").map(|x| remap(x.as_bytes())).collect::<FxHashSet<u64>>();
|
||||||
let to_make = to_make.lines().map(|x| x.bytes().collect::<Vec<u8>>());
|
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for pattern in to_make {
|
for pattern in to_make.lines() {
|
||||||
count += test(&towels, &pattern) as i64;
|
count += test(&towels, pattern.as_bytes()) as i64;
|
||||||
}
|
}
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(towels: &FxHashSet<Vec<u8>>, pattern: &[u8]) -> bool {
|
fn test(towels: &FxHashSet<u64>, pattern: &[u8]) -> bool {
|
||||||
let n = pattern.len();
|
let n = pattern.len();
|
||||||
let mut dp = vec![false; n + 1];
|
let mut dp = vec![false; n + 1];
|
||||||
dp[0] = true;
|
dp[0] = true;
|
||||||
|
|
||||||
for i in 1..n+1 {
|
for i in 1..n+1 {
|
||||||
for j in 0..i {
|
for j in 0..i {
|
||||||
if dp[j] && towels.contains(&pattern[j..i]) {
|
if dp[j] && (i - j <= 8 && towels.contains(&remap(&pattern[j..i]))) {
|
||||||
dp[i] = true;
|
dp[i] = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +45,18 @@ fn test(towels: &FxHashSet<Vec<u8>>, pattern: &[u8]) -> bool {
|
||||||
dp[n]
|
dp[n]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn remap(n: &[u8]) -> u64 {
|
||||||
|
let mut out = 0;
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n.len() {
|
||||||
|
out <<= 8;
|
||||||
|
out |= n[i as usize] as u64;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
for input in INPUTS.iter() {
|
for input in INPUTS.iter() {
|
||||||
println!("answer = {}", run(input));
|
println!("answer = {}", run(input));
|
||||||
|
|
|
@ -19,25 +19,27 @@ bbrgwb",
|
||||||
|
|
||||||
pub fn run(input: &str) -> i64 {
|
pub fn run(input: &str) -> i64 {
|
||||||
let (towels, to_make) = input.split_once("\n\n").unwrap();
|
let (towels, to_make) = input.split_once("\n\n").unwrap();
|
||||||
let towels = towels.split(", ").map(|x| x.bytes().collect::<Vec<u8>>()).collect::<FxHashSet<Vec<u8>>>();
|
let towels = towels.split(", ").map(|x| remap(x.as_bytes())).collect::<FxHashSet<u64>>();
|
||||||
let to_make = to_make.lines().map(|x| x.bytes().collect::<Vec<u8>>());
|
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for pattern in to_make {
|
for pattern in to_make.lines() {
|
||||||
let sum = test(&towels, &pattern);
|
count += test(&towels, pattern.as_bytes());
|
||||||
count += sum;
|
|
||||||
}
|
}
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test(towels: &FxHashSet<Vec<u8>>, pattern: &[u8]) -> i64 {
|
fn test(towels: &FxHashSet<u64>, pattern: &[u8]) -> i64 {
|
||||||
let n = pattern.len();
|
let n = pattern.len();
|
||||||
let mut dp = vec![0; n + 1];
|
let mut dp = vec![0; n + 1];
|
||||||
dp[0] = 1; // only 1 way to make an empty string
|
dp[0] = 1; // only 1 way to make an empty string
|
||||||
|
|
||||||
for i in 1..n+1 {
|
for i in 1..n+1 {
|
||||||
for j in 0..i {
|
for j in 0..i {
|
||||||
if towels.contains(&pattern[j..i]) {
|
// no word bigger than 8 chars
|
||||||
|
if i - j > 8 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if towels.contains(&remap(&pattern[j..i])) {
|
||||||
dp[i] += dp[j];
|
dp[i] += dp[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +48,18 @@ fn test(towels: &FxHashSet<Vec<u8>>, pattern: &[u8]) -> i64 {
|
||||||
dp[n]
|
dp[n]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn remap(n: &[u8]) -> u64 {
|
||||||
|
let mut out = 0;
|
||||||
|
let mut i = 0;
|
||||||
|
while i < n.len() {
|
||||||
|
out <<= 8;
|
||||||
|
out |= n[i as usize] as u64;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
for input in INPUTS.iter() {
|
for input in INPUTS.iter() {
|
||||||
println!("answer = {}", run(input));
|
println!("answer = {}", run(input));
|
||||||
|
@ -53,7 +67,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn part1(b: &mut test::Bencher) {
|
fn part2(b: &mut test::Bencher) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let v = run(INPUTS[1]);
|
let v = run(INPUTS[1]);
|
||||||
test::black_box(v);
|
test::black_box(v);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user