DEV Community

Discussion on: Daily Challenge #227 - Android Lock Screen

Collapse
 
qm3ster profile image
Mihail Malo • Edited

Rust bruteforce solution

#[derive(Copy, Clone)]
struct Set(u16);
fn xy(n: i8) -> (i8, i8) {
    ((n % 3) as i8, (n / 3) as i8)
}

impl Set {
    fn has(&self, n: i8) -> bool {
        (self.0 & (1 << n)) != 0
    }
    fn flip(&self, n: i8) -> Self {
        Self(self.0 ^ (1 << n))
    }
}
impl Default for Set {
    fn default() -> Self {
        Set(0b111111111)
    }
}
fn attempt(pos: i8, depth: u8, field: Set) -> u16 {
    if depth == 0 {
        return 1;
    }
    let field = field.flip(pos);
    let (mx, my) = xy(pos);
    (0..9)
        .filter(|&i| field.has(i))
        .filter_map(|i| {
            let (x, y) = xy(i);
            let dx = x - mx;
            let dy = y - my;
            if match (dx.abs(), dy.abs()) {
                (0, 1) | (1, 0) | (1, 1) | (1, 2) | (2, 1) => true,
                (0, 2) | (2, 0) | (2, 2) => {
                    if !field.has((pos + i) / 2) {
                        true
                    } else {
                        false
                    }
                }
                _ => unreachable!(),
            } {
                Some(attempt(i, depth - 1, field))
            } else {
                None
            }
        })
        .sum()
}

fn main() {
    for start in 0..9 {
        for len in 0..=9 {
            println!(
                "start at {}, len {}: {} possibilities",
                start,
                len,
                attempt(start, len, Default::default())
            );
        }
    }
}

Look at it go
But note that the "game board" is rotationally symmetric, so there are only three distinctive positions: corner, side, and center.