Compare commits
No commits in common. "33e9af89beb42db8631f176016e70d5cd3a5c552" and "50db6dafd060762b0fe31975da4189675ffae7d9" have entirely different histories.
33e9af89be
...
50db6dafd0
@ -92,6 +92,29 @@ fn show(grid: &Vec2<bool>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SAMPLE: &str = "6,10
|
||||||
|
0,14
|
||||||
|
9,10
|
||||||
|
0,3
|
||||||
|
10,4
|
||||||
|
4,11
|
||||||
|
6,0
|
||||||
|
6,12
|
||||||
|
4,1
|
||||||
|
0,13
|
||||||
|
10,12
|
||||||
|
3,4
|
||||||
|
3,0
|
||||||
|
8,4
|
||||||
|
1,10
|
||||||
|
2,14
|
||||||
|
8,10
|
||||||
|
9,0
|
||||||
|
|
||||||
|
fold along y=7
|
||||||
|
fold along x=5";
|
||||||
|
|
||||||
|
|
||||||
pub fn run(data: &str) -> eyre::Result<(usize, usize)> {
|
pub fn run(data: &str) -> eyre::Result<(usize, usize)> {
|
||||||
let (grid, folds) = load(data)?;
|
let (grid, folds) = load(data)?;
|
||||||
|
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use color_eyre::eyre;
|
|
||||||
|
|
||||||
use crate::lib::{IterExt, Counter};
|
|
||||||
|
|
||||||
|
|
||||||
type Pairs = Counter<(char, char)>;
|
|
||||||
type Rules = HashMap<(char, char), char>;
|
|
||||||
|
|
||||||
|
|
||||||
fn load(data: &str) -> eyre::Result<(Pairs, Rules)> {
|
|
||||||
let mut lines = data.lines();
|
|
||||||
let template = lines.next().unwrap().to_string();
|
|
||||||
let mut pairs = Counter::new();
|
|
||||||
for i in 1..template.len() {
|
|
||||||
let a = template.as_bytes()[i - 1] as char;
|
|
||||||
let b = template.as_bytes()[i] as char;
|
|
||||||
pairs.inc((a, b));
|
|
||||||
}
|
|
||||||
lines.next();
|
|
||||||
|
|
||||||
let mut rules = HashMap::new();
|
|
||||||
for line in &mut lines {
|
|
||||||
let (pair_s, tgt_s) = line.split(" -> ").take_pair()?;
|
|
||||||
let pair = pair_s.chars().take_pair()?;
|
|
||||||
let tgt = tgt_s.chars().next().unwrap();
|
|
||||||
rules.insert(pair, tgt);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((pairs, rules))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn expand(src: &Pairs, rules: &Rules) -> Pairs {
|
|
||||||
let mut dst = Counter::new();
|
|
||||||
for (&(a, b), count) in src.iter() {
|
|
||||||
if let Some(&tween) = rules.get(&(a, b)) {
|
|
||||||
dst.inc_by((a, tween), count);
|
|
||||||
dst.inc_by((tween, b), count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dst
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn score(pairs: &Pairs) -> usize {
|
|
||||||
// "score" is defined as the number of occurences of the most common
|
|
||||||
// character minus the number of occurrences of the least common
|
|
||||||
let mut firsts = Counter::new();
|
|
||||||
let mut lasts = Counter::new();
|
|
||||||
for (pair, count) in pairs.iter() {
|
|
||||||
let (a, b) = *pair;
|
|
||||||
firsts.inc_by(a, count);
|
|
||||||
lasts.inc_by(b, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// the count of a given character is the number of times it appears
|
|
||||||
// in either first or last place of a pair, whichever is greater
|
|
||||||
let mut counts = Counter::new();
|
|
||||||
for (c, count) in firsts.iter().chain(lasts.iter()) {
|
|
||||||
if count > counts.get(c) {
|
|
||||||
counts.set(*c, count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let max = counts.iter().map(|(_c, n)| n).max().unwrap();
|
|
||||||
let min = counts.iter().map(|(_c, n)| n).min().unwrap();
|
|
||||||
max - min
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn run(data: &str) -> eyre::Result<(usize, usize)> {
|
|
||||||
let (mut pairs, rules) = load(data)?;
|
|
||||||
|
|
||||||
for _i in 0..10 {pairs = expand(&pairs, &rules);}
|
|
||||||
let one = score(&pairs);
|
|
||||||
|
|
||||||
for _i in 0..30 {pairs = expand(&pairs, &rules);}
|
|
||||||
let two = score(&pairs);
|
|
||||||
|
|
||||||
Ok((one, two))
|
|
||||||
}
|
|
@ -1,11 +1,9 @@
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt::{Display, Formatter};
|
|
||||||
use std::fs::File;
|
|
||||||
use std::hash::Hash;
|
|
||||||
use std::ops::{Index, IndexMut};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
use color_eyre::{eyre};
|
use color_eyre::{eyre};
|
||||||
use eyre::eyre;
|
use eyre::eyre;
|
||||||
@ -266,54 +264,3 @@ impl<T: Display> Display for Vec2<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Counter<K> {
|
|
||||||
data: HashMap<K, usize>
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl<K> Counter<K>
|
|
||||||
where K: Eq + Hash,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Counter {data: HashMap::<K, usize>::new()}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inc(&mut self, key: K) {
|
|
||||||
let v = self.data.entry(key).or_insert(0);
|
|
||||||
*v += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inc_by(&mut self, key: K, increment: usize) {
|
|
||||||
let v = self.data.entry(key).or_insert(0);
|
|
||||||
*v += increment;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dec(&mut self, key: K) {
|
|
||||||
let v = self.data.entry(key).or_insert(0);
|
|
||||||
if *v > 0 {
|
|
||||||
*v -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dec_by(&mut self, key: K, decrement: usize) {
|
|
||||||
let v = self.data.entry(key).or_insert(0);
|
|
||||||
if *v >= decrement {
|
|
||||||
*v -= decrement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get(&mut self, key: &K) -> usize {
|
|
||||||
*self.data.get(key).unwrap_or(&0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set(&mut self, key: K, value: usize) {
|
|
||||||
self.data.insert(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item =(&'_ K, usize)> {
|
|
||||||
self.data.iter().map(|(k, v)| (k, *v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -4,14 +4,14 @@ use color_eyre::eyre;
|
|||||||
|
|
||||||
mod lib;
|
mod lib;
|
||||||
use lib::load;
|
use lib::load;
|
||||||
mod day14;
|
mod day13;
|
||||||
|
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
let data = load("data/14.txt")?;
|
let data = load("data/13.txt")?;
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let (one, two) = day14::run(&data)?;
|
let (one, two) = day13::run(&data)?;
|
||||||
let (dur, unit) = format_ns(start.elapsed().as_nanos());
|
let (dur, unit) = format_ns(start.elapsed().as_nanos());
|
||||||
|
|
||||||
let precision = 2.0 - dur.log10().floor();
|
let precision = 2.0 - dur.log10().floor();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user