Skip to content

Instantly share code, notes, and snippets.

@icub3d
Created January 30, 2026 01:02
Show Gist options
  • Select an option

  • Save icub3d/19312b5cddbf57adf5e8daeca04597fd to your computer and use it in GitHub Desktop.

Select an option

Save icub3d/19312b5cddbf57adf5e8daeca04597fd to your computer and use it in GitHub Desktop.
Solution for Advent of Code 2017 Day 8
use std::time::Instant;
use rustc_hash::FxHashMap;
const INPUT: &str = include_str!("inputs/day08.txt");
enum Modifier {
Increment(isize),
Decrement(isize),
}
impl Modifier {
fn new(what: &str, quantity: &str) -> Self {
match what {
"inc" => Self::Increment(quantity.parse::<isize>().unwrap()),
_ => Self::Decrement(quantity.parse::<isize>().unwrap()),
}
}
fn apply(&self, to: &mut isize) {
match self {
Self::Increment(q) => *to += q,
Self::Decrement(q) => *to -= q,
}
}
}
enum Comparator {
Equal,
NotEqual,
Less,
LessEqual,
Greater,
GreaterEqual,
}
impl Comparator {
fn eval(&self, lhs: isize, rhs: isize) -> bool {
match self {
Comparator::Equal => lhs == rhs,
Comparator::NotEqual => lhs != rhs,
Comparator::Less => lhs < rhs,
Comparator::LessEqual => lhs <= rhs,
Comparator::Greater => lhs > rhs,
Comparator::GreaterEqual => lhs >= rhs,
}
}
}
impl From<&str> for Comparator {
fn from(value: &str) -> Self {
match value {
"==" => Comparator::Equal,
"!=" => Comparator::NotEqual,
"<" => Comparator::Less,
"<=" => Comparator::LessEqual,
">" => Comparator::Greater,
">=" => Comparator::GreaterEqual,
_ => panic!("bug"),
}
}
}
struct Condition<'a> {
register: &'a str,
comp: Comparator,
value: isize,
}
impl<'a> Condition<'a> {
fn eval(&self, registers: &FxHashMap<&str, isize>) -> bool {
self.comp
.eval(*registers.get(self.register).unwrap_or(&0), self.value)
}
fn new(register: &'a str, comp: &str, value: &str) -> Self {
Self {
register,
comp: comp.into(),
value: value.parse::<isize>().unwrap(),
}
}
}
struct Instruction<'a> {
register: &'a str,
modifier: Modifier,
condition: Condition<'a>,
}
impl<'a> Instruction<'a> {
fn parse(input: &'a str) -> Self {
let mut parts = input.split_whitespace().filter(|&v| v != "if");
Instruction {
register: parts.next().unwrap(),
modifier: Modifier::new(parts.next().unwrap(), parts.next().unwrap()),
condition: Condition::new(
parts.next().unwrap(),
parts.next().unwrap(),
parts.next().unwrap(),
),
}
}
}
fn parse<'a>(input: &'a str) -> Vec<Instruction<'a>> {
input.lines().map(Instruction::parse).collect()
}
fn p1(input: &str) -> isize {
let instructions = parse(input);
let mut registers = FxHashMap::default();
for instruction in instructions {
if instruction.condition.eval(&registers) {
instruction
.modifier
.apply(registers.entry(instruction.register).or_default());
}
}
*registers.values().max().unwrap()
}
fn p2(input: &str) -> isize {
let instructions = parse(input);
let mut registers = FxHashMap::default();
let mut max = isize::MIN;
for instruction in instructions {
if instruction.condition.eval(&registers) {
let reg = registers.entry(instruction.register).or_default();
instruction.modifier.apply(reg);
max = max.max(*reg);
}
}
max
}
fn main() {
let now = Instant::now();
let solution = p1(INPUT);
println!("p1 {:?} {}", now.elapsed(), solution);
let now = Instant::now();
let solution = p2(INPUT);
println!("p2 {:?} {}", now.elapsed(), solution);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_p1() {
let input = "b inc 5 if a > 1\na inc 1 if b < 5\nc dec -10 if a >= 1\nc inc -20 if c == 10";
assert_eq!(p1(input), 1);
}
#[test]
fn test_p2() {
let input = "b inc 5 if a > 1\na inc 1 if b < 5\nc dec -10 if a >= 1\nc inc -20 if c == 10";
assert_eq!(p2(input), 10);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment