2021: day16: part 1: parse litterals

This commit is contained in:
Antoine Martin 2021-12-16 15:50:19 +01:00
parent 95d955f506
commit 025374e685
6 changed files with 171 additions and 10 deletions

47
Cargo.lock generated
View file

@ -88,6 +88,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"aoc", "aoc",
"bitvec 0.22.3",
"rand", "rand",
] ]
@ -130,14 +131,26 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
version = "0.19.6" version = "0.19.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
dependencies = [ dependencies = [
"funty", "funty",
"radium", "radium 0.5.3",
"tap", "tap",
"wyz", "wyz 0.2.0",
]
[[package]]
name = "bitvec"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
dependencies = [
"funty",
"radium 0.6.2",
"tap",
"wyz 0.4.0",
] ]
[[package]] [[package]]
@ -336,9 +349,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]] [[package]]
name = "funty" name = "funty"
version = "1.1.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
[[package]] [[package]]
name = "generic-array" name = "generic-array"
@ -470,12 +483,11 @@ dependencies = [
[[package]] [[package]]
name = "nom" name = "nom"
version = "6.2.1" version = "6.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6" checksum = "3d521ee2250f619dd5e06515ba405858d249edc8fae9ddee2dba0695e57db01b"
dependencies = [ dependencies = [
"bitvec", "bitvec 0.19.4",
"funty",
"lexical-core", "lexical-core",
"memchr", "memchr",
"version_check", "version_check",
@ -570,6 +582,12 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
[[package]]
name = "radium"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.4" version = "0.8.4"
@ -913,3 +931,12 @@ name = "wyz"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
[[package]]
name = "wyz"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
dependencies = [
"tap",
]

View file

@ -10,6 +10,7 @@ edition = "2021"
aoc = { path = "../aoc" } aoc = { path = "../aoc" }
anyhow = "1.0" anyhow = "1.0"
rand = "0.8" rand = "0.8"
bitvec = "0.22"
[lib] [lib]
path = "src/lib.rs" path = "src/lib.rs"

1
aoc2021/input/day16.txt Normal file
View file

@ -0,0 +1 @@
E20D4100AA9C0199CA6A3D9D6352294D47B3AC6A4335FBE3FDD251003873657600B46F8DC600AE80273CCD2D5028B6600AF802B2959524B727D8A8CC3CCEEF3497188C017A005466DAA6FDB3A96D5944C014C006865D5A7255D79926F5E69200A164C1A65E26C867DDE7D7E4794FE72F3100C0159A42952A7008A6A5C189BCD456442E4A0A46008580273ADB3AD1224E600ACD37E802200084C1083F1540010E8D105A371802D3B845A0090E4BD59DE0E52FFC659A5EBE99AC2B7004A3ECC7E58814492C4E2918023379DA96006EC0008545B84B1B00010F8E915E1E20087D3D0E577B1C9A4C93DD233E2ECF65265D800031D97C8ACCCDDE74A64BD4CC284E401444B05F802B3711695C65BCC010A004067D2E7C4208A803F23B139B9470D7333B71240050A20042236C6A834600C4568F5048801098B90B626B00155271573008A4C7A71662848821001093CB4A009C77874200FCE6E7391049EB509FE3E910421924D3006C40198BB11E2A8803B1AE2A4431007A15C6E8F26009E002A725A5292D294FED5500C7170038C00E602A8CC00D60259D008B140201DC00C401B05400E201608804D45003C00393600B94400970020C00F6002127128C0129CDC7B4F46C91A0084E7C6648DC000DC89D341B23B8D95C802D09453A0069263D8219DF680E339003032A6F30F126780002CC333005E8035400042635C578A8200DC198890AA46F394B29C4016A4960C70017D99D7E8AF309CC014FCFDFB0FE0DA490A6F9D490010567A3780549539ED49167BA47338FAAC1F3005255AEC01200043A3E46C84E200CC4E895114C011C0054A522592912C9C8FDE10005D8164026C70066C200C4618BD074401E8C90E23ACDFE5642700A6672D73F285644B237E8CCCCB77738A0801A3CFED364B823334C46303496C940

129
aoc2021/src/day16.rs Normal file
View file

@ -0,0 +1,129 @@
use std::fmt::Write;
use anyhow::{Context, Result};
use bitvec::prelude::*;
const INPUT: &str = include_str!("../input/day16.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let packet: Packet = input.parse()?;
Ok(packet.version_sum())
}
#[derive(PartialEq, Eq, Debug)]
enum PacketType {
Litteral(LitteralPacket),
Operator(OperatorPacket),
}
#[derive(PartialEq, Eq, Debug)]
struct Packet {
version: u8,
type_id: u8,
packet: PacketType,
}
impl Packet {
fn version_sum(&self) -> u64 {
match &self.packet {
PacketType::Litteral(_) => self.version as u64,
PacketType::Operator(op) => op.sub_packets.iter().map(Packet::version_sum).sum(),
}
}
}
#[derive(PartialEq, Eq, Debug)]
struct LitteralPacket {
value: u64,
}
#[derive(PartialEq, Eq, Debug)]
struct OperatorPacket {
sub_packets: Vec<Packet>,
}
impl std::str::FromStr for Packet {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let s = s.trim();
let mut bits = BitVec::<Msb0, usize>::new();
bits.resize(4 * s.len(), false);
for (i, c) in s.chars().enumerate() {
let bit_index = i * 4;
let digit = c.to_digit(16).context("character wasn't hex digit")?;
bits[bit_index..(bit_index + 4)].store(digit);
}
bits.as_bitslice().try_into()
}
}
impl<'bits, Store> TryFrom<&'bits BitSlice<Msb0, Store>> for Packet
where
Store: BitStore,
{
type Error = anyhow::Error;
fn try_from(bits: &'bits BitSlice<Msb0, Store>) -> Result<Self> {
let version: u8 = bits[0..3].load();
let type_id: u8 = bits[3..6].load();
match type_id {
4 => {
let mut value = 0;
for i in (6..).step_by(5) {
let val = bits[(i + 1)..(i + 5)].load::<u64>();
value = (value << 4) + val;
if !bits[i] {
break;
}
}
Ok(Packet {
version,
type_id,
packet: PacketType::Litteral(LitteralPacket { value }),
})
}
_ => unimplemented!("Operator packets aren't implemented yet"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED1: &str = "D2FE28";
const PROVIDED2: &str = "38006F45291200";
const PROVIDED3: &str = "EE00D40C823060";
const PROVIDED4: &str = "8A004A801A8002F478";
const PROVIDED5: &str = "620080001611562C8802118E34";
const PROVIDED6: &str = "C0015000016115A2E0802F182340";
const PROVIDED7: &str = "A0016C880162017C3686B18A3D4780";
#[test]
fn part1_provided() {
assert_eq!(
PROVIDED1.parse::<Packet>().unwrap(),
Packet {
version: 6,
type_id: 4,
packet: PacketType::Litteral(LitteralPacket { value: 2021 }),
}
);
}
}

View file

@ -15,3 +15,4 @@ pub mod day12;
pub mod day13; pub mod day13;
pub mod day14; pub mod day14;
pub mod day15; pub mod day15;
pub mod day16;

View file

@ -17,6 +17,7 @@ use aoc2021::day12;
use aoc2021::day13; use aoc2021::day13;
use aoc2021::day14; use aoc2021::day14;
use aoc2021::day15; use aoc2021::day15;
use aoc2021::day16;
fn main() -> Result<()> { fn main() -> Result<()> {
let days: &[DayFunc] = &[ let days: &[DayFunc] = &[
@ -35,6 +36,7 @@ fn main() -> Result<()> {
day13::run, day13::run,
day14::run, day14::run,
day15::run, day15::run,
day16::run,
]; ];
aoc::run(days) aoc::run(days)