fn parse_and_prepare(input: &str) -> Option<(Puzzle, PartialSolution)> {
    let sides: Vec<&str> = input.split(" == ").collect();
    if sides.len() != 2 {
        return None;
    }
    let to_sym_num = |xs: &str| xs.chars().rev().collect();
    let lhs: Vec<SymbolNum> = sides[0].split(" + ").map(to_sym_num).collect();
    if lhs.is_empty() {
        return None;
    }
    let vlen = lhs.iter().fold(0, |acc, x| acc.max(x.len()));
    let rhs = to_sym_num(sides[1]);
    if vlen > rhs.len() {
        return None;
    }
    let mut lhs_digits = vec![HashMap::new(); vlen];
    lhs.iter().for_each(|num: &SymbolNum| {
        num.iter().enumerate().for_each(|(i, ch)| {
            lhs_digits[i]
                .entry(*ch)
                .and_modify(|e| *e += 1)
                .or_insert(1);
        })
    });

    let lhs_needs: Vec<Vec<char>> = {
        let mut needs_acc: HashSet<char> = HashSet::new();
        lhs_digits
            .iter()
            .map(|ds| {
                let s = ds
                    .keys()
                    .filter(|k| !needs_acc.contains(&k))
                    .copied()
                    .collect::<Vec<char>>();
                s.iter().for_each(|ch| {
                    needs_acc.insert(*ch);
                });
                s
            })
            .collect()
    };
    let non_zeros: HashSet<char> = {
        let mut nz = lhs
            .iter()
            .map(|s| *s.last().unwrap())
            .collect::<HashSet<char>>();
        nz.insert(*rhs.last().unwrap());
        nz
    };
    let puzzle = Puzzle {
        lhs_digits,
        rhs,
        lhs_needs,
        non_zeros,
    };

    let solution = {
        PartialSolution {
            unassigned_digits: (0..=9).collect(),
            assigns: HashMap::new(),
        }
    };

    Some((puzzle, solution))
}
/// Parse input puzzle and preprocess some info for solving algorithm.
Parse input puzzle and preprocess some info for solving algorithm.
Parse input puzzle and preprocess some info for solving algorithm .
fn parse_and_prepare(input: &str) -> Option<(Puzzle, PartialSolution)> {
    let sides: Vec<&str> = input.split(" == ").collect();
    if sides.len() != 2 {
        return None;
    }
    let to_sym_num = |xs: &str| xs.chars().rev().collect();
    let lhs: Vec<SymbolNum> = sides[0].split(" + ").map(to_sym_num).collect();
    if lhs.is_empty() {
        return None;
    }
    let vlen = lhs.iter().fold(0, |acc, x| acc.max(x.len()));
    let rhs = to_sym_num(sides[1]);
    if vlen > rhs.len() {
        return None;
    }
    let mut lhs_digits = vec![HashMap::new(); vlen];
    lhs.iter().for_each(|num: &SymbolNum| {
        num.iter().enumerate().for_each(|(i, ch)| {
            lhs_digits[i]
                .entry(*ch)
                .and_modify(|e| *e += 1)
                .or_insert(1);
        })
    });
    let lhs_needs: Vec<Vec<char>> = {
        let mut needs_acc: HashSet<char> = HashSet::new();
        lhs_digits
            .iter()
            .map(|ds| {
                let s = ds
                    .keys()
                    .filter(|k| !needs_acc.contains(&k))
                    .copied()
                    .collect::<Vec<char>>();
                s.iter().for_each(|ch| {
                    needs_acc.insert(*ch);
                });
                s
            })
            .collect()
    };
    let non_zeros: HashSet<char> = {
        let mut nz = lhs
            .iter()
            .map(|s| *s.last().unwrap())
            .collect::<HashSet<char>>();
        nz.insert(*rhs.last().unwrap());
        nz
    };
    let puzzle = Puzzle {
        lhs_digits,
        rhs,
        lhs_needs,
        non_zeros,
    };
    let solution = {
        PartialSolution {
            unassigned_digits: (0..=9).collect(),
            assigns: HashMap::new(),
        }
    };
    Some((puzzle, solution))
}
fn parse_and_prepare ( input : & str ) -> Option < ( Puzzle , PartialSolution ) > { let sides : Vec < & str > = input . split ( " " ) . collect ( ) ; if sides . len ( ) != 2 { return None ; } let to_sym_num = | xs : & str | xs . chars ( ) . rev ( ) . collect ( ) ; let lhs : Vec < SymbolNum > = sides [ 0 ] . split ( " " ) . map ( to_sym_num ) . collect ( ) ; if lhs . is_empty ( ) { return None ; } let vlen = lhs . iter ( ) . fold ( 0 , | acc , x | acc . max ( x . len ( ) ) ) ; let rhs = to_sym_num ( sides [ 1 ] ) ; if vlen > rhs . len ( ) { return None ; } let mut lhs_digits = vec ! [ HashMap new ( ) vlen ] ; lhs . iter ( ) . for_each ( | num : & SymbolNum | { num . iter ( ) . enumerate ( ) . for_each ( | ( i , ch ) | { lhs_digits [ i ] . entry ( * ch ) . and_modify ( | e | * e += 1 ) . or_insert ( 1 ) ; } ) } ) ; let lhs_needs : Vec < Vec < char > > = { let mut needs_acc : HashSet < char > = HashSet :: new ( ) ; lhs_digits . iter ( ) . map ( | ds | { let s = ds . keys ( ) . filter ( | k | ! needs_acc . contains ( & k ) ) . copied ( ) . collect :: < Vec < char > > ( ) ; s . iter ( ) . for_each ( | ch | { needs_acc . insert ( * ch ) ; } ) ; s } ) . collect ( ) } ; let non_zeros : HashSet < char > = { let mut nz = lhs . iter ( ) . map ( | s | * s . last ( ) . unwrap ( ) ) . collect :: < HashSet < char > > ( ) ; nz . insert ( * rhs . last ( ) . unwrap ( ) ) ; nz } ; let puzzle = Puzzle { lhs_digits , rhs , lhs_needs , non_zeros , } ; let solution = { PartialSolution { unassigned_digits : ( 0 ..= 9 ) . collect ( ) , assigns : HashMap :: new ( ) , } } ; Some ( ( puzzle , solution ) ) }
Parse input puzzle and preprocess some info for solving algorithm.
Parse input puzzle and preprocess some info for solving algorithm .
input
&str
input
&str