#![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 { // println!("ret 1"); return 1; } 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 mut ret = 0; for i in 0..(s.len() - n) { let mut all = true; // check before first # for ii in 0..i { if s[ii] == State::Nok { all = false; } } // check if # * n for ii in 0..n { if s[i + ii] == State::Ok { all = false; } } // check if next is not # if s[i + n] == State::Nok { all = false; } if all { ret += rec2(&s[i + n + 1..], arr, depth + 1); } } if s.len() == n { let mut all = true; for ii in 0..n { if s[ii] == State::Ok { all = false; } } if all { // println!("ret 1"); return 1; } } // handle last digit and last place if arr.len() == 0 { let mut all = true; for i in 0..(s.len() - n) { // check before first # if s[i] == State::Nok { all = false; } } for i in (s.len() - n)..s.len() { // check if # * n if s[i] == State::Ok { all = false; } } if all { ret += 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 l in ls { // let a = rec(l); // // println!("{}", a); // res1 += a; // } let mut ls2: Vec = Vec::new(); for i in 0..ls.len() { let mut l2: Line = Default::default(); for _ in 0..5 { l2.0.append(&mut ls[i].0.clone()); l2.0.push(State::Unk); l2.1.append(&mut ls[i].1.clone()); } ls2.push(l2); } // for l in [ls2[0].clone()] { // for l in [ls[5].clone()] { for l in ls2 { let a = rec2(&l.0, &l.1, 0); println!("{}", a); res2 += a; } println!("res1: {}", res1); println!("res2: {}", res2); }