Added day 16
This commit is contained in:
parent
dceca0e77f
commit
837ee1b9a3
|
@ -0,0 +1 @@
|
|||
220D6448300428021F9EFE668D3F5FD6025165C00C602FC980B45002A40400B402548808A310028400C001B5CC00B10029C0096011C0003C55003C0028270025400C1002E4F19099F7600142C801098CD0761290021B19627C1D3007E33C4A8A640143CE85CB9D49144C134927100823275CC28D9C01234BD21F8144A6F90D1B2804F39B972B13D9D60939384FE29BA3B8803535E8DF04F33BC4AFCAFC9E4EE32600C4E2F4896CE079802D4012148DF5ACB9C8DF5ACB9CD821007874014B4ECE1A8FEF9D1BCC72A293A0E801C7C9CA36A5A9D6396F8FCC52D18E91E77DD9EB16649AA9EC9DA4F4600ACE7F90DFA30BA160066A200FC448EB05C401B8291F22A2002051D247856600949C3C73A009C8F0CA7FBCCF77F88B0000B905A3C1802B3F7990E8029375AC7DDE2DCA20C2C1004E4BE9F392D0E90073D31634C0090667FF8D9E667FF8D9F0C01693F8FE8024000844688FF0900010D8EB0923A9802903F80357100663DC2987C0008744F8B5138803739EB67223C00E4CC74BA46B0AD42C001DE8392C0B0DE4E8F660095006AA200EC198671A00010E87F08E184FCD7840289C1995749197295AC265B2BFC76811381880193C8EE36C324F95CA69C26D92364B66779D63EA071008C360098002191A637C7310062224108C3263A600A49334C19100A1A000864728BF0980010E8571EE188803D19A294477008A595A53BC841526BE313D6F88CE7E16A7AC60401A9E80273728D2CC53728D2CCD2AA2600A466A007CE680E5E79EFEB07360041A6B20D0F4C021982C966D9810993B9E9F3B1C7970C00B9577300526F52FCAB3DF87EC01296AFBC1F3BC9A6200109309240156CC41B38015796EABCB7540804B7C00B926BD6AC36B1338C4717E7D7A76378C85D8043F947C966593FD2BBBCB27710E57FDF6A686E00EC229B4C9247300528029393EC3BAA32C9F61DD51925AD9AB2B001F72B2EE464C0139580D680232FA129668
|
|
@ -1,10 +1 @@
|
|||
1163751742
|
||||
1381373672
|
||||
2136511328
|
||||
3694931569
|
||||
7463417111
|
||||
1319128137
|
||||
1359912421
|
||||
3125421639
|
||||
1293138521
|
||||
2311944581
|
||||
8A004A801A8002F478
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::collections::BinaryHeap;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead};
|
||||
use std::vec::Vec;
|
||||
|
||||
fn expand_digits(line: &str) -> Vec<bool> {
|
||||
let mut bin = Vec::new();
|
||||
|
||||
for c in line.chars() {
|
||||
let bits = match c {
|
||||
'0' => [false, false, false, false],
|
||||
'1' => [false, false, false, true],
|
||||
'2' => [false, false, true, false],
|
||||
'3' => [false, false, true, true],
|
||||
'4' => [false, true, false, false],
|
||||
'5' => [false, true, false, true],
|
||||
'6' => [false, true, true, false],
|
||||
'7' => [false, true, true, true],
|
||||
'8' => [true, false, false, false],
|
||||
'9' => [true, false, false, true],
|
||||
'A' => [true, false, true, false],
|
||||
'B' => [true, false, true, true],
|
||||
'C' => [true, true, false, false],
|
||||
'D' => [true, true, false, true],
|
||||
'E' => [true, true, true, false],
|
||||
'F' => [true, true, true, true],
|
||||
_ => panic!("Unsupported char {}", c),
|
||||
};
|
||||
|
||||
bin.extend_from_slice(&bits);
|
||||
}
|
||||
|
||||
bin
|
||||
}
|
||||
|
||||
fn print_binary(bin: &[bool]) {
|
||||
for bit in bin.iter() {
|
||||
if *bit {
|
||||
print!("1");
|
||||
} else {
|
||||
print!("0");
|
||||
}
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
|
||||
fn bits_to_uint(bits: &[bool]) -> u64 {
|
||||
let mut base = 1;
|
||||
let mut res = 0;
|
||||
for bit in bits.iter().rev() {
|
||||
if *bit {
|
||||
res += base;
|
||||
}
|
||||
base *= 2;
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
enum Packet {
|
||||
Literal(u64, u64, u64),
|
||||
Operator(u64, u64, Vec<Packet>),
|
||||
}
|
||||
|
||||
fn parse_packet(bits: &[bool]) -> (Packet, &[bool]) {
|
||||
let version = bits_to_uint(&bits[0..3]);
|
||||
let type_id = bits_to_uint(&bits[3..6]);
|
||||
println!("Version: {}", version);
|
||||
println!("Type: {}", type_id);
|
||||
|
||||
//Literal value
|
||||
if type_id == 4 {
|
||||
let mut tail = &bits[6..];
|
||||
let mut res: Vec<bool> = Vec::new();
|
||||
loop {
|
||||
let chunk = &tail[0..5];
|
||||
tail = &tail[5..];
|
||||
res.extend_from_slice(&chunk[1..5]);
|
||||
if !chunk[0] {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let literal = bits_to_uint(&res);
|
||||
println!("Literal {}", literal);
|
||||
return (Packet::Literal(version, type_id, literal), tail);
|
||||
} else {
|
||||
if !bits[6] {
|
||||
let bit_lenght = bits_to_uint(&bits[7..22]) as usize;
|
||||
println!("15 bits, bit lenght {}", bit_lenght);
|
||||
|
||||
let mut sub_packets = &bits[22..22 + bit_lenght];
|
||||
let tail = &bits[22 + bit_lenght..];
|
||||
|
||||
let mut packets: Vec<Packet> = Vec::new();
|
||||
while sub_packets.len() >= 11 {
|
||||
let (packet, rest) = parse_packet(sub_packets);
|
||||
packets.push(packet);
|
||||
sub_packets = rest;
|
||||
}
|
||||
|
||||
return (Packet::Operator(version, type_id, packets), tail);
|
||||
} else {
|
||||
let packet_lenght = bits_to_uint(&bits[7..18]) as usize;
|
||||
println!("11 bits, number of packets {}", packet_lenght);
|
||||
|
||||
let mut tail = &bits[18..];
|
||||
|
||||
let mut packets: Vec<Packet> = Vec::new();
|
||||
for _ in 0..packet_lenght {
|
||||
let (packet, rest) = parse_packet(tail);
|
||||
packets.push(packet);
|
||||
tail = rest;
|
||||
}
|
||||
|
||||
return (Packet::Operator(version, type_id, packets), tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn add_versions(packet: &Packet) -> u64 {
|
||||
match packet {
|
||||
Packet::Literal(version, _, _) => *version,
|
||||
Packet::Operator(version, _, sub_packets) => {
|
||||
version
|
||||
+ sub_packets
|
||||
.iter()
|
||||
.map(|p| add_versions(p))
|
||||
.fold(0, |a, b| a + b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn execute_packet(packet: &Packet) -> u64 {
|
||||
match packet {
|
||||
Packet::Literal(_, _, value) => *value,
|
||||
Packet::Operator(_, type_id, sub_packets) => match type_id {
|
||||
0 => sub_packets
|
||||
.iter()
|
||||
.map(|p| execute_packet(p))
|
||||
.fold(0, |a, b| a + b), // sum
|
||||
1 => sub_packets
|
||||
.iter()
|
||||
.map(|p| execute_packet(p))
|
||||
.fold(1, |a, b| a * b), // product
|
||||
2 => sub_packets.iter().map(|p| execute_packet(p)).min().unwrap(), // min
|
||||
3 => sub_packets.iter().map(|p| execute_packet(p)).max().unwrap(), // max
|
||||
5 => {
|
||||
if execute_packet(&sub_packets[0]) > execute_packet(&sub_packets[1]) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
6 => {
|
||||
if execute_packet(&sub_packets[0]) < execute_packet(&sub_packets[1]) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
7 => {
|
||||
if execute_packet(&sub_packets[0]) == execute_packet(&sub_packets[1]) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => panic!("Unsupported packet type {}", type_id),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let file = File::open("inputs/day16.txt")?;
|
||||
let line: String = io::BufReader::new(file).lines().next().unwrap()?;
|
||||
|
||||
let data = expand_digits(&line);
|
||||
print_binary(&data);
|
||||
|
||||
let (packet, _) = parse_packet(&data);
|
||||
|
||||
let answer1 = add_versions(&packet);
|
||||
|
||||
println!("Answer1: {}", answer1);
|
||||
|
||||
let answer2 = execute_packet(&packet);
|
||||
|
||||
println!("Answer2: {}", answer2);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue