Refactoring, Added day9
This commit is contained in:
parent
28a57f0ff7
commit
5f243befac
94
src/day9/1.rs
Normal file
94
src/day9/1.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
#![feature(byte_slice_trim_ascii)]
|
||||
#![feature(test)]
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
extern crate test;
|
||||
|
||||
const INPUTS: [&[u8]; 2] = [
|
||||
include_bytes!("./sample1.txt"),
|
||||
include_bytes!("./input.txt"),
|
||||
];
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Move {
|
||||
R(usize),
|
||||
L(usize),
|
||||
U(usize),
|
||||
D(usize),
|
||||
}
|
||||
|
||||
fn parse(input: &[u8]) -> impl Iterator<Item = Move> + '_ {
|
||||
input.trim_ascii().split(|&c| c == b'\n').map(|line| {
|
||||
let (a, b) = line.split_at(1);
|
||||
|
||||
let b = b
|
||||
.iter()
|
||||
.skip(1)
|
||||
.fold(0, |a, x| (a * 10) + (x - b'0') as usize);
|
||||
|
||||
match &a {
|
||||
[b'R'] => Move::R(b),
|
||||
[b'L'] => Move::L(b),
|
||||
[b'U'] => Move::U(b),
|
||||
[b'D'] => Move::D(b),
|
||||
|
||||
_ => unreachable!(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for input in INPUTS.iter() {
|
||||
let output = parse(input);
|
||||
let score = solution(output);
|
||||
println!("{}", score);
|
||||
}
|
||||
}
|
||||
|
||||
fn solution(input: impl Iterator<Item = Move>) -> usize {
|
||||
let (mut sxh, mut syh) = (0, 0);
|
||||
let (mut sxt, mut syt) = (0, 0);
|
||||
|
||||
let mut set = HashSet::with_capacity(5000);
|
||||
|
||||
for mmove in input {
|
||||
let (steps, (dsxh, dsyh)): (usize, (i32, i32)) = match mmove {
|
||||
Move::R(v) => (v, (1, 0)),
|
||||
Move::L(v) => (v, (-1, 0)),
|
||||
Move::U(v) => (v, (0, -1)),
|
||||
Move::D(v) => (v, (0, 1)),
|
||||
};
|
||||
for _ in 0..steps {
|
||||
sxh += dsxh;
|
||||
syh += dsyh;
|
||||
|
||||
(sxt, syt) = move_tail((sxh, syh), (sxt, syt));
|
||||
|
||||
set.insert((sxt, syt));
|
||||
}
|
||||
}
|
||||
|
||||
set.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn move_tail((sxh, syh): (i32, i32), (sxt, syt): (i32, i32)) -> (i32, i32) {
|
||||
let dx = sxh - sxt;
|
||||
let dy = syh - syt;
|
||||
|
||||
if dx.abs() == 2 || dy.abs() == 2 {
|
||||
(sxt + dx.signum(), syt + dy.signum())
|
||||
} else {
|
||||
(sxt, syt)
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn solution_bench(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
let input = parse(INPUTS[1]);
|
||||
let result = solution(input);
|
||||
test::black_box(result);
|
||||
})
|
||||
}
|
107
src/day9/2.rs
Normal file
107
src/day9/2.rs
Normal file
|
@ -0,0 +1,107 @@
|
|||
#![feature(byte_slice_trim_ascii)]
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
const INPUTS: [&[u8]; 2] = [
|
||||
include_bytes!("./sample.txt"),
|
||||
include_bytes!("./input.txt"),
|
||||
];
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Move {
|
||||
R(u8),
|
||||
L(u8),
|
||||
U(u8),
|
||||
D(u8),
|
||||
}
|
||||
|
||||
fn parse(input: &[u8]) -> Vec<Move> {
|
||||
input
|
||||
.trim_ascii()
|
||||
.split(|&c| c == b'\n')
|
||||
.map(|line| {
|
||||
let (a, b) = line.split_at(1);
|
||||
|
||||
let b = b.iter().skip(1).fold(0, |a, x| (a * 10) + (x - b'0'));
|
||||
|
||||
match &a {
|
||||
[b'R'] => Move::R(b),
|
||||
[b'L'] => Move::L(b),
|
||||
[b'U'] => Move::U(b),
|
||||
[b'D'] => Move::D(b),
|
||||
|
||||
_ => unreachable!(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for input in INPUTS.iter() {
|
||||
let output = parse(input);
|
||||
let score = solution(output);
|
||||
println!("{}", score);
|
||||
}
|
||||
}
|
||||
|
||||
fn solution(input: Vec<Move>) -> usize {
|
||||
let mut locs = [(0, 0); 10];
|
||||
let mut set: HashSet<(i32, i32)> = HashSet::with_capacity_and_hasher(3000, Default::default());
|
||||
set.insert((0, 0));
|
||||
|
||||
for mmove in input {
|
||||
let (steps, (dsxh, dsyh)) = match mmove {
|
||||
Move::R(v) => (v, (1, 0)),
|
||||
Move::L(v) => (v, (-1, 0)),
|
||||
Move::U(v) => (v, (0, -1)),
|
||||
Move::D(v) => (v, (0, 1)),
|
||||
};
|
||||
|
||||
let locs9 = locs[9];
|
||||
|
||||
for _ in 0..steps {
|
||||
// Update Head position
|
||||
locs[0].0 += dsxh;
|
||||
locs[0].1 += dsyh;
|
||||
|
||||
// One by one, Updated position of each knot
|
||||
for i in 1..10 {
|
||||
let loci = move_tail(locs[i - 1], locs[i]);
|
||||
if loci == locs[i] {
|
||||
break;
|
||||
}
|
||||
locs[i] = loci;
|
||||
}
|
||||
|
||||
if locs9 != locs[9] {
|
||||
set.insert(locs[9]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn move_tail((sxh, syh): (i32, i32), (sxt, syt): (i32, i32)) -> (i32, i32) {
|
||||
let dx = sxh - sxt;
|
||||
let dy = syh - syt;
|
||||
|
||||
if dx.abs() == 2 || dy.abs() == 2 {
|
||||
// signum gets you 1 or -1 depending on the sign of number
|
||||
(sxt + dx.signum(), syt + dy.signum())
|
||||
} else {
|
||||
(sxt, syt)
|
||||
}
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn solution_bench(b: &mut test::Bencher) {
|
||||
b.iter(|| {
|
||||
let input = parse(INPUTS[1]);
|
||||
let result = solution(input);
|
||||
test::black_box(result);
|
||||
})
|
||||
}
|
2000
src/day9/input.txt
Normal file
2000
src/day9/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
8
src/day9/sample.txt
Normal file
8
src/day9/sample.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
R 5
|
||||
U 8
|
||||
L 8
|
||||
D 3
|
||||
R 17
|
||||
D 10
|
||||
L 25
|
||||
U 20
|
8
src/day9/sample1.txt
Normal file
8
src/day9/sample1.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
R 4
|
||||
U 4
|
||||
L 3
|
||||
D 1
|
||||
R 4
|
||||
D 1
|
||||
L 5
|
||||
R 2
|
Loading…
Reference in New Issue
Block a user