day 13 part 1
This commit is contained in:
parent
f458030577
commit
50f217eea0
3 changed files with 1455 additions and 1097 deletions
21
example.txt
21
example.txt
|
@ -1,6 +1,15 @@
|
||||||
???.### 1,1,3
|
#.##..##.
|
||||||
.??..??...?##. 1,1,3
|
..#.##.#.
|
||||||
?#?#?#?#?#?#?#? 1,3,1,6
|
##......#
|
||||||
????.#...#... 4,1,1
|
##......#
|
||||||
????.######..#####. 1,6,5
|
..#.##.#.
|
||||||
?###???????? 3,2,1
|
..##..##.
|
||||||
|
#.#.##.#.
|
||||||
|
|
||||||
|
#...##..#
|
||||||
|
#....#..#
|
||||||
|
..##..###
|
||||||
|
#####.##.
|
||||||
|
#####.##.
|
||||||
|
..##..###
|
||||||
|
#....#..#
|
||||||
|
|
164
src/main.rs
164
src/main.rs
|
@ -1,90 +1,84 @@
|
||||||
use std::{collections::HashMap, io::stdin};
|
use std::{collections::HashSet, io::stdin, vec};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
fn matches(conditions: &str, group: &str) -> bool {
|
fn mirror_points(line: &[char]) -> Vec<usize> {
|
||||||
for (g, c) in group.chars().zip(conditions.chars()) {
|
let mut result = vec![];
|
||||||
if c == '?' {
|
for i in 1..line.len() {
|
||||||
continue;
|
let mut mirror = true;
|
||||||
}
|
for j in 0..i {
|
||||||
if g == c {
|
if i + j >= line.len() {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
type Cache = HashMap<String, i64>;
|
|
||||||
|
|
||||||
fn arrangements_inner(conditions: &str, groups: &[String], cache: &mut Cache) -> i64 {
|
|
||||||
let g = &groups[0];
|
|
||||||
let w = conditions.len() - groups.iter().skip(1).map(|s| s.len()).sum::<usize>();
|
|
||||||
|
|
||||||
let positions = w - g.len() + 1;
|
|
||||||
let mut sum = 0;
|
|
||||||
for i in 0..positions {
|
|
||||||
if !matches(&conditions[i..], g) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if conditions[..i].contains('#') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let after = if (i + g.len()) < conditions.len() {
|
|
||||||
conditions.chars().nth(i + g.len()).unwrap()
|
|
||||||
} else {
|
|
||||||
'.'
|
|
||||||
};
|
|
||||||
if after == '#' {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if groups.len() == 1 {
|
|
||||||
if conditions[i + g.len()..].contains('#') {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sum += 1;
|
if line[i - j - 1] != line[i + j] {
|
||||||
|
mirror = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if mirror {
|
||||||
|
result.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vertical_mirror_points(grid: &Vec<Vec<char>>) -> HashSet<usize> {
|
||||||
|
let mut s: HashSet<usize> = HashSet::new();
|
||||||
|
for row in grid {
|
||||||
|
let n: HashSet<usize> = mirror_points(row).iter().copied().collect();
|
||||||
|
if s.is_empty() {
|
||||||
|
s = n;
|
||||||
} else {
|
} else {
|
||||||
let cache_key = format!("{},{:?}", &conditions[i + g.len()..], &groups[1..]);
|
s = s.intersection(&n).cloned().collect();
|
||||||
if let Some(v) = cache.get(&cache_key) {
|
if s.is_empty() {
|
||||||
sum += v;
|
return s;
|
||||||
} else {
|
|
||||||
let a = arrangements_inner(&conditions[i + g.len()..], &groups[1..], cache);
|
|
||||||
cache.insert(cache_key, a);
|
|
||||||
sum += a;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sum
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arrangements(conditions: &str, groups: &[usize]) -> i64 {
|
fn horizontal_mirror_points(grid: &Vec<Vec<char>>) -> HashSet<usize> {
|
||||||
let mut group_strings = vec![];
|
let mut s: HashSet<usize> = HashSet::new();
|
||||||
group_strings.push("#".repeat(groups[0]).to_owned());
|
for x in 0..grid[0].len() {
|
||||||
for g in groups.iter().skip(1) {
|
let mut column = vec![];
|
||||||
group_strings.push(".".to_owned() + &"#".to_owned().repeat(*g));
|
for row in grid {
|
||||||
|
column.push(row[x]);
|
||||||
|
}
|
||||||
|
let n: HashSet<usize> = mirror_points(&column).iter().copied().collect();
|
||||||
|
if s.is_empty() {
|
||||||
|
s = n;
|
||||||
|
} else {
|
||||||
|
s = s.intersection(&n).cloned().collect();
|
||||||
|
if s.is_empty() {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let mut cache: Cache = Cache::new();
|
s
|
||||||
arrangements_inner(conditions, &group_strings, &mut cache)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Grid = Vec<Vec<char>>;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let mut sum = 0;
|
let mut grids: Vec<Grid> = vec![];
|
||||||
|
grids.push(vec![]);
|
||||||
for line in stdin().lines().map_while(Result::ok) {
|
for line in stdin().lines().map_while(Result::ok) {
|
||||||
let mut split = line.split_whitespace();
|
println!("{line}");
|
||||||
let conditions = split.next().unwrap();
|
if line.is_empty() {
|
||||||
let groups: Vec<usize> = split
|
grids.push(vec![]);
|
||||||
.next()
|
continue;
|
||||||
.unwrap()
|
}
|
||||||
.split(',')
|
grids.last_mut().unwrap().push(line.chars().collect());
|
||||||
.map(str::parse)
|
}
|
||||||
.map_while(Result::ok)
|
let mut sum = 0;
|
||||||
.collect();
|
for (i, grid) in grids.iter().enumerate() {
|
||||||
|
for v in vertical_mirror_points(grid) {
|
||||||
let conditions = [conditions].repeat(5).join("?");
|
println!("grid {i}: v = {v}");
|
||||||
let groups = groups.repeat(5);
|
sum += v;
|
||||||
|
}
|
||||||
let a = arrangements(&conditions, &groups);
|
for h in horizontal_mirror_points(grid) {
|
||||||
sum += a;
|
println!("grid {i}: h = {h}");
|
||||||
|
sum += 100 * h;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
println!("{sum}");
|
println!("{sum}");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -95,24 +89,12 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_arrangements() {
|
fn test_mirror_points() {
|
||||||
assert_eq!(arrangements(".??.?#??##???.", &[1, 6]), 5);
|
let chars: Vec<char> = "#.##..##.".chars().collect();
|
||||||
assert_eq!(arrangements("???.###", &[1, 1, 3]), 1);
|
assert_eq!(mirror_points(&chars), vec![5, 7]);
|
||||||
assert_eq!(arrangements(".??..??...?##.", &[1, 1, 3]), 4);
|
let chars: Vec<char> = "#.##..#".chars().collect();
|
||||||
assert_eq!(arrangements("?#?#?#?#?#?#?#?", &[1, 3, 1, 6]), 1);
|
assert_eq!(mirror_points(&chars), vec![5]);
|
||||||
assert_eq!(arrangements("????.#...#...", &[4, 1, 1]), 1);
|
let chars: Vec<char> = ".#.##".chars().collect();
|
||||||
assert_eq!(arrangements("????.######..#####.", &[1, 6, 5]), 4);
|
assert_eq!(mirror_points(&chars), vec![4]);
|
||||||
assert_eq!(arrangements("?###????????", &[3, 2, 1]), 10);
|
|
||||||
assert_eq!(arrangements("????#?#?..?#?", &[4, 1]), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_matches() {
|
|
||||||
assert!(matches("?", "#"));
|
|
||||||
assert!(matches("?", "."));
|
|
||||||
assert!(matches("#", "#"));
|
|
||||||
assert!(matches(".", "."));
|
|
||||||
assert!(!matches("#", "."));
|
|
||||||
assert!(!matches(".", "#"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue