Solve day 1 in Rust
This commit is contained in:
parent
2aab786dba
commit
abda4f84d8
48
rust/main.rs
48
rust/main.rs
@ -1,3 +1,49 @@
|
|||||||
|
mod puzzle;
|
||||||
|
mod puzzles;
|
||||||
|
use crate::puzzle::Puzzle;
|
||||||
|
use puzzles::day1;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
const PUZZLES: [&dyn SomePuzzle; 1] = [&day1::PUZZLE];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
[false, true].iter().for_each(|is_real_data| {
|
||||||
|
let t = if *is_real_data { "real" } else { "examples" };
|
||||||
|
println!("{}", t);
|
||||||
|
PUZZLES.into_iter().for_each(|puzzle| {
|
||||||
|
println!(" {}", puzzle.number());
|
||||||
|
let input = fs::read_to_string(format!("../inputs/{}/{}", t, puzzle.number()))
|
||||||
|
.expect("no input file");
|
||||||
|
puzzle.run(&input).iter().zip(1..).for_each(|(output, n)| {
|
||||||
|
let expected =
|
||||||
|
fs::read_to_string(format!("../outputs/{}/{}/{}", t, puzzle.number(), n))
|
||||||
|
.expect("no golden file");
|
||||||
|
print!(" {}: ", n);
|
||||||
|
if expected == *output {
|
||||||
|
println!("OK");
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"expected {}, got {}",
|
||||||
|
expected.trim_end(),
|
||||||
|
output.trim_end()
|
||||||
|
);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SomePuzzle {
|
||||||
|
fn number(&self) -> u32;
|
||||||
|
fn run(&self, input: &str) -> Vec<String>;
|
||||||
|
}
|
||||||
|
impl<Input, Output: Display, const N: usize> SomePuzzle for Puzzle<Input, Output, { N }> {
|
||||||
|
fn number(&self) -> u32 {
|
||||||
|
self.number
|
||||||
|
}
|
||||||
|
fn run(&self, s: &str) -> Vec<String> {
|
||||||
|
let input = (self.parser)(s);
|
||||||
|
self.parts.map(|p| p(&input).to_string() + "\n").to_vec()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
rust/puzzle.rs
Normal file
5
rust/puzzle.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub struct Puzzle<Input, Output, const N: usize> {
|
||||||
|
pub number: u32,
|
||||||
|
pub parser: fn(&str) -> Input,
|
||||||
|
pub parts: [fn(&Input) -> Output; N],
|
||||||
|
}
|
||||||
70
rust/puzzles/day1.rs
Normal file
70
rust/puzzles/day1.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use crate::puzzle::Puzzle;
|
||||||
|
|
||||||
|
pub const PUZZLE: Puzzle<Vec<(Direction, i32)>, i32, 2> = Puzzle {
|
||||||
|
number: 1,
|
||||||
|
parser: |input| {
|
||||||
|
input
|
||||||
|
.lines()
|
||||||
|
.filter(|line| !line.is_empty())
|
||||||
|
.map(|line| {
|
||||||
|
let d = match line.chars().next().unwrap() {
|
||||||
|
'L' => Direction::L,
|
||||||
|
'R' => Direction::R,
|
||||||
|
c => panic!("Unknown direction: {}", c),
|
||||||
|
};
|
||||||
|
let i: i32 = line[1..].parse().unwrap();
|
||||||
|
(d, i)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
},
|
||||||
|
parts: [
|
||||||
|
|instructions| {
|
||||||
|
let mut p = 50;
|
||||||
|
let mut r = 0;
|
||||||
|
for (d, i) in instructions {
|
||||||
|
let (_, p1) = step(*i, *d, p);
|
||||||
|
if p1 == 0 {
|
||||||
|
r += 1;
|
||||||
|
}
|
||||||
|
p = p1;
|
||||||
|
}
|
||||||
|
r
|
||||||
|
},
|
||||||
|
|instructions| {
|
||||||
|
let mut p = 50;
|
||||||
|
let mut r = 0;
|
||||||
|
for (d, i) in instructions {
|
||||||
|
let (c, p1) = step(*i, *d, p);
|
||||||
|
let c1 = match d {
|
||||||
|
Direction::R => c.abs(),
|
||||||
|
Direction::L => {
|
||||||
|
if p == 0 {
|
||||||
|
c.abs() - 1
|
||||||
|
} else if p1 == 0 {
|
||||||
|
c.abs() + 1
|
||||||
|
} else {
|
||||||
|
c.abs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r += c1;
|
||||||
|
p = p1;
|
||||||
|
}
|
||||||
|
r
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Direction {
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(i: i32, d: Direction, p: i32) -> (i32, i32) {
|
||||||
|
let p1 = match d {
|
||||||
|
Direction::L => p - i,
|
||||||
|
Direction::R => p + i,
|
||||||
|
};
|
||||||
|
(p1.div_euclid(100), p1.rem_euclid(100))
|
||||||
|
}
|
||||||
1
rust/puzzles/mod.rs
Normal file
1
rust/puzzles/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub(crate) mod day1;
|
||||||
Loading…
x
Reference in New Issue
Block a user