Skip to content

Instantly share code, notes, and snippets.

@arcrose
Last active December 2, 2017 00:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arcrose/3ef449a4ad6791378adc6715df2da2ef to your computer and use it in GitHub Desktop.
Save arcrose/3ef449a4ad6791378adc6715df2da2ef to your computer and use it in GitHub Desktop.
Answers to the Advent of Code challenges
// Answer to challenge 1 for Advent of Code 2017 on December 1
const MY_INPUT: &str = "INPUT GOES HERE";
/// Creates a vector where each element is a single digit taken from the input string, in order.
///
/// `input` is expected to be a string of digits in base 10.
///
/// # Panics
///
/// This function will panic if `input` contains characters that are not any of the digits 0 to 9.
fn string_to_digit_list(input: &str) -> Vec<u8> {
let mut digit_list = Vec::with_capacity(input.len());
let characters = input.chars();
for digit_character in characters {
let digit = digit_character.to_digit(10).unwrap();
digit_list.push(digit as u8);
}
digit_list
}
/// Solution to Advent of Code 2017 December 1 Challenge 1.
///
/// My solution here is to simulate something of a circularly-linked list using a vector, peeking,
/// and a record of the first element.
///
/// The solution is computed by treating the input vector of digits like input to a state machine
/// with a memory of the sum it's computing and the first digit it saw.
fn solution(digits: &mut Vec<u8>) -> u64 {
let mut sum: u64 = 0;
let mut first_digit = None;
let mut digits = digits.iter().peekable();
while let Some(digit) = digits.next() {
match (first_digit, digits.peek()) {
// Seeing the first value as well as peeking at the next, we have to record the first.
(None, Some(&&number)) if *digit == number => {
first_digit = Some(*digit);
sum += number as u64;
},
// Seeing the first value, we have to record it to look at it again later.
(None, _) => {
first_digit = Some(*digit);
}
// Seeing the next number after the first, we just check the current and next digits.
(_, Some(&&number)) if *digit == number => {
sum += number as u64;
}
// Seeing the last digit, check the circular case, where the last digit equals the first one.
(Some(first), None) if *digit == first => {
sum += first as u64;
},
_ => {},
};
}
sum
}
fn main() {
let mut digits = string_to_digit_list(MY_INPUT);
let answer = solution(&mut digits);
println!("Answer = {}", answer);
}
#[test]
fn examples_work() {
let examples = vec![
("1122", 3),
("1111", 4),
("1234", 0),
("91212129", 9),
];
for example in examples {
println!("Testing case ({}, {})", example.0, example.1);
let mut digits = string_to_digit_list(example.0);
let total = solution(&mut digits);
assert_eq!(total, example.1);
}
}
// Answer to challenge 2 for Advent of Code 2017 on December 1
const MY_INPUT: &str = "INPUT GOES HERE";
/// Creates a vector where each element is a single digit taken from the input string, in order.
///
/// `input` is expected to be a string of digits in base 10.
///
/// # Panics
///
/// This function will panic if `input` contains characters that are not any of the digits 0 to 9.
fn string_to_digit_list(input: &str) -> Vec<u8> {
let mut digit_list = Vec::with_capacity(input.len());
let characters = input.chars();
for digit_character in characters {
let digit = digit_character.to_digit(10).unwrap();
digit_list.push(digit as u8);
}
digit_list
}
/// Solution to Advent of Code 2017 December 1 Challenge 2.
///
/// My solution here is to simulate something of a circularly-linked list using a vector, making
/// "circular" lookups possible by simply computing an offset from a given index modulo the length
/// of the list of digits.
fn solution(digits: &mut Vec<u8>) -> u64 {
let mut sum: u64 = 0;
let offset = digits.len() / 2;
for current_index in 0..digits.len() {
let next_index = (current_index + offset) % digits.len();
let (current, next) = (digits[current_index], digits[next_index]);
if current == next {
sum += current as u64;
}
}
sum
}
fn main() {
let mut digits = string_to_digit_list(MY_INPUT);
let answer = solution(&mut digits);
println!("Answer = {}", answer);
}
#[test]
fn examples_work() {
let examples = vec![
("1212", 6),
("1221", 0),
("123425", 4),
("123123", 12),
("12131415", 4),
];
for example in examples {
println!("Testing case ({}, {})", example.0, example.1);
let mut digits = string_to_digit_list(example.0);
let total = solution(&mut digits);
assert_eq!(total, example.1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment