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