Last active
December 2, 2017 00:07
-
-
Save chaoticsmol/3ef449a4ad6791378adc6715df2da2ef to your computer and use it in GitHub Desktop.
Answers to the Advent of Code challenges
This file contains hidden or 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
// 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); | |
} | |
} |
This file contains hidden or 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
// 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