~cdv/aoc-2018-rs

94f6d4c1f3c3d1bc4ebe0b2a9db11fd4b7bddb73 — Christopher Vittal 2 years ago 1db0298 day12
Solve day twelve
2 files changed, 154 insertions(+), 1 deletions(-)

A data/day12
M src/bin/day12.rs
A data/day12 => data/day12 +34 -0
@@ 0,0 1,34 @@
initial state: #.......##.###.#.#..##..##..#.#.###..###..##.#.#..##....#####..##.#.....########....#....##.#..##...

..... => .
#.... => .
..### => .
##..# => #
.###. => #
...## => .
#.#.. => .
..##. => .
##.#. => #
..#.. => .
.#... => #
##.## => .
....# => .
.#.#. => .
#..#. => #
#.### => .
.##.# => #
.#### => .
.#..# => .
####. => #
#...# => #
.#.## => #
#..## => .
..#.# => #
#.##. => .
###.. => .
##### => #
###.# => #
...#. => #
#.#.# => #
.##.. => .
##... => #

M src/bin/day12.rs => src/bin/day12.rs +120 -1
@@ 1,1 1,120 @@
fn main() {}
//static INPUT: &str = "data/day12";

static INPUT: &[u8] = b"#.......##.###.#.#..##..##..#.#.###..###..##.#.#..##....#####..##.#.....########....#....##.#..##...";

fn rule(m: &[u8]) -> u8 {
    match m {
        b"#####" => b'#',
        b"####." => b'#',
        b"###.#" => b'#',
        b"###.." => b'.',
        b"##.##" => b'.',
        b"##.#." => b'#',
        b"##..#" => b'#',
        b"##..." => b'#',
        b"#.###" => b'.',
        b"#.##." => b'.',
        b"#.#.#" => b'#',
        b"#.#.." => b'.',
        b"#..##" => b'.',
        b"#..#." => b'#',
        b"#...#" => b'#',
        b"#...." => b'.',
        b".####" => b'.',
        b".###." => b'#',
        b".##.#" => b'#',
        b".##.." => b'.',
        b".#.##" => b'#',
        b".#.#." => b'.',
        b".#..#" => b'.',
        b".#..." => b'#',
        b"..###" => b'.',
        b"..##." => b'.',
        b"..#.#" => b'#',
        b"..#.." => b'.',
        b"...##" => b'.',
        b"...#." => b'#',
        b"....#" => b'.',
        b"....." => b'.',
        _ => panic!("invalid input"),
    }
}

fn last(l: &[u8]) -> [u8; 4] {
    let n = l.len();
    [rule(&[l[n - 4], l[n - 3], l[n - 2], l[n - 1], b'.']),
     rule(&[l[n - 3], l[n - 2], l[n - 1], b'.', b'.']),
     rule(&[l[n - 2], l[n - 1], b'.', b'.', b'.']),
     rule(&[l[n - 1], b'.', b'.', b'.', b'.'])]
}

fn generation(line: Vec<u8>, zero: usize) -> (Vec<u8>, usize) {
    let first = [rule(&[b'.', b'.', b'.', b'.', line[0]]),
                 rule(&[b'.', b'.', b'.', line[0], line[1]]),
                 rule(&[b'.', b'.', line[0], line[1], line[2]]),
                 rule(&[b'.', line[0], line[1], line[2], line[3]])];
    let first = if first[0] == b'.' {
        if first[1] == b'.' {
            &first[2..]
        } else {
            &first[1..]
        }
    } else {
        &first[..]
    };

    let next = line.windows(5).map(rule);
    let last = last(&line);
    let last = if let Some(p) = last.iter().rposition(|&b| b == b'#') {
        &last[0..p+1]
    } else {
        &[]
    };
    (first.iter().cloned().chain(next).chain(last.iter().cloned()).collect::<Vec<_>>(),
     zero + first.len() - 2)
}

fn plant_sum(line: &[u8], zero: usize) -> isize {
    line.iter().enumerate().map(|(i, &e)| if e == b'#' {
        (i as isize - zero as isize)
    } else {
        0
    }).sum()
}

fn main() {
    let mut line = Vec::from(INPUT);
    let mut zero = 0;

    for _ in 0..20 {
        let gen = generation(line, zero);
        line = gen.0;
        zero = gen.1;
    }

    let mut sum = plant_sum(&line, zero);
    println!("  1: {}", sum);

    // Assumption, difference stabilizes eventually
    let mut heuristic = 0;
    let mut diff = 0;
    let mut end_gen = 20;
    loop {
        end_gen += 1;
        let gen = generation(line, zero);
        line = gen.0;
        zero = gen.1;
        let prev = sum;
        sum = plant_sum(&line, zero);
        if diff == sum-prev {
            heuristic += 1;
        } else {
            heuristic = 0;
        }
        if heuristic > 1000 {
            break;
        }
        diff = sum - prev;
    };
    println!("  2: {}", sum + (50_000_000_000 - end_gen) * diff);
}