Replace all real tests with macro's
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
0c9603fb3e
commit
d2f0553716
21
src/day.rs
21
src/day.rs
|
@ -5,3 +5,24 @@ pub trait Day {
|
|||
fn part1(&self) -> Result<String>;
|
||||
fn part2(&self) -> Result<String>;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! day_tests {
|
||||
($day_struct:ty, $day_number:expr, $part1_expected:expr, $part2_expected:expr) => {
|
||||
#[test]
|
||||
fn part1_real() -> anyhow::Result<()> {
|
||||
use crate::day::Day;
|
||||
let d = <$day_struct>::init(crate::load_input($day_number)?)?;
|
||||
assert_eq!($part1_expected, d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> anyhow::Result<()> {
|
||||
use crate::day::Day;
|
||||
let d = <$day_struct>::init(crate::load_input($day_number)?)?;
|
||||
assert_eq!($part2_expected, d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
}
|
18
src/day01.rs
18
src/day01.rs
|
@ -33,25 +33,11 @@ fn increments((a, b): (i32, i32), c: i32) -> (i32, i32) {
|
|||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use std::fs::read_to_string;
|
||||
use super::Day01;
|
||||
use crate::day::Day;
|
||||
use crate::day_tests;
|
||||
|
||||
#[test]
|
||||
pub fn part1_real() -> anyhow::Result<()> {
|
||||
let f = read_to_string("./input/day01")?;
|
||||
let d = Day01::init(f)?;
|
||||
assert_eq!("1466", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn part2_real() -> anyhow::Result<()> {
|
||||
let f = read_to_string("./input/day01")?;
|
||||
let d = Day01::init(f)?;
|
||||
assert_eq!("1491", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day01, "01", "1466", "1491");
|
||||
|
||||
#[test]
|
||||
pub fn part1_test() -> anyhow::Result<()>{
|
||||
|
|
16
src/day02.rs
16
src/day02.rs
|
@ -60,9 +60,9 @@ fn str_to_instr(s: &str) -> Result<Instruction> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::read_to_string;
|
||||
use crate::day02::Day02;
|
||||
use crate::day::Day;
|
||||
use crate::day_tests;
|
||||
use super::Result;
|
||||
|
||||
const D: &str = r"forward 5
|
||||
|
@ -84,17 +84,5 @@ forward 2";
|
|||
Ok(assert_eq!("900", d2.part2()?))
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn part1_real() -> Result<()> {
|
||||
let f = read_to_string("./input/day02")?;
|
||||
let d = Day02::init(f)?;
|
||||
Ok(assert_eq!("1524750", d.part1()?))
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn part2_real()-> Result<()> {
|
||||
let f = read_to_string("./input/day02")?;
|
||||
let d = Day02::init(f)?;
|
||||
Ok(assert_eq!("1592426537", d.part2()?))
|
||||
}
|
||||
day_tests!(Day02, "02", "1524750", "1592426537");
|
||||
}
|
22
src/day03.rs
22
src/day03.rs
|
@ -124,9 +124,7 @@ fn split_lines(content: &str) -> Vec<bool> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::read_to_string;
|
||||
|
||||
use crate::Day03;
|
||||
use crate::{Day03, day_tests};
|
||||
use crate::day::Day;
|
||||
use anyhow::Result;
|
||||
|
||||
|
@ -159,21 +157,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> Result<()>{
|
||||
let f = read_to_string("./input/day03")?;
|
||||
let t = Day03::init(f)?;
|
||||
let p1 = t.part1()?;
|
||||
assert_eq!("4118544", p1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> Result<()>{
|
||||
let f = read_to_string("./input/day03")?;
|
||||
let t = Day03::init(f)?;
|
||||
let p2 = t.part2()?;
|
||||
assert_eq!("3832770", p2);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day03, "03", "4118544", "3832770");
|
||||
}
|
23
src/day04.rs
23
src/day04.rs
|
@ -126,9 +126,7 @@ impl Board {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::read_to_string;
|
||||
|
||||
use crate::Day04;
|
||||
use crate::{Day04, day_tests};
|
||||
use crate::day04::Board;
|
||||
use crate::day::Day;
|
||||
use anyhow::Result;
|
||||
|
@ -207,22 +205,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> Result<()> {
|
||||
let f = read_to_string("./input/day04")?;
|
||||
let t = Day04::init(f)?;
|
||||
let p1 = t.part1()?;
|
||||
assert_eq!("8136", p1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> Result<()> {
|
||||
let f = read_to_string("./input/day04")?;
|
||||
let t = Day04::init(f)?;
|
||||
let p2 = t.part2()?;
|
||||
assert_eq!("12738", p2);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day04, "04", "8136", "12738");
|
||||
}
|
16
src/day05.rs
16
src/day05.rs
|
@ -141,7 +141,7 @@ fn str_to_vent(st: &str) -> Result<Path> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Day05;
|
||||
use crate::{Day05, day_tests};
|
||||
use crate::day05::{Coordinate, Direction};
|
||||
use crate::day::Day;
|
||||
use anyhow::Result;
|
||||
|
@ -183,17 +183,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> Result<()> {
|
||||
let d = Day05::init(crate::load_input("05")?)?;
|
||||
assert_eq!("6564", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> Result<()> {
|
||||
let d = Day05::init(crate::load_input("05")?)?;
|
||||
assert_eq!("19172", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day05, "05", "6564", "19172");
|
||||
}
|
15
src/day06.rs
15
src/day06.rs
|
@ -37,6 +37,7 @@ mod tests {
|
|||
use crate::day06::Day06;
|
||||
use crate::day::Day;
|
||||
use anyhow::Result;
|
||||
use crate::day_tests;
|
||||
|
||||
const INPUT: &str = r"3,4,3,1,2";
|
||||
|
||||
|
@ -54,19 +55,7 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> Result<()> {
|
||||
let d = Day06::init(crate::load_input("06")?)?;
|
||||
assert_eq!("362740", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> Result<()> {
|
||||
let d = Day06::init(crate::load_input("06")?)?;
|
||||
assert_eq!("1644874076764", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day06, "06", "362740", "1644874076764");
|
||||
|
||||
#[test]
|
||||
fn youri_test() -> Result<()> {
|
||||
|
|
15
src/day07.rs
15
src/day07.rs
|
@ -43,6 +43,7 @@ mod tests {
|
|||
use crate::day07::Day07;
|
||||
use crate::day::Day;
|
||||
use anyhow::Result;
|
||||
use crate::day_tests;
|
||||
|
||||
const INPUT: &str = "16,1,2,0,4,2,7,1,2,14";
|
||||
|
||||
|
@ -60,17 +61,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> Result<()> {
|
||||
let d = Day07::init(crate::load_input("07")?)?;
|
||||
assert_eq!("357353", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> Result<()> {
|
||||
let d = Day07::init(crate::load_input("07")?)?;
|
||||
assert_eq!("104822130", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day07, "07", "357353", "104822130");
|
||||
}
|
16
src/day08.rs
16
src/day08.rs
|
@ -65,7 +65,7 @@ fn foo(st: &str) -> (Vec<String>, Vec<String>) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests{
|
||||
use crate::Day08;
|
||||
use crate::{Day08, day_tests};
|
||||
use crate::day::Day;
|
||||
|
||||
const INPUT: &str = r"be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
|
||||
|
@ -93,17 +93,5 @@ gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> anyhow::Result<()> {
|
||||
let d = Day08::init(crate::load_input("08")?)?;
|
||||
assert_eq!("479", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> anyhow::Result<()> {
|
||||
let d = Day08::init(crate::load_input("08")?)?;
|
||||
assert_eq!("1041746", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day08, "08", "479", "1041746");
|
||||
}
|
16
src/day09.rs
16
src/day09.rs
|
@ -77,7 +77,7 @@ impl Day09 {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Day09;
|
||||
use crate::{Day09, day_tests};
|
||||
use crate::day::Day;
|
||||
|
||||
const INPUT: &str = r"2199943210
|
||||
|
@ -100,17 +100,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> anyhow::Result<()> {
|
||||
let d = Day09::init(crate::load_input("09")?)?;
|
||||
assert_eq!("439", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> anyhow::Result<()> {
|
||||
let d = Day09::init(crate::load_input("09")?)?;
|
||||
assert_eq!("900900", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day09, "09", "439", "900900");
|
||||
}
|
16
src/day10.rs
16
src/day10.rs
|
@ -114,7 +114,7 @@ pub enum Bracket {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Day;
|
||||
use crate::{Day, day_tests};
|
||||
use crate::day10::Day10;
|
||||
|
||||
const INPUT: &str = r"[({(<(())[]>[[{[]{<()<>>
|
||||
|
@ -142,17 +142,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> anyhow::Result<()> {
|
||||
let d = Day10::init(crate::load_input("10")?)?;
|
||||
assert_eq!("392421", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> anyhow::Result<()> {
|
||||
let d = Day10::init(crate::load_input("10")?)?;
|
||||
assert_eq!("2769449099", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day10, "10", "392421", "2769449099");
|
||||
}
|
16
src/day11.rs
16
src/day11.rs
|
@ -100,7 +100,7 @@ fn print_flashes(map: &FlashMap, x_max: i32, y_max: i32) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::Day;
|
||||
use crate::{Day, day_tests};
|
||||
use crate::day11::Day11;
|
||||
|
||||
const INPUT: &str = r"5483143223
|
||||
|
@ -128,17 +128,5 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> anyhow::Result<()> {
|
||||
let d = Day11::init(crate::load_input("11")?)?;
|
||||
assert_eq!("1647", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> anyhow::Result<()> {
|
||||
let d = Day11::init(crate::load_input("11")?)?;
|
||||
assert_eq!("348", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day11, "11", "1647", "348");
|
||||
}
|
15
src/day14.rs
15
src/day14.rs
|
@ -99,6 +99,7 @@ fn do_pain(input: &HashMap<String, u64>, map: &ReplacementMap) -> HashMap<String
|
|||
mod tests {
|
||||
use crate::day14::Day14;
|
||||
use crate::day::Day;
|
||||
use crate::day_tests;
|
||||
|
||||
const INPUT: &str = r"NNCB
|
||||
|
||||
|
@ -133,17 +134,5 @@ CN -> C";
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() -> anyhow::Result<()> {
|
||||
let d = Day14::init(crate::load_input("14")?)?;
|
||||
assert_eq!("2590", d.part1()?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() -> anyhow::Result<()> {
|
||||
let d = Day14::init(crate::load_input("14")?)?;
|
||||
assert_eq!("2875665202438", d.part2()?);
|
||||
Ok(())
|
||||
}
|
||||
day_tests!(Day14, "14", "2590", "2875665202438");
|
||||
}
|
61
src/day16.rs
61
src/day16.rs
|
@ -41,7 +41,7 @@ enum PacketType {
|
|||
|
||||
impl From<u8> for PacketType {
|
||||
fn from(n: u8) -> Self {
|
||||
use PacketType::*;
|
||||
use PacketType::{Sum, Product, Minimum, Maximum, Literal, Greater, Less, Eq};
|
||||
match n {
|
||||
0 => Sum,
|
||||
1 => Product,
|
||||
|
@ -79,7 +79,7 @@ fn hex_to_bytes(hex: char) -> [u8; 4] {
|
|||
}
|
||||
|
||||
fn parse_str<T: AsRef<str>>(content: T) -> Vec<u8> {
|
||||
content.as_ref().chars().map(hex_to_bytes).flatten().collect::<Vec<_>>()
|
||||
content.as_ref().chars().flat_map(hex_to_bytes).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
impl Day for Day16 {
|
||||
|
@ -90,7 +90,6 @@ impl Day for Day16 {
|
|||
}
|
||||
|
||||
fn part1(&self) -> anyhow::Result<String> {
|
||||
let p = &self.0;
|
||||
fn calc(packet: &Packet) -> u32 {
|
||||
(packet.version) + if packet.type_id == PacketType::Literal {
|
||||
0
|
||||
|
@ -98,11 +97,10 @@ impl Day for Day16 {
|
|||
packet.sub_packets.iter().map(calc).sum()
|
||||
}
|
||||
}
|
||||
Ok(format!("{}", calc(p)))
|
||||
Ok(format!("{}", calc(&self.0)))
|
||||
}
|
||||
|
||||
fn part2(&self) -> anyhow::Result<String> {
|
||||
let p = &self.0;
|
||||
fn calc(packet: &Packet) -> u64 {
|
||||
match packet.type_id {
|
||||
PacketType::Sum => packet.sub_packets.iter().map(calc).sum(),
|
||||
|
@ -110,46 +108,25 @@ impl Day for Day16 {
|
|||
PacketType::Minimum => packet.sub_packets.iter().map(calc).min().unwrap(),
|
||||
PacketType::Maximum => packet.sub_packets.iter().map(calc).max().unwrap(),
|
||||
PacketType::Literal => packet.value,
|
||||
PacketType::Greater => {
|
||||
let z = packet.sub_packets.iter().map(calc).collect::<Vec<_>>();
|
||||
if z[0] > z[1] {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
PacketType::Greater => (calc(&packet.sub_packets[0]) > calc(&packet.sub_packets[1])) as u64,
|
||||
PacketType::Less => (calc(&packet.sub_packets[0]) < calc(&packet.sub_packets[1])) as u64,
|
||||
PacketType::Eq => (calc(&packet.sub_packets[0]) == calc(&packet.sub_packets[1])) as u64,
|
||||
}
|
||||
}
|
||||
PacketType::Less => {
|
||||
let z = packet.sub_packets.iter().map(calc).collect::<Vec<_>>();
|
||||
if z[0] < z[1] {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
PacketType::Eq => {
|
||||
let z = packet.sub_packets.iter().map(calc).collect::<Vec<_>>();
|
||||
if z[0] == z[1] {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(format!("{}", calc(p)))
|
||||
Ok(format!("{}", calc(&self.0)))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_packet<T: Iterator<Item=u8>>(it: &mut T) -> Option<Packet> {
|
||||
let version = it.take(3).enumerate().fold(0, |a, (idx, num)| a | ((num as u32) << (2 - idx)));
|
||||
let version = it.take(3).enumerate().fold(0, |a, (idx, num)| a | (u32::from(num) << (2 - idx)));
|
||||
let type_id = it.take(3).enumerate().fold(0, |a, (idx, num)| a | (num << (2 - idx))).into();
|
||||
|
||||
|
||||
Some(Packet {
|
||||
version,
|
||||
type_id,
|
||||
sub_packets: if type_id != PacketType::Literal { decode_other(it)? } else { Vec::new() },
|
||||
value: if type_id == PacketType::Literal { decode_literal(it)? } else { 0 },
|
||||
sub_packets: if type_id == PacketType::Literal { Vec::new() } else { decode_other(it)? },
|
||||
value: if type_id == PacketType::Literal { decode_literal(it) } else { 0 },
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -162,7 +139,7 @@ fn decode_other<T: Iterator<Item=u8>>(it: &mut T) -> Option<Vec<Packet>> {
|
|||
let mut new_iter = to_parse.iter().copied().peekable();
|
||||
let mut a = Vec::new();
|
||||
while new_iter.peek().is_some() {
|
||||
a.push(parse_packet(&mut new_iter)?)
|
||||
a.push(parse_packet(&mut new_iter)?);
|
||||
}
|
||||
Some(a)
|
||||
}
|
||||
|
@ -178,28 +155,28 @@ fn decode_other<T: Iterator<Item=u8>>(it: &mut T) -> Option<Vec<Packet>> {
|
|||
};
|
||||
}
|
||||
|
||||
fn decode_literal<T: Iterator<Item=u8>>(it: &mut T) -> Option<u64> {
|
||||
fn decode_literal<T: Iterator<Item=u8>>(it: &mut T) -> u64 {
|
||||
let mut z = it.take(5).collect::<Vec<_>>();
|
||||
let mut n = 0;
|
||||
loop {
|
||||
for a in 0..4 {
|
||||
n <<= 1;
|
||||
n += z[a + 1] as u64
|
||||
n += u64::from(z[a + 1]);
|
||||
}
|
||||
|
||||
if z[0] == 0 {
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
z = it.take(5).collect::<Vec<_>>();
|
||||
}
|
||||
}
|
||||
Some(n)
|
||||
n
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::day16::{Day16, PacketType, parse_packet, parse_str};
|
||||
use crate::day::Day;
|
||||
use crate::day_tests;
|
||||
|
||||
#[test]
|
||||
fn test_literal() {
|
||||
|
@ -268,8 +245,8 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn part2_tests() -> anyhow::Result<()>{
|
||||
fn calc(s: &str) -> anyhow::Result<String>{
|
||||
fn part2_tests() -> anyhow::Result<()> {
|
||||
fn calc(s: &str) -> anyhow::Result<String> {
|
||||
let d = Day16::init(s.to_string())?;
|
||||
d.part2()
|
||||
}
|
||||
|
@ -284,4 +261,6 @@ mod tests {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
day_tests!(Day16, "16", "979", "277110354175");
|
||||
}
|
Loading…
Reference in a new issue