2021: day16: part 1: parse litterals
This commit is contained in:
parent
95d955f506
commit
025374e685
47
Cargo.lock
generated
47
Cargo.lock
generated
|
@ -88,6 +88,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"aoc",
|
||||
"bitvec 0.22.3",
|
||||
"rand",
|
||||
]
|
||||
|
||||
|
@ -130,14 +131,26 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "0.19.6"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33"
|
||||
checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"radium 0.5.3",
|
||||
"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]]
|
||||
|
@ -336,9 +349,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
|||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
|
@ -470,12 +483,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.2.1"
|
||||
version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6"
|
||||
checksum = "3d521ee2250f619dd5e06515ba405858d249edc8fae9ddee2dba0695e57db01b"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"funty",
|
||||
"bitvec 0.19.4",
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
|
@ -570,6 +582,12 @@ version = "0.5.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
|
@ -913,3 +931,12 @@ name = "wyz"
|
|||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
|
|
|
@ -10,6 +10,7 @@ edition = "2021"
|
|||
aoc = { path = "../aoc" }
|
||||
anyhow = "1.0"
|
||||
rand = "0.8"
|
||||
bitvec = "0.22"
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
|
|
1
aoc2021/input/day16.txt
Normal file
1
aoc2021/input/day16.txt
Normal file
|
@ -0,0 +1 @@
|
|||
E20D4100AA9C0199CA6A3D9D6352294D47B3AC6A4335FBE3FDD251003873657600B46F8DC600AE80273CCD2D5028B6600AF802B2959524B727D8A8CC3CCEEF3497188C017A005466DAA6FDB3A96D5944C014C006865D5A7255D79926F5E69200A164C1A65E26C867DDE7D7E4794FE72F3100C0159A42952A7008A6A5C189BCD456442E4A0A46008580273ADB3AD1224E600ACD37E802200084C1083F1540010E8D105A371802D3B845A0090E4BD59DE0E52FFC659A5EBE99AC2B7004A3ECC7E58814492C4E2918023379DA96006EC0008545B84B1B00010F8E915E1E20087D3D0E577B1C9A4C93DD233E2ECF65265D800031D97C8ACCCDDE74A64BD4CC284E401444B05F802B3711695C65BCC010A004067D2E7C4208A803F23B139B9470D7333B71240050A20042236C6A834600C4568F5048801098B90B626B00155271573008A4C7A71662848821001093CB4A009C77874200FCE6E7391049EB509FE3E910421924D3006C40198BB11E2A8803B1AE2A4431007A15C6E8F26009E002A725A5292D294FED5500C7170038C00E602A8CC00D60259D008B140201DC00C401B05400E201608804D45003C00393600B94400970020C00F6002127128C0129CDC7B4F46C91A0084E7C6648DC000DC89D341B23B8D95C802D09453A0069263D8219DF680E339003032A6F30F126780002CC333005E8035400042635C578A8200DC198890AA46F394B29C4016A4960C70017D99D7E8AF309CC014FCFDFB0FE0DA490A6F9D490010567A3780549539ED49167BA47338FAAC1F3005255AEC01200043A3E46C84E200CC4E895114C011C0054A522592912C9C8FDE10005D8164026C70066C200C4618BD074401E8C90E23ACDFE5642700A6672D73F285644B237E8CCCCB77738A0801A3CFED364B823334C46303496C940
|
129
aoc2021/src/day16.rs
Normal file
129
aoc2021/src/day16.rs
Normal 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 }),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -15,3 +15,4 @@ pub mod day12;
|
|||
pub mod day13;
|
||||
pub mod day14;
|
||||
pub mod day15;
|
||||
pub mod day16;
|
||||
|
|
|
@ -17,6 +17,7 @@ use aoc2021::day12;
|
|||
use aoc2021::day13;
|
||||
use aoc2021::day14;
|
||||
use aoc2021::day15;
|
||||
use aoc2021::day16;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let days: &[DayFunc] = &[
|
||||
|
@ -35,6 +36,7 @@ fn main() -> Result<()> {
|
|||
day13::run,
|
||||
day14::run,
|
||||
day15::run,
|
||||
day16::run,
|
||||
];
|
||||
|
||||
aoc::run(days)
|
||||
|
|
Loading…
Reference in a new issue