Skip to content

Instantly share code, notes, and snippets.

@archer884
Created Dec 5, 2017
Embed
What would you like to do?
AOC/5 (Rust)
static INPUT: &str = include_str!("../input.txt");
struct ProgramWithOffset<F> {
instructions: Vec<i32>,
offset: F,
}
impl<F: Fn(i32) -> i32> ProgramWithOffset<F> {
fn new<T: IntoIterator<Item = i32>>(instructions: T, offset: F) -> Self {
Self {
instructions: instructions.into_iter().collect(),
offset,
}
}
fn run(&mut self) -> usize {
let mut pointer = 0;
let mut counter = 0;
while pointer >= 0 && pointer < (self.instructions.len() as i32) {
let next = pointer + self.instructions[pointer as usize];
self.apply_offset(pointer as usize);
pointer = next;
counter += 1;
}
counter
}
fn apply_offset(&mut self, idx: usize) {
// I can't believe this compiles.
self.instructions[idx] = (self.offset)(self.instructions[idx]);
}
}
fn main() {
println!("{}", part_1(INPUT));
println!("{}", part_2(INPUT));
}
fn part_1(s: &str) -> usize {
let instructions = s.lines().filter_map(|n| n.parse().ok());
let mut program = ProgramWithOffset::new(instructions, |i| i + 1);
program.run()
}
fn part_2(s: &str) -> usize {
let instructions = s.lines().filter_map(|n| n.parse().ok());
let mut program = ProgramWithOffset::new(instructions, |i| {
if i >= 3 { i - 1 } else { i + 1 }
});
program.run()
}
#[cfg(test)]
mod tests {
static TEST_INPUT: &str = "0\n3\n0\n1\n-3\n";
#[test]
fn part_1_works() {
assert_eq!(5, super::part_1(TEST_INPUT));
}
#[test]
fn part_2_works() {
assert_eq!(10, super::part_2(TEST_INPUT));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment