Skip to content

Instantly share code, notes, and snippets.

@kjhoerr
Last active December 25, 2017 07:41
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 kjhoerr/e0b81e416a9645a3db83961414f5dd0a to your computer and use it in GitHub Desktop.
Save kjhoerr/e0b81e416a9645a3db83961414f5dd0a to your computer and use it in GitHub Desktop.
aocday1a.rs
#[cfg(not(test))]
use std::env;
// take a string and turn it into a vector of digits
fn to_vec (input: &String) -> Result<Vec<u32>,()> {
input
.chars()
.map(|c| c.to_digit(10).ok_or(()))
.collect()
}
// take a vector of digits and sum the number of digits whose next digit is the same number (cyclic)
fn count_seq (sequence: Vec<u32>) -> Option<u32> {
let first: &u32 = sequence.first()?;
// map the sequence to a slice (by reference) with comparative digits, and zip the sequences
let next_seq: &[u32] = &sequence[1..];
let pairs = sequence.iter().zip(next_seq);
// calculate last (unzipped) digit
let last_match: &u32 =
if sequence.len() > 1 && sequence.last().unwrap() == first { first }
else { &0 };
// map the tuple of digits to the digit if the digits are the same, else 0, and sum them
Some(pairs.map(|(a, b)| {
if a == b { *a } else { 0 }
}).sum::<u32>() + *last_match)
}
// magically convert string of numbers into result
fn magic (input: &String) -> Option<u32> {
count_seq(to_vec(input).ok()?)
}
#[cfg(not(test))]
fn main () {
// get input number as positional argument
let args: Vec<String> = env::args().collect();
let query: &String = &args[1];
println!("Number Sequence: {}", query);
let result: u32 = magic(query).unwrap_or(0);
println!("Captcha result: {}", result);
}
// Unit tests
#[cfg(test)]
mod tests {
use super::*;
macro_rules! nstr {
($x:expr) => (&$x.to_owned())
}
macro_rules! unwrap {
($funct:ident, $input:expr) => (($funct(&$input.to_owned())).unwrap())
}
macro_rules! gen_tests {
($($name:ident: ($expected:expr, $actual:expr),)*) => {
$(
#[test]
fn $name() {
assert_eq!($expected, $actual);
}
)*
}
}
gen_tests! {
// to_vec boundaries
to_vec_empty: (true, unwrap!(to_vec, "").is_empty()),
to_vec_1: (vec![1], unwrap!(to_vec, "1")),
to_vec_09: (vec![0,0,0,0,0,0,0,0,0], unwrap!(to_vec, "000000000")),
to_vec_19: (vec![1,1,1,1,1,1,1,1,1], unwrap!(to_vec, "111111111")),
to_vec_99: (vec![9,9,9,9,9,9,9,9,9], unwrap!(to_vec, "999999999")),
// to_vec examples from problem
to_vec_ex1: (vec![1,1,2,2], unwrap!(to_vec, "1122")),
to_vec_ex2: (vec![1,1,1,1], unwrap!(to_vec, "1111")),
to_vec_ex3: (vec![1,2,3,4], unwrap!(to_vec, "1234")),
to_vec_ex4: (vec!(9,1,2,1,2,1,2,9), unwrap!(to_vec, "91212129")),
// to_vec bad inputs
to_vec_no1: (true, to_vec(nstr!("1111b")).is_err()),
to_vec_no2: (true, to_vec(nstr!("0x9513")).is_err()),
to_vec_no3: (true, to_vec(nstr!("!!009")).is_err()),
// count_seq boundaries
count_seq_empty: (None, count_seq(Vec::new())),
count_seq_1: (0, count_seq(vec![1]).unwrap()),
count_seq_09: (0, count_seq(vec![0,0,0,0,0,0,0,0,0]).unwrap()),
count_seq_19: (9, count_seq(vec![1,1,1,1,1,1,1,1,1]).unwrap()),
count_seq_99: (81, count_seq(vec![9,9,9,9,9,9,9,9,9]).unwrap()),
// count_seq examples from problem
count_seq_ex1: (3, count_seq(vec![1,1,2,2]).unwrap()),
count_seq_ex2: (4, count_seq(vec![1,1,1,1]).unwrap()),
count_seq_ex3: (0, count_seq(vec![1,2,3,4]).unwrap()),
count_seq_ex4: (9, count_seq(vec![9,1,2,1,2,1,2,9]).unwrap()),
// magic boundaries
magic_empty: (None, magic(nstr!(""))),
magic_1: (0, unwrap!(magic, "1")),
magic_09: (0, unwrap!(magic, "000000000")),
magic_19: (9, unwrap!(magic, "111111111")),
magic_99: (81, unwrap!(magic, "999999999")),
// magic examples from problem
magic_ex1: (3, unwrap!(magic, "1122")),
magic_ex2: (4, unwrap!(magic, "1111")),
magic_ex3: (0, unwrap!(magic, "1234")),
magic_ex4: (9, unwrap!(magic, "91212129")),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment