Created
December 22, 2017 08:09
-
-
Save tinaun/0a3d01a862b9345c0bece32ff4f9ef2e to your computer and use it in GitHub Desktop.
day22 p2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate gif; | |
use std::collections::HashMap; | |
use gif::{Frame, Encoder, Repeat, SetParameter}; | |
use std::fs::File; | |
use std::io::prelude::*; | |
static COLOR_MAP: [u8; 15] = [ | |
20, 12, 28, // CLEAN | |
218, 212, 94, // WEAKENED | |
208, 70, 72, // INFECTED | |
89, 125, 206, // FLAGGED | |
222, 238, 214 // ANT | |
]; | |
static SIZE_X: u16 = 501; | |
static SIZE_Y: u16 = 501; | |
#[derive(Debug, Copy, Clone, PartialEq, Eq)] | |
enum State { | |
Weakened, | |
Infected, | |
Flagged, | |
} | |
#[derive(Debug, Copy, Clone, PartialEq, Eq)] | |
enum Facing { | |
North, | |
East, | |
South, | |
West, | |
} | |
impl Facing { | |
fn rot_r(&mut self) { | |
*self = match *self { | |
Facing::North => Facing::East, | |
Facing::East => Facing::South, | |
Facing::South => Facing::West, | |
Facing::West => Facing::North, | |
} | |
} | |
fn rot_l(&mut self) { | |
*self = match *self { | |
Facing::North => Facing::West, | |
Facing::East => Facing::North, | |
Facing::South => Facing::East, | |
Facing::West => Facing::South, | |
} | |
} | |
fn delta(&self) -> (isize, isize) { | |
match *self { | |
Facing::North => (0, 1), | |
Facing::East => (1, 0), | |
Facing::South => (0, -1), | |
Facing::West => (-1, 0), | |
} | |
} | |
} | |
#[derive(Debug, Clone, PartialEq, Eq)] | |
struct Ant { | |
pos: (isize, isize), | |
dir: Facing, | |
} | |
impl Ant { | |
fn new() -> Self { | |
Ant { | |
pos: (0, 0), | |
dir: Facing::North, | |
} | |
} | |
fn step(&mut self) { | |
let delta = self.dir.delta(); | |
self.pos.0 += delta.0; | |
self.pos.1 += delta.1; | |
} | |
} | |
fn gen_frame<W: Write>(e: &mut Encoder<W>, buf: &[u8], delay: u16) { | |
// write frame | |
let mut frame = Frame::default(); | |
frame.delay = delay; | |
frame.width = SIZE_X; | |
frame.height = SIZE_Y; | |
frame.buffer = buf.into(); | |
e.write_frame(&frame).unwrap(); | |
} | |
fn main() { | |
let input = include_str!("../input.txt"); | |
let mut image = File::create("path.gif").unwrap(); | |
let mut encoder = Encoder::new(&mut image, SIZE_X, SIZE_Y, &COLOR_MAP).unwrap(); | |
encoder.set(Repeat::Infinite).unwrap(); | |
let sx = SIZE_X as usize; | |
let sy = SIZE_Y as usize; | |
let mut buf = vec![0; sx * sy]; | |
let mut field = HashMap::<(isize, isize), State>::new(); | |
for (y, l) in input.lines().enumerate() { | |
let m = (l.len() / 2) as isize; | |
let px = (sx - l.len()) / 2; | |
let py = (sy - l.len()) / 2; | |
for (x, c) in l.chars().enumerate() { | |
if c == '#' { | |
field.insert((x as isize - m, m - y as isize), State::Infected); | |
buf[(py + y) * sx + (px + x)] = 2; | |
} | |
} | |
} | |
buf[(sy/2) * sx + (sx/2)] = 4; | |
let mut ant = Ant::new(); | |
let mut infects = 0; | |
for f in 0..10_000_000 { | |
if f % 5_000 == 0 { | |
gen_frame(&mut encoder, &buf, 2); | |
} | |
// turn | |
let (px, py) = (sx/2, sy/2); | |
let (nx, ny) = (px as isize + ant.pos.0, py as isize + ant.pos.1); | |
if field.contains_key(&ant.pos) { | |
match *field.get(&ant.pos).unwrap() { | |
State::Flagged => { | |
ant.dir.rot_l(); | |
ant.dir.rot_l(); | |
field.remove(&ant.pos); | |
if nx > -1 && nx < sx as isize && ny > -1 && ny < sy as isize { | |
buf[ny as usize * sx + nx as usize] = 0; | |
} | |
}, | |
State::Infected => { | |
ant.dir.rot_r(); | |
field.insert(ant.pos, State::Flagged); | |
if nx > -1 && nx < sx as isize && ny > -1 && ny < sy as isize { | |
buf[ny as usize * sx + nx as usize] = 3; | |
} | |
}, | |
State::Weakened => { | |
// don't turn | |
field.insert(ant.pos, State::Infected); | |
infects += 1; | |
if nx > -1 && nx < sx as isize && ny > -1 && ny < sy as isize { | |
buf[ny as usize * sx + nx as usize] = 2; | |
} | |
}, | |
} | |
} else { | |
ant.dir.rot_l(); | |
field.insert(ant.pos, State::Weakened); | |
if nx > -1 && nx < sx as isize && ny > -1 && ny < sy as isize { | |
buf[ny as usize * sx + nx as usize] = 1; | |
} | |
} | |
// move | |
ant.step(); | |
let (nx, ny) = (px as isize + ant.pos.0, py as isize + ant.pos.1); | |
if nx > -1 && nx < sx as isize && ny > -1 && ny < sy as isize { | |
buf[ny as usize * sx + nx as usize] = 4; | |
} | |
} | |
gen_frame(&mut encoder, &buf, 100); | |
println!("p2: {}", infects); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment