Skip to content

Instantly share code, notes, and snippets.

@johngian
Last active December 9, 2023 11:13
Show Gist options
  • Save johngian/617eae3f183e4244e3262a4eba9a9dd1 to your computer and use it in GitHub Desktop.
Save johngian/617eae3f183e4244e3262a4eba9a9dd1 to your computer and use it in GitHub Desktop.
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;
use itertools::Itertools;
pub fn parse_input(path: PathBuf) -> std::io::Lines<std::io::BufReader<std::fs::File>> {
let file: fs::File = fs::File::open(path).unwrap();
let buf: BufReader<fs::File> = std::io::BufReader::new(file);
buf.lines()
}
pub fn parse_line(line: &str) -> Vec<i32> {
return line
.split_ascii_whitespace()
.map(|elem| elem.parse::<i32>().unwrap())
.collect_vec();
}
pub fn steps(line: Vec<i32>, forward: bool) -> i32 {
let mut all_zero = true;
let sequence = line
.iter()
.zip(line.iter().skip(1))
.map(|(x, y)| {
all_zero = x == y && y == &0;
y - x
})
.collect_vec();
if all_zero {
return 0;
}
if forward {
return line.last().unwrap() + steps(sequence, true);
}
return line.first().unwrap() - steps(sequence, false);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_split_line() {
assert_eq!(parse_line("0 3 6 9 12 15"), [0, 3, 6, 9, 12, 15])
}
#[test]
fn test_parse_input() {
let mut path: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("input/example-1.txt");
let mut lines = parse_input(path);
let line = lines.next().unwrap().unwrap();
assert_eq!(parse_line(&line), [0, 3, 6, 9, 12, 15])
}
#[test]
fn test_steps_example() {
let mut path: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("input/example-1.txt");
let mut lines = parse_input(path);
let line = lines.next().unwrap().unwrap();
let input = parse_line(&line);
assert_eq!(steps(input, true), 18)
}
#[test]
fn test_part1() {
let mut path: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("input/part-1.txt");
let lines = parse_input(path);
let mut sum = 0;
for line in lines {
let input = parse_line(&line.unwrap());
sum += steps(input, true)
}
assert_eq!(sum, 1877825184)
}
#[test]
fn test_steps_backward_example() {
let mut path: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("input/example-1.txt");
let mut lines = parse_input(path);
let line = lines.next().unwrap().unwrap();
let input = parse_line(&line);
assert_eq!(steps(input, false), -3)
}
#[test]
fn test_part2() {
let mut path: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("input/part-1.txt");
let lines = parse_input(path);
let mut sum = 0;
for line in lines {
let input = parse_line(&line.unwrap());
sum += steps(input, false)
}
assert_eq!(sum, 1108)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment