2021 day8/rust: add solutions
This commit is contained in:
parent
6b9ff21a5a
commit
aa464884fe
7 changed files with 280 additions and 0 deletions
15
2021/day8/day8_rs/Cargo.toml
Normal file
15
2021/day8/day8_rs/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "day8_rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
criterion = "0.3.5"
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "unscramble"
|
||||||
|
harness = false
|
13
2021/day8/day8_rs/src/lib.rs
Normal file
13
2021/day8/day8_rs/src/lib.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#![warn(clippy::pedantic)]
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||||
|
pub struct LineResult {
|
||||||
|
pub unique_digits: usize,
|
||||||
|
pub number: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod v1;
|
||||||
|
pub mod v2;
|
||||||
|
pub mod v3;
|
||||||
|
pub mod v4;
|
23
2021/day8/day8_rs/src/main.rs
Normal file
23
2021/day8/day8_rs/src/main.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#![warn(clippy::pedantic)]
|
||||||
|
use day8_rs::{v3::unscramble, LineResult};
|
||||||
|
use std::io::{stdin, BufRead};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let result = stdin()
|
||||||
|
.lock()
|
||||||
|
.lines()
|
||||||
|
.map(|s| unscramble(&s.unwrap()))
|
||||||
|
.fold(
|
||||||
|
LineResult {
|
||||||
|
unique_digits: 0,
|
||||||
|
number: 0,
|
||||||
|
},
|
||||||
|
|a, b| LineResult {
|
||||||
|
unique_digits: a.unique_digits + b.unique_digits,
|
||||||
|
number: a.number + b.number,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("{}", result.unique_digits);
|
||||||
|
println!("{}", result.number);
|
||||||
|
}
|
51
2021/day8/day8_rs/src/v1.rs
Normal file
51
2021/day8/day8_rs/src/v1.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::LineResult;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn lookup(n: usize) -> usize {
|
||||||
|
match n {
|
||||||
|
17 => 1,
|
||||||
|
25 => 7,
|
||||||
|
30 => 4,
|
||||||
|
34 => 2,
|
||||||
|
37 => 5,
|
||||||
|
39 => 3,
|
||||||
|
41 => 6,
|
||||||
|
42 => 0,
|
||||||
|
49 => 8,
|
||||||
|
45 => 9,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn unscramble(line: &str) -> LineResult {
|
||||||
|
let mut parts = line.split('|');
|
||||||
|
let input = parts.next().unwrap();
|
||||||
|
|
||||||
|
let mut counts: HashMap<_, usize> = HashMap::new();
|
||||||
|
for c in input.chars() {
|
||||||
|
*counts.entry(c).or_default() += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let digits: Vec<_> = parts
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.split(' ')
|
||||||
|
.map(|s| s.chars().map(|c| counts[&c]).sum())
|
||||||
|
.map(lookup)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
LineResult {
|
||||||
|
unique_digits: digits.iter().filter(|d| [1, 4, 7, 8].contains(d)).count(),
|
||||||
|
number: digits
|
||||||
|
.iter()
|
||||||
|
.map(|&d| char::from_digit(d as u32, 10).unwrap())
|
||||||
|
.collect::<String>()
|
||||||
|
.parse()
|
||||||
|
.unwrap(),
|
||||||
|
}
|
||||||
|
}
|
52
2021/day8/day8_rs/src/v2.rs
Normal file
52
2021/day8/day8_rs/src/v2.rs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
use crate::LineResult;
|
||||||
|
|
||||||
|
const FREQ_TABLE: [usize; 50] = {
|
||||||
|
let mut tab = [0; 50];
|
||||||
|
tab[17] = 1;
|
||||||
|
tab[25] = 7;
|
||||||
|
tab[30] = 4;
|
||||||
|
tab[34] = 2;
|
||||||
|
tab[37] = 5;
|
||||||
|
tab[39] = 3;
|
||||||
|
tab[41] = 6;
|
||||||
|
tab[42] = 0;
|
||||||
|
tab[45] = 9;
|
||||||
|
tab[49] = 8;
|
||||||
|
tab
|
||||||
|
};
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub fn unscramble(line: &str) -> LineResult {
|
||||||
|
let mut parts = line.split('|');
|
||||||
|
let input = parts.next().unwrap();
|
||||||
|
|
||||||
|
let mut counts = [0; 7];
|
||||||
|
for c in input.bytes() {
|
||||||
|
if (b'a'..=b'g').contains(&c) {
|
||||||
|
counts[c as usize - b'a' as usize] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let digits: Vec<_> = parts
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.split(' ')
|
||||||
|
.map(|s| s.bytes().map(|c| counts[c as usize - b'a' as usize]).sum())
|
||||||
|
.map(|n: usize| FREQ_TABLE[n])
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
LineResult {
|
||||||
|
unique_digits: digits.iter().filter(|d| [1, 4, 7, 8].contains(d)).count(),
|
||||||
|
number: digits
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.scan(1, |mul, &d| {
|
||||||
|
let ret = Some(d * *mul);
|
||||||
|
*mul *= 10;
|
||||||
|
ret
|
||||||
|
})
|
||||||
|
.sum(),
|
||||||
|
}
|
||||||
|
}
|
63
2021/day8/day8_rs/src/v3.rs
Normal file
63
2021/day8/day8_rs/src/v3.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::LineResult;
|
||||||
|
|
||||||
|
const FREQ_TABLE: [usize; 256] = {
|
||||||
|
let mut tab = [0; 256];
|
||||||
|
tab[17] = 1;
|
||||||
|
tab[25] = 7;
|
||||||
|
tab[30] = 4;
|
||||||
|
tab[34] = 2;
|
||||||
|
tab[37] = 5;
|
||||||
|
tab[39] = 3;
|
||||||
|
tab[41] = 6;
|
||||||
|
tab[42] = 0;
|
||||||
|
tab[45] = 9;
|
||||||
|
tab[49] = 8;
|
||||||
|
tab
|
||||||
|
};
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub fn unscramble(line: &str) -> LineResult {
|
||||||
|
let mut bytes = line.bytes();
|
||||||
|
|
||||||
|
let mut counts = [0; 7];
|
||||||
|
loop {
|
||||||
|
match bytes.next().unwrap() {
|
||||||
|
c @ b'a'..=b'g' => {
|
||||||
|
counts[c as usize - b'a' as usize] += 1;
|
||||||
|
}
|
||||||
|
b'|' => break,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.next();
|
||||||
|
|
||||||
|
let mut freq = 0;
|
||||||
|
let mut unique_digits = 0;
|
||||||
|
let mut number = 0;
|
||||||
|
loop {
|
||||||
|
let c = bytes.next();
|
||||||
|
match c {
|
||||||
|
Some(b' ') | None => {
|
||||||
|
let digit = FREQ_TABLE[freq & 0xff];
|
||||||
|
if [1, 4, 7, 8].contains(&digit) {
|
||||||
|
unique_digits += 1;
|
||||||
|
}
|
||||||
|
number = number * 10 + digit;
|
||||||
|
freq = 0;
|
||||||
|
if c.is_none() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(c) => {
|
||||||
|
freq += counts[c as usize - b'a' as usize];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LineResult {
|
||||||
|
unique_digits,
|
||||||
|
number,
|
||||||
|
}
|
||||||
|
}
|
63
2021/day8/day8_rs/src/v4.rs
Normal file
63
2021/day8/day8_rs/src/v4.rs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
use crate::LineResult;
|
||||||
|
|
||||||
|
const FREQ_TABLE: [usize; 256] = {
|
||||||
|
let mut tab = [0; 256];
|
||||||
|
tab[17] = 1;
|
||||||
|
tab[25] = 7;
|
||||||
|
tab[30] = 4;
|
||||||
|
tab[34] = 2;
|
||||||
|
tab[37] = 5;
|
||||||
|
tab[39] = 3;
|
||||||
|
tab[41] = 6;
|
||||||
|
tab[42] = 0;
|
||||||
|
tab[45] = 9;
|
||||||
|
tab[49] = 8;
|
||||||
|
tab
|
||||||
|
};
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
#[inline]
|
||||||
|
pub fn unscramble(line: &str) -> LineResult {
|
||||||
|
let mut bytes = line.bytes();
|
||||||
|
|
||||||
|
let mut counts = [0; 7];
|
||||||
|
loop {
|
||||||
|
match bytes.next().unwrap() {
|
||||||
|
c @ b'a'..=b'g' => {
|
||||||
|
*unsafe { counts.get_unchecked_mut(c as usize - b'a' as usize) } += 1;
|
||||||
|
}
|
||||||
|
b'|' => break,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes.next();
|
||||||
|
|
||||||
|
let mut freq = 0;
|
||||||
|
let mut unique_digits = 0;
|
||||||
|
let mut number = 0;
|
||||||
|
loop {
|
||||||
|
let c = bytes.next();
|
||||||
|
match c {
|
||||||
|
Some(b' ') | None => {
|
||||||
|
let digit = FREQ_TABLE[freq & 0xff];
|
||||||
|
if [1, 4, 7, 8].contains(&digit) {
|
||||||
|
unique_digits += 1;
|
||||||
|
}
|
||||||
|
number = number * 10 + digit;
|
||||||
|
freq = 0;
|
||||||
|
if c.is_none() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(c) => {
|
||||||
|
freq += unsafe { counts.get_unchecked(c as usize - b'a' as usize) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LineResult {
|
||||||
|
unique_digits,
|
||||||
|
number,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue