mirror of
https://github.com/mx42/aoc2016.git
synced 2026-01-14 13:49:53 +01:00
feat: add day 10
This commit is contained in:
122
Cargo.lock
generated
122
Cargo.lock
generated
@@ -22,6 +22,7 @@ name = "advent_of_code"
|
||||
version = "0.11.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"color-eyre",
|
||||
"dhat",
|
||||
"itertools",
|
||||
"md5",
|
||||
@@ -116,6 +117,33 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"color-spantrace",
|
||||
"eyre",
|
||||
"indenter",
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color-spantrace"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"owo-colors",
|
||||
"tracing-core",
|
||||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
@@ -144,6 +172,16 @@ version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.28.1"
|
||||
@@ -173,6 +211,12 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
@@ -280,6 +324,12 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
@@ -309,6 +359,12 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
@@ -420,6 +476,15 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
@@ -459,18 +524,75 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820"
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyjson"
|
||||
version = "2.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ab95735ea2c8fd51154d01e39cf13912a78071c2d89abc49a7ef102a7dd725a"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-error"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
dependencies = [
|
||||
"sharded-slab",
|
||||
"thread_local",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.95"
|
||||
|
||||
@@ -23,6 +23,7 @@ test_lib = []
|
||||
|
||||
# Template dependencies
|
||||
chrono = { version = "0.4.38", optional = true }
|
||||
color-eyre = "0.6.3"
|
||||
dhat = { version = "0.3.3", optional = true }
|
||||
itertools = "0.13.0"
|
||||
md5 = "0.7.0"
|
||||
|
||||
@@ -20,8 +20,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
|
||||
| [Day 7](./src/bin/07.rs) | `1.5ms` | `1.3ms` |
|
||||
| [Day 8](./src/bin/08.rs) | `132.9ms` | `-` |
|
||||
| [Day 9](./src/bin/09.rs) | `77.2µs` | `969.4µs` |
|
||||
| [Day 10](./src/bin/10.rs) | `164.5µs` | `287.9µs` |
|
||||
|
||||
**Total: 17333.30ms**
|
||||
**Total: 17333.76ms**
|
||||
<!--- benchmarking table --->
|
||||
|
||||
---
|
||||
|
||||
6
data/examples/10.txt
Normal file
6
data/examples/10.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
value 5 goes to bot 2
|
||||
bot 2 gives low to bot 1 and high to bot 0
|
||||
value 3 goes to bot 1
|
||||
bot 1 gives low to output 1 and high to bot 0
|
||||
bot 0 gives low to output 2 and high to output 0
|
||||
value 2 goes to bot 2
|
||||
196
src/bin/10.rs
Normal file
196
src/bin/10.rs
Normal file
@@ -0,0 +1,196 @@
|
||||
advent_of_code::solution!(10);
|
||||
|
||||
use color_eyre::eyre::{eyre, Report, Result};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
enum GiveTo {
|
||||
Bot(usize),
|
||||
Output(usize),
|
||||
Undef,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Bot {
|
||||
high_out: GiveTo,
|
||||
low_out: GiveTo,
|
||||
current: [Option<u8>; 2],
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct State {
|
||||
bots: HashMap<usize, Bot>,
|
||||
outputs: HashMap<usize, u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Instruction {
|
||||
GiveValue(GiveTo, u8),
|
||||
BotInit(usize, GiveTo, GiveTo),
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn apply(&mut self, instr: Vec<Instruction>) {
|
||||
instr.iter().for_each(|i| match i {
|
||||
Instruction::GiveValue(GiveTo::Bot(bot), value) => {
|
||||
let bot = self.bots.entry(*bot).or_insert(Bot::init());
|
||||
bot.add_value(*value);
|
||||
}
|
||||
Instruction::GiveValue(GiveTo::Output(out), value) => {
|
||||
let out = self.outputs.entry(*out).or_default();
|
||||
if *out != 0 {
|
||||
panic!("Overwriting an output ??");
|
||||
}
|
||||
*out = *value;
|
||||
}
|
||||
Instruction::BotInit(bot, low, high) => {
|
||||
let bot = self.bots.entry(*bot).or_insert(Bot::init());
|
||||
bot.set_outputs(*high, *low);
|
||||
}
|
||||
_ => {
|
||||
println!("{:?}", i);
|
||||
panic!("Unsupported instruction !");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn init() -> Self {
|
||||
Self {
|
||||
bots: HashMap::new(),
|
||||
outputs: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn step(self) -> Option<Self> {
|
||||
let mut new = self.clone();
|
||||
let new_instr: Vec<Instruction> = new
|
||||
.bots
|
||||
.iter_mut()
|
||||
.flat_map(|(_, &mut ref mut bot)| bot.process())
|
||||
.collect();
|
||||
if !new_instr.is_empty() {
|
||||
new.apply(new_instr);
|
||||
Some(new)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for Instruction {
|
||||
type Error = Report;
|
||||
|
||||
fn try_from(input: &str) -> Result<Self> {
|
||||
let input = input.split(" ").collect::<Vec<_>>();
|
||||
match input.len() {
|
||||
// [value] [x] [goes] [to] [bot] [y]
|
||||
6 => Ok(Instruction::GiveValue(
|
||||
GiveTo::Bot(input[5].parse::<usize>()?),
|
||||
input[1].parse::<u8>()?,
|
||||
)),
|
||||
// [bot] [x] [gives] [low] [to] [bot] [y] [and] [high] [to] [bot] [z]
|
||||
12 => {
|
||||
let low: GiveTo = match input[5] {
|
||||
"bot" => GiveTo::Bot(input[6].parse::<usize>()?),
|
||||
"output" => GiveTo::Output(input[6].parse::<usize>()?),
|
||||
_ => panic!("invalid input"),
|
||||
};
|
||||
let high: GiveTo = match input[10] {
|
||||
"bot" => GiveTo::Bot(input[11].parse::<usize>()?),
|
||||
"output" => GiveTo::Output(input[11].parse::<usize>()?),
|
||||
_ => panic!("invalid input"),
|
||||
};
|
||||
Ok(Instruction::BotInit(input[1].parse::<usize>()?, low, high))
|
||||
}
|
||||
_ => Err(eyre!("invalid input ?!")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Bot {
|
||||
fn init() -> Self {
|
||||
Self {
|
||||
high_out: GiveTo::Undef,
|
||||
low_out: GiveTo::Undef,
|
||||
current: [None, None],
|
||||
}
|
||||
}
|
||||
|
||||
fn set_outputs(&mut self, high: GiveTo, low: GiveTo) {
|
||||
if self.high_out != GiveTo::Undef {
|
||||
panic!("Trying to set output to already set output");
|
||||
}
|
||||
self.high_out = high;
|
||||
self.low_out = low;
|
||||
}
|
||||
|
||||
fn add_value(&mut self, value: u8) {
|
||||
let value: Option<u8> = Some(value);
|
||||
if self.current[0].is_none() {
|
||||
self.current[0] = value;
|
||||
} else if self.current[1].is_none() {
|
||||
self.current[1] = value;
|
||||
} else {
|
||||
panic!("Giving a value to an otherwise filled bot!!");
|
||||
}
|
||||
}
|
||||
|
||||
fn process(&mut self) -> Vec<Instruction> {
|
||||
let mut res: Vec<Instruction> = Vec::new();
|
||||
let (low, high) = match self.current {
|
||||
[None, _] => return res,
|
||||
[_, None] => return res,
|
||||
[Some(a), Some(b)] if a < b => (a, b),
|
||||
[Some(a), Some(b)] => (b, a),
|
||||
};
|
||||
self.current = [None, None];
|
||||
res.push(Instruction::GiveValue(self.high_out, high));
|
||||
res.push(Instruction::GiveValue(self.low_out, low));
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
pub fn part_one(input: &str) -> Option<usize> {
|
||||
let mut state = State::init();
|
||||
state.apply(input.lines().flat_map(Instruction::try_from).collect());
|
||||
while let Some(new_state) = state.clone().step() {
|
||||
state = new_state;
|
||||
for (bot_nb, bot) in state.bots.iter() {
|
||||
if bot.current == [Some(61), Some(17)] || bot.current == [Some(17), Some(61)] {
|
||||
return Some(*bot_nb);
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn part_two(input: &str) -> Option<u32> {
|
||||
let mut state = State::init();
|
||||
state.apply(input.lines().flat_map(Instruction::try_from).collect());
|
||||
while let Some(new_state) = state.clone().step() {
|
||||
state = new_state;
|
||||
}
|
||||
|
||||
Some(
|
||||
*state.outputs.entry(0).or_default() as u32
|
||||
* *state.outputs.entry(1).or_default() as u32
|
||||
* *state.outputs.entry(2).or_default() as u32,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part_one() {
|
||||
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
|
||||
assert_eq!(result, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part_two() {
|
||||
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
|
||||
assert_eq!(result, Some(30));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user