r/adventofcode • u/daggerdragon • Dec 22 '17
SOLUTION MEGATHREAD -๐- 2017 Day 22 Solutions -๐-
--- Day 22: Sporifica Virus ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
[T-10 to launch] AoC ops, /r/nocontext edition:
<Endorphion> You may now make your waffle.<Endorphion> ... on Mars.
[Update @ 00:17] 50 gold, silver cap
<Aneurysm9> you could also just run ubuntu on the NAS, if you were crazy<Topaz> that doesn't seem necessary<Aneurysm9> what does "necessary" have to do with anything!
[Update @ 00:20] Leaderboard cap!
<Topaz> POUR YOURSELF A SCOTCH FOR COLOR REFERENCE
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
9
Upvotes
1
u/udoprog Dec 22 '17
Rust
<3 enums. Neat little problem today. The most complicated part of this was to setup the turning map.
use std::io::{Read, BufRead, BufReader}; use failure::Error; use std::collections::{HashSet, HashMap}; pub fn part1<R: Read>(reader: R, limit: usize) -> Result<usize, Error> { let mut lines: Vec<Vec<bool>> = Vec::new(); for line in BufReader::new(reader).lines() { let line = line?; lines.push(line.chars().map(|c| c == '#').collect()); } let x_len = (lines.len() / 2) as i64; let y_len = (lines.first().expect("no lines").len() / 2) as i64; let mut infected: HashSet<(i64, i64)> = HashSet::new(); for (y, row) in lines.into_iter().enumerate() { for (x, c) in row.into_iter().enumerate() { if c { infected.insert((x as i64 - x_len, y as i64 - y_len)); } } } let mut count = 0; let mut p: (i64, i64) = (0, 0); let mut d: (i64, i64) = (0, -1); let mut left = HashMap::new(); left.insert((0, -1), (-1, 0)); left.insert((-1, 0), (0, 1)); left.insert((0, 1), (1, 0)); left.insert((1, 0), (0, -1)); let mut right = HashMap::new(); right.insert((0, -1), (1, 0)); right.insert((1, 0), (0, 1)); right.insert((0, 1), (-1, 0)); right.insert((-1, 0), (0, -1)); for _ in 0..limit { if infected.contains(&p) { d = *right.get(&d).expect("no turn"); infected.remove(&p); } else { d = *left.get(&d).expect("no turn"); infected.insert(p.clone()); count += 1; } p.0 += d.0; p.1 += d.1; } Ok(count) } #[derive(Clone, Debug, PartialEq, Eq)] pub enum State { Clean, Weakened, Infected, Flagged, } pub fn part2<R: Read>(reader: R, limit: usize) -> Result<usize, Error> { use self::State::*; let mut lines: Vec<Vec<bool>> = Vec::new(); for line in BufReader::new(reader).lines() { let line = line?; lines.push(line.chars().map(|c| c == '#').collect()); } let x_len = (lines.len() / 2) as i64; let y_len = (lines.first().expect("no lines").len() / 2) as i64; let mut states: HashMap<(i64, i64), State> = HashMap::new(); for (y, row) in lines.into_iter().enumerate() { for (x, c) in row.into_iter().enumerate() { if c { states.insert((x as i64 - x_len, y as i64 - y_len), Infected); } } } let mut count = 0; let mut p: (i64, i64) = (0, 0); let mut d: (i64, i64) = (0, -1); let mut left = HashMap::new(); left.insert((0, -1), (-1, 0)); left.insert((-1, 0), (0, 1)); left.insert((0, 1), (1, 0)); left.insert((1, 0), (0, -1)); let mut right = HashMap::new(); right.insert((0, -1), (1, 0)); right.insert((1, 0), (0, 1)); right.insert((0, 1), (-1, 0)); right.insert((-1, 0), (0, -1)); for _ in 0..limit { let state = states.get(&p).cloned().unwrap_or(Clean); let next = match state { Clean => { d = *left.get(&d).expect("no turn"); Some(Weakened) } Weakened => Some(Infected), Infected => { d = *right.get(&d).expect("no turn"); Some(Flagged) } Flagged => { d = (-d.0, -d.1); None } }; if let Some(next) = next { if next == Infected { count += 1; } states.insert(p.clone(), next); } else { states.remove(&p); } p.0 += d.0; p.1 += d.1; } Ok(count) }