Day 12
This commit is contained in:
parent
d0a7ddea55
commit
82aa5ccf03
16
day12/Cargo.lock
generated
Normal file
16
day12/Cargo.lock
generated
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.75"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||
|
||||
[[package]]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
]
|
9
day12/Cargo.toml
Normal file
9
day12/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "day12"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.75"
|
1000
day12/input
Normal file
1000
day12/input
Normal file
File diff suppressed because it is too large
Load Diff
363
day12/log
Normal file
363
day12/log
Normal file
@ -0,0 +1,363 @@
|
||||
Compiling day12 v0.1.0 (/home/max/aoc2023/day12)
|
||||
warning: unused imports: `Deref`, `Index`, `RangeBounds`, `Range`, `borrow::Borrow`
|
||||
--> src/main.rs:1:50
|
||||
|
|
||||
1 | use std::{str::FromStr, slice::SliceIndex, ops::{Index, Deref, RangeBounds, Range, RangeFrom}, borrow::Borrow, io::stdin, collections::Ha...
|
||||
| ^^^^^ ^^^^^ ^^^^^^^^^^^ ^^^^^ ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` on by default
|
||||
|
||||
warning: unused import: `slice::SliceIndex`
|
||||
--> src/main.rs:1:25
|
||||
|
|
||||
1 | use std::{str::FromStr, slice::SliceIndex, ops::{Index, Deref, RangeBounds, Range, RangeFrom}, borrow::Borrow, io::stdin, collections::Ha...
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: variable does not need to be mutable
|
||||
--> src/main.rs:194:9
|
||||
|
|
||||
194 | let mut rows: Vec<Row> = stdin().lines().map(|l| {
|
||||
| ----^^^^
|
||||
| |
|
||||
| help: remove this `mut`
|
||||
|
|
||||
= note: `#[warn(unused_mut)]` on by default
|
||||
|
||||
warning: methods `enumerate`, `optimize`, and `multiply` are never used
|
||||
--> src/main.rs:25:8
|
||||
|
|
||||
20 | impl Row {
|
||||
| -------- methods in this implementation
|
||||
...
|
||||
25 | fn enumerate<F>(&self, f: &mut F)
|
||||
| ^^^^^^^^^
|
||||
...
|
||||
32 | fn optimize(&mut self) {
|
||||
| ^^^^^^^^
|
||||
...
|
||||
44 | fn multiply(self, n: usize) -> Self {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: methods `compatible` and `enumerate` are never used
|
||||
--> src/main.rs:96:8
|
||||
|
|
||||
94 | impl <'r> RowView<'r> {
|
||||
| --------------------- methods in this implementation
|
||||
95 |
|
||||
96 | fn compatible(&self, buffer: &[bool]) -> bool {
|
||||
| ^^^^^^^^^^
|
||||
...
|
||||
148 | fn enumerate<F>(&self, buf: &mut [bool], window: RangeFrom<usize>, f: &mut F)
|
||||
| ^^^^^^^^^
|
||||
|
||||
warning: function `pretty` is never used
|
||||
--> src/main.rs:188:4
|
||||
|
|
||||
188 | fn pretty(row: &[bool]) -> String {
|
||||
| ^^^^^^
|
||||
|
||||
warning: `day12` (bin "day12") generated 6 warnings (run `cargo fix --bin "day12"` to apply 2 suggestions)
|
||||
Finished release [optimized] target(s) in 0.32s
|
||||
Running `target/release/day12`
|
||||
Counting solutions for RowView { bits: [None, None, None, Some(false), Some(true), Some(true), Some(true)], pattern: [1, 1, 3], freedom: 0 }
|
||||
Descending p=0 consumed=0 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=2 consumed=1 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=4 consumed=2 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=8 consumed=3 freedom=0
|
||||
no blocks remain
|
||||
1 at position 5
|
||||
1 at position 3
|
||||
1 at position 1
|
||||
Counting solutions for RowView { bits: [Some(false), None, None, Some(false), Some(false), None, None, Some(false), Some(false), Some(false), None, Some(true), Some(true), Some(false)], pattern: [1, 1, 3], freedom: 7 }
|
||||
Descending p=0 consumed=0 freedom=7
|
||||
Trying offset 0
|
||||
Bit cleared in range 0..1, continuing
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=3 consumed=1 freedom=6
|
||||
Trying offset 0
|
||||
Bit cleared in range 3..4, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 4..5, continuing
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Descending p=7 consumed=2 freedom=4
|
||||
Trying offset 0
|
||||
Bit cleared in range 7..10, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 8..11, continuing
|
||||
Trying offset 2
|
||||
Bit cleared in range 9..12, continuing
|
||||
Trying offset 3
|
||||
Descending...
|
||||
Descending p=14 consumed=3 freedom=1
|
||||
no blocks remain
|
||||
1 at position 11
|
||||
Trying offset 4
|
||||
Bit cleared in range 11..14, continuing
|
||||
1 at position 6
|
||||
Trying offset 3
|
||||
Descending...
|
||||
Descending p=8 consumed=2 freedom=3
|
||||
Trying offset 0
|
||||
Bit cleared in range 8..11, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 9..12, continuing
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 11
|
||||
Trying offset 3
|
||||
Bit cleared in range 11..14, continuing
|
||||
2 at position 7
|
||||
Trying offset 4
|
||||
Bit cleared in range 7..8, continuing
|
||||
Trying offset 5
|
||||
Bit cleared in range 8..9, continuing
|
||||
Trying offset 6
|
||||
Bit cleared in range 9..10, continuing
|
||||
2 at position 2
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Descending p=4 consumed=1 freedom=5
|
||||
Trying offset 0
|
||||
Bit cleared in range 4..5, continuing
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 6
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Cache hit
|
||||
2 at position 7
|
||||
Trying offset 3
|
||||
Bit cleared in range 7..8, continuing
|
||||
Trying offset 4
|
||||
Bit cleared in range 8..9, continuing
|
||||
Trying offset 5
|
||||
Bit cleared in range 9..10, continuing
|
||||
4 at position 3
|
||||
Trying offset 3
|
||||
Bit cleared in range 3..4, continuing
|
||||
Trying offset 4
|
||||
Bit cleared in range 4..5, continuing
|
||||
Trying offset 5
|
||||
Descending...
|
||||
Descending p=7 consumed=1 freedom=2
|
||||
Trying offset 0
|
||||
Bit cleared in range 7..8, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 8..9, continuing
|
||||
Trying offset 2
|
||||
Bit cleared in range 9..10, continuing
|
||||
4 at position 6
|
||||
Trying offset 6
|
||||
Descending...
|
||||
Descending p=8 consumed=1 freedom=1
|
||||
Trying offset 0
|
||||
Bit cleared in range 8..9, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 9..10, continuing
|
||||
4 at position 7
|
||||
Trying offset 7
|
||||
Bit cleared in range 7..8, continuing
|
||||
Counting solutions for RowView { bits: [None, Some(true), None, Some(true), None, Some(true), None, Some(true), None, Some(true), None, Some(true), None, Some(true), None], pattern: [1, 3, 1, 6], freedom: 1 }
|
||||
Descending p=0 consumed=0 freedom=1
|
||||
Trying offset 0
|
||||
found blocker at 1
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=3 consumed=1 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=7 consumed=2 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=9 consumed=3 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=16 consumed=4 freedom=0
|
||||
no blocks remain
|
||||
1 at position 10
|
||||
1 at position 8
|
||||
1 at position 4
|
||||
1 at position 2
|
||||
Counting solutions for RowView { bits: [None, None, None, None, Some(false), Some(true), Some(false), Some(false), Some(false), Some(true), Some(false), Some(false), Some(false)], pattern: [4, 1, 1], freedom: 5 }
|
||||
Descending p=0 consumed=0 freedom=5
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=5 consumed=1 freedom=5
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=7 consumed=2 freedom=5
|
||||
Trying offset 0
|
||||
Bit cleared in range 7..8, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 8..9, continuing
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Descending p=11 consumed=3 freedom=3
|
||||
no blocks remain
|
||||
1 at position 10
|
||||
Trying offset 3
|
||||
Bit 9 set, giving up
|
||||
1 at position 6
|
||||
Trying offset 1
|
||||
Bit 5 set, giving up
|
||||
1 at position 1
|
||||
Trying offset 1
|
||||
Bit cleared in range 1..5, continuing
|
||||
Trying offset 2
|
||||
Bit cleared in range 2..6, continuing
|
||||
Trying offset 3
|
||||
Bit cleared in range 3..7, continuing
|
||||
Trying offset 4
|
||||
Bit cleared in range 4..8, continuing
|
||||
Trying offset 5
|
||||
Bit cleared in range 5..9, continuing
|
||||
Counting solutions for RowView { bits: [None, None, None, None, Some(false), Some(true), Some(true), Some(true), Some(true), Some(true), Some(true), Some(false), Some(false), Some(true), Some(true), Some(true), Some(true), Some(true), Some(false)], pattern: [1, 6, 5], freedom: 5 }
|
||||
Descending p=0 consumed=0 freedom=5
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=2 consumed=1 freedom=5
|
||||
Trying offset 0
|
||||
Bit cleared in range 2..8, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 3..9, continuing
|
||||
Trying offset 2
|
||||
Bit cleared in range 4..10, continuing
|
||||
Trying offset 3
|
||||
Descending...
|
||||
Descending p=12 consumed=2 freedom=2
|
||||
Trying offset 0
|
||||
Bit cleared in range 12..17, continuing
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=19 consumed=3 freedom=1
|
||||
no blocks remain
|
||||
1 at position 14
|
||||
Trying offset 2
|
||||
Bit 13 set, giving up
|
||||
1 at position 6
|
||||
Trying offset 4
|
||||
Bit 5 set, giving up
|
||||
1 at position 1
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=3 consumed=1 freedom=4
|
||||
Trying offset 0
|
||||
Bit cleared in range 3..9, continuing
|
||||
Trying offset 1
|
||||
Bit cleared in range 4..10, continuing
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 6
|
||||
Trying offset 3
|
||||
Bit 5 set, giving up
|
||||
2 at position 2
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Descending p=4 consumed=1 freedom=3
|
||||
Trying offset 0
|
||||
Bit cleared in range 4..10, continuing
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 6
|
||||
Trying offset 2
|
||||
Bit 5 set, giving up
|
||||
3 at position 3
|
||||
Trying offset 3
|
||||
Descending...
|
||||
Descending p=5 consumed=1 freedom=2
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 6
|
||||
Trying offset 1
|
||||
Bit 5 set, giving up
|
||||
4 at position 4
|
||||
Trying offset 4
|
||||
Bit cleared in range 4..5, continuing
|
||||
Trying offset 5
|
||||
found blocker at 6
|
||||
Counting solutions for RowView { bits: [None, Some(true), Some(true), Some(true), None, None, None, None, None, None, None, None], pattern: [3, 2, 1], freedom: 4 }
|
||||
Descending p=0 consumed=0 freedom=4
|
||||
Trying offset 0
|
||||
found blocker at 3
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=5 consumed=1 freedom=3
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=8 consumed=2 freedom=3
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Descending p=10 consumed=3 freedom=3
|
||||
no blocks remain
|
||||
1 at position 9
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=11 consumed=3 freedom=2
|
||||
no blocks remain
|
||||
2 at position 10
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Descending p=12 consumed=3 freedom=1
|
||||
no blocks remain
|
||||
3 at position 11
|
||||
Trying offset 3
|
||||
Descending...
|
||||
Descending p=13 consumed=3 freedom=0
|
||||
no blocks remain
|
||||
4 at position 12
|
||||
4 at position 6
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Descending p=9 consumed=2 freedom=2
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 10
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Cache hit
|
||||
2 at position 11
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Cache hit
|
||||
3 at position 12
|
||||
7 at position 7
|
||||
Trying offset 2
|
||||
Descending...
|
||||
Descending p=10 consumed=2 freedom=1
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 11
|
||||
Trying offset 1
|
||||
Descending...
|
||||
Cache hit
|
||||
2 at position 12
|
||||
9 at position 8
|
||||
Trying offset 3
|
||||
Descending...
|
||||
Descending p=11 consumed=2 freedom=0
|
||||
Trying offset 0
|
||||
Descending...
|
||||
Cache hit
|
||||
1 at position 12
|
||||
10 at position 9
|
||||
10 at position 2
|
||||
Trying offset 2
|
||||
Bit 1 set, giving up
|
||||
Part 1: Total: 21
|
242
day12/src/main.rs
Normal file
242
day12/src/main.rs
Normal file
@ -0,0 +1,242 @@
|
||||
use std::{str::FromStr, ops::RangeFrom, io::stdin, collections::HashMap, fmt::Display};
|
||||
use anyhow::{Result, Error, anyhow};
|
||||
|
||||
#[derive(Debug,Clone,PartialEq,Eq)]
|
||||
struct Row {
|
||||
bits: Vec<Option<bool>>,
|
||||
pattern: Vec<usize>,
|
||||
freedom: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct RowView<'r> {
|
||||
bits: &'r [Option<bool>],
|
||||
pattern: &'r [usize],
|
||||
freedom: usize,
|
||||
}
|
||||
|
||||
type Cache = HashMap<(usize,usize), usize>;
|
||||
|
||||
impl Row {
|
||||
fn view(&self) -> RowView<'_> {
|
||||
RowView { bits: &self.bits, pattern: &self.pattern, freedom: self.freedom }
|
||||
}
|
||||
|
||||
fn enumerate<F>(&self, f: &mut F)
|
||||
where F: FnMut(&[bool])
|
||||
{
|
||||
let mut buf = vec![false; self.bits.len()];
|
||||
self.view().enumerate(&mut buf, 0.., f);
|
||||
}
|
||||
|
||||
fn optimize(&mut self) {
|
||||
let mut offset = 0;
|
||||
for &block in &self.pattern {
|
||||
if block > self.freedom {
|
||||
for cell in &mut self.bits[offset + self.freedom .. offset + block] {
|
||||
*cell = Some(true)
|
||||
}
|
||||
}
|
||||
offset += block + 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn multiply(self, n: usize) -> Self {
|
||||
let mut bits = self.bits;
|
||||
bits.push(None);
|
||||
bits = bits.repeat(n);
|
||||
bits.pop();
|
||||
|
||||
let pattern = self.pattern.repeat(n);
|
||||
|
||||
Row { bits, pattern, freedom: self.freedom * n}
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.view().count()
|
||||
}
|
||||
|
||||
fn exhaustive_count(&self) -> usize {
|
||||
self.view().exhaustive_count()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl FromStr for Row {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let (bits, nums) = s.split_once(' ')
|
||||
.ok_or_else(|| anyhow!("Bad line {s}"))?;
|
||||
|
||||
let bits = bits.chars()
|
||||
.map(|c| match c {
|
||||
'.' => Ok(Some(false)),
|
||||
'#' => Ok(Some(true)),
|
||||
'?' => Ok(None),
|
||||
oth => Err(anyhow!("Invalid character {oth}")),
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
let pattern = nums.split(',')
|
||||
.map(str::parse)
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let size = (pattern.iter().sum::<usize>() + pattern.len())
|
||||
.saturating_sub(1);
|
||||
|
||||
let freedom = bits.len()
|
||||
.checked_sub(size).ok_or_else(|| anyhow!("Unsolvable row {s}"))?;
|
||||
|
||||
Ok(Self { bits, pattern, freedom })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Display for Row {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for bit in &self.bits {
|
||||
write!(f, "{}", match bit {
|
||||
None => '?',
|
||||
Some(false) => '.',
|
||||
Some(true) => '#',
|
||||
})?;
|
||||
}
|
||||
write!(f, "{:?}", &self.pattern)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl <'r> RowView<'r> {
|
||||
|
||||
fn exhaustive_count(&self) -> usize {
|
||||
let mut c = 0;
|
||||
let mut buf = vec![false; self.bits.len()];
|
||||
self.enumerate(&mut buf, 0.., &mut |_| c += 1);
|
||||
c
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.dfs(0, 0, self.freedom, &mut HashMap::new())
|
||||
}
|
||||
|
||||
fn dfs(&self, position: usize, consumed: usize, freedom: usize, cache: &mut Cache) -> usize {
|
||||
//eprintln!("DFS enter position={position} consumed={consumed} freedom={freedom}");
|
||||
fn cached_dfs(this: &RowView, position: usize, consumed: usize, freedom: usize, cache: &mut Cache) -> usize {
|
||||
if let Some(&solutions) = cache.get(&(consumed, position)) {
|
||||
//eprintln!("Cache hit for position={position} consumed={consumed} freedom={freedom} = {solutions}");
|
||||
return solutions
|
||||
}
|
||||
|
||||
let solutions = this.dfs(position, consumed, freedom, cache);
|
||||
cache.insert((consumed, position), solutions);
|
||||
solutions
|
||||
}
|
||||
|
||||
if consumed == self.pattern.len() {
|
||||
if position <= self.bits.len() && self.bits[position..].iter().any(|b| b == &Some(true)) {
|
||||
//eprintln!("Terminal conflict");
|
||||
0
|
||||
} else {
|
||||
//eprintln!("Valid solution");
|
||||
1
|
||||
}
|
||||
} else {
|
||||
let current = self.pattern[consumed];
|
||||
let mut solutions = 0;
|
||||
for offset in 0..=freedom {
|
||||
// Uncovered bit in prefix space, no point in continuing
|
||||
if offset > 0 && self.bits[position+offset-1] == Some(true) { break }
|
||||
|
||||
// Block collides with empty cell, try next offset
|
||||
if self.bits[position+offset..][..current].iter().any(|b| b == &Some(false)) { continue }
|
||||
|
||||
// Block is not last and cell following block is not empty
|
||||
if position+offset+current < self.bits.len() && self.bits[position+offset+current] == Some(true) { continue }
|
||||
|
||||
solutions += cached_dfs(&self, position+offset+current+1, consumed+1, freedom - offset, cache);
|
||||
}
|
||||
//eprintln!("DFS leave position={position} consumed={consumed} freedom={freedom} -> {solutions}");
|
||||
solutions
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn enumerate<F>(&self, buf: &mut [bool], window: RangeFrom<usize>, f: &mut F)
|
||||
where F: FnMut(&[bool])
|
||||
{
|
||||
if let Some((&h, rest)) = self.pattern.split_first() {
|
||||
for offset in 0..=self.freedom {
|
||||
|
||||
if self.bits[..offset].iter().any(|b| b == &Some(true)) { continue }
|
||||
for b in &mut buf[window.clone()][..offset] {
|
||||
*b = false;
|
||||
}
|
||||
|
||||
if self.bits[offset..][..h].iter().any(|b| b == &Some(false)) { continue }
|
||||
for b in &mut buf[window.clone()][offset..][..h] {
|
||||
*b = true;
|
||||
}
|
||||
|
||||
if rest.len() == 0 {
|
||||
RowView { pattern: rest, bits: &self.bits[offset+h..], freedom: self.freedom - offset}
|
||||
.enumerate(buf, window.start + offset + h .., f);
|
||||
} else {
|
||||
if self.bits[offset + h] == Some(true) { continue; }
|
||||
buf[window.clone()][offset + h] = false;
|
||||
RowView { pattern: rest, bits: &self.bits[offset+h+1..], freedom: self.freedom - offset }
|
||||
.enumerate(buf, window.start + offset + h + 1 .., f);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
for b in buf[window.clone()].iter_mut() { *b = false }
|
||||
if self.compatible(&buf[window]) {
|
||||
f(&buf)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
fn pretty(row: &[bool]) -> String {
|
||||
row.iter().map(|&f| if f {'#'} else {'.'}).collect()
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_optimization() {
|
||||
let row: Row = "#??##????#??? 8,1,1".parse().unwrap();
|
||||
let row2 = row.clone();
|
||||
assert_eq!(row.count(), row2.count());
|
||||
}
|
||||
fn main() -> Result<()> {
|
||||
|
||||
let rows: Vec<Row> = stdin().lines().map(|l| {
|
||||
l.unwrap().parse().unwrap()
|
||||
}).collect();
|
||||
|
||||
{
|
||||
let mut rows = rows.clone();
|
||||
|
||||
for row in &mut rows {
|
||||
row.optimize();
|
||||
}
|
||||
|
||||
let total: usize = rows.iter().map(Row::count).sum();
|
||||
println!("Part 1: Total: {total}");
|
||||
|
||||
}
|
||||
|
||||
|
||||
let mut rows: Vec<Row> = rows.into_iter().map(|r| r.multiply(5)).collect();
|
||||
for r in &mut rows { r.optimize() }
|
||||
|
||||
let total: usize = rows.iter().map(Row::count).sum();
|
||||
println!("Part 2: Total: {total}");
|
||||
|
||||
Ok(())
|
||||
|
||||
}
|
6
day12/test
Normal file
6
day12/test
Normal file
@ -0,0 +1,6 @@
|
||||
???.### 1,1,3
|
||||
.??..??...?##. 1,1,3
|
||||
?#?#?#?#?#?#?#? 1,3,1,6
|
||||
????.#...#... 4,1,1
|
||||
????.######..#####. 1,6,5
|
||||
?###???????? 3,2,1
|
Loading…
Reference in New Issue
Block a user