#![allow(dead_code)] #![allow(unused_variables)] #![allow(unused_mut)] use std::fmt; use std::fs::File; use std::io::Read; #[derive(Eq, PartialEq, Clone, Copy)] enum State { Ok, Nok, Unk, } impl std::fmt::Debug for State { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let a = match self { State::Ok => '.', State::Nok => '#', State::Unk => '?', }; write!(f, "{}", a) } } type Line = (Vec, Vec); fn rec(l: Line) -> usize { for i in 0..l.0.len() { if l.0[i] == State::Unk { let mut sum = 0; let mut l1 = l.clone(); let mut l2 = l.clone(); l1.0[i] = State::Ok; l2.0[i] = State::Nok; sum += rec(l1); sum += rec(l2); return sum; } } if is_valid(&l) { return 1; } else { return 0; } } fn is_valid(l: &Line) -> bool { let mut a: Vec = Vec::new(); let mut prev = State::Ok; let mut count = 0; for i in 0..l.0.len() { if l.0[i] == State::Nok { count += 1; } else if l.0[i] == State::Ok && prev == State::Nok { a.push(count); count = 0; } prev = l.0[i]; } if count != 0 { a.push(count); } let ret = a == l.1; ret } fn rec2(mut s: &[State], mut arr: &[usize], depth: u32) -> usize { // println!("{} {:?} {:?}", depth, s, arr); if arr.len() == 0 { let mut all = true; for i in 0..s.len() { if s[i] == State::Nok { all = false; } } if all { // println!("ret 1"); return 1; } else { // println!("ret 0"); return 0; } } if s.len() == 0 { // println!("ret 0"); return 0; } if s.len() < arr.iter().fold(0, |x, y| x + y) + arr.len() - 1 { // println!("ret 0"); return 0; } let n = arr[0]; let arr = &arr[1..]; let start = if depth == 0 { 0 } else { 1 }; let mut ret = 0; // println!("nok_s {} {}", start, s.len() - n); for nok_s in start..=(s.len() - n) { let mut all = true; // check before first # for ii in 0..nok_s { if s[ii] == State::Nok { all = false; } } // check if # * n for ii in 0..n { if s[nok_s + ii] == State::Ok { all = false; } } if all { ret += rec2(&s[nok_s + n..], arr, depth + 1); } } ret } fn main() { // let filename = "in/day12.ref"; let filename = "in/day12.pzl"; let mut f = File::open(filename).expect("cannot open file"); let mut content = String::new(); f.read_to_string(&mut content).expect("cannot read file"); let lines = content.trim_end().split('\n'); let mut ls: Vec = Vec::new(); for line in lines { let (a, b) = line.split_once(' ').unwrap(); let mut l: Line = (Vec::new(), Vec::new()); for c in a.chars() { let s = match c { '.' => State::Ok, '#' => State::Nok, '?' => State::Unk, _ => panic!(), }; l.0.push(s); } for c in b.split(',') { l.1.push(c.parse().unwrap()); } ls.push(l); } let mut res1 = 0; let mut res2 = 0; // for (i,l) in ls.iter().enumerate() { // let a = rec(l.clone()); // println!("{} {}", i+1, a); // res1 += a; // } let mut ls2: Vec = Vec::new(); for i in 0..ls.len() { let mut l2: Line = Default::default(); l2.0 = vec![ls[i].0.clone(); 5].join(&State::Unk); l2.1 = vec![ls[i].1.clone(); 5] .into_iter() .flat_map(|s| s) .collect::>(); ls2.push(l2); } // for (i,l) in [ls[998].clone()].into_iter().enumerate() { for (i, l) in ls2.iter().enumerate() { let a = rec2(&l.0, &l.1, 0); // println!("{:?} {:?}", &l.0, &l.1); println!("{} {}", i + 1, a); res2 += a; } println!("res1: {}", res1); println!("res2: {}", res2); }