1
0
Fork 0

Added Day 17 Part 1

This commit is contained in:
Ishan Jain 2021-12-17 12:25:46 +05:30
parent 56f8c5bc1f
commit a2cafe726c
3 changed files with 58 additions and 173 deletions

View File

@ -1 +1 @@
820D4A801EE00720190CA005201682A00498014C04BBB01186C040A200EC66006900C44802BA280104021B30070A4016980044C800B84B5F13BFF007081800FE97FDF830401BF4A6E239A009CCE22E53DC9429C170013A8C01E87D102399803F1120B4632004261045183F303E4017DE002F3292CB04DE86E6E7E54100366A5490698023400ABCC59E262CFD31DDD1E8C0228D938872A472E471FC80082950220096E55EF0012882529182D180293139E3AC9A00A080391563B4121007223C4A8B3279B2AA80450DE4B72A9248864EAB1802940095CDE0FA4DAA5E76C4E30EBE18021401B88002170BA0A43000043E27462829318F83B00593225F10267FAEDD2E56B0323005E55EE6830C013B00464592458E52D1DF3F97720110258DAC0161007A084228B0200DC568FB14D40129F33968891005FBC00E7CAEDD25B12E692A7409003B392EA3497716ED2CFF39FC42B8E593CC015B00525754B7DFA67699296DD018802839E35956397449D66997F2013C3803760004262C4288B40008747E8E114672564E5002256F6CC3D7726006125A6593A671A48043DC00A4A6A5B9EAC1F352DCF560A9385BEED29A8311802B37BE635F54F004A5C1A5C1C40279FDD7B7BC4126ED8A4A368994B530833D7A439AA1E9009D4200C4178FF0880010E8431F62C880370F63E44B9D1E200ADAC01091029FC7CB26BD25710052384097004677679159C02D9C9465C7B92CFACD91227F7CD678D12C2A402C24BF37E9DE15A36E8026200F4668AF170401A8BD05A242009692BFC708A4BDCFCC8A4AC3931EAEBB3D314C35900477A0094F36CF354EE0CCC01B985A932D993D87E2017CE5AB6A84C96C265FA750BA4E6A52521C300467033401595D8BCC2818029C00AA4A4FBE6F8CB31CAE7D1CDDAE2E9006FD600AC9ED666A6293FAFF699FC168001FE9DC5BE3B2A6B3EED060
target area: x=124..174, y=-123..-86

View File

@ -1 +1 @@
A0016C880162017C3686B18A3D4780
target area: x=20..30, y=-10..-5

View File

@ -1,200 +1,84 @@
#![feature(test)]
use std::ops::RangeInclusive;
extern crate test;
use bitvec::{order::Msb0, view::BitView};
type BitSlice<'a> = &'a bitvec::slice::BitSlice<Msb0, u8>;
const INPUTS: [&'static str; 2] = [
include_str!("../inputs/sample.txt"),
include_str!("../inputs/input.txt"),
];
#[derive(Debug)]
struct PacketHeader {
version: u8,
type_id: u8,
fn parse(input: &'static str) -> (RangeInclusive<i32>, RangeInclusive<i32>) {
let input = input.trim();
let input = input.trim_start_matches("target area: ");
let (x, y) = input.split_once(", ").unwrap();
let x = x.trim_start_matches("x=");
let y = y.trim_start_matches("y=");
let (sx, ex) = x
.split_once("..")
.map(|(a, b)| (a.parse::<i32>().unwrap(), b.parse::<i32>().unwrap()))
.unwrap();
let (sy, ey) = y
.split_once("..")
.map(|(a, b)| (a.parse::<i32>().unwrap(), b.parse::<i32>().unwrap()))
.unwrap();
(sx..=ex, sy..=ey)
}
#[derive(Debug)]
struct Packet {
header: PacketHeader,
size: u64,
literal: Option<u64>,
sub_packets: Vec<Packet>,
}
impl Packet {
fn new(input: &'static str) -> Self {
let out = hex::decode(input).unwrap();
let mut bvec: BitSlice = BitView::view_bits(out.as_slice());
Self::parse(&mut bvec)
}
fn read_literal(ip: &mut BitSlice) -> (u64, u64) {
let mut out = 0;
let mut read = 0;
fn check(
mut vx: i32,
mut vy: i32,
(tx, ty): (RangeInclusive<i32>, RangeInclusive<i32>),
) -> Option<i32> {
let mut sx = 0;
let mut sy = 0;
let mut y_max = 0;
loop {
let (word, remaining) = ip.split_at(5);
*ip = remaining;
read += 5;
out = out << 4 | read_as_u8(&word[1..]) as u64;
if !*word.first().unwrap() {
break;
}
if vx == 0 && sy < *ty.start() {
return None;
}
(out, read)
if tx.contains(&sx) && ty.contains(&sy) {
return Some(y_max);
}
fn read_header(ip: &mut BitSlice) -> (u8, u8) {
(take_u8(ip, 3), take_u8(ip, 3))
}
sx += vx;
sy += vy;
fn parse(input: &mut BitSlice) -> Packet {
let (version, type_id) = Self::read_header(input);
y_max = y_max.max(sy);
let mut out = Packet {
size: 6,
literal: None,
header: PacketHeader { version, type_id },
sub_packets: vec![],
vy -= 1;
vx -= if vx > 0 {
1
} else if vx < 0 {
-1
} else {
0
};
match type_id {
// Literal
4 => {
let (literal, read) = Self::read_literal(input);
out.size += read;
out.literal = Some(literal);
}
// Operation
_ => {
let length_type_id = take_u8(input, 1);
out.size += 1;
match length_type_id {
0 => {
let mut trailing_packet_size = take_u64(input, 15);
out.size += 15;
while trailing_packet_size > 0 {
let packet = Self::parse(input);
trailing_packet_size -= packet.size;
out.size += packet.size;
out.sub_packets.push(packet);
}
}
1 => {
let trailing_packet_count = take_u64(input, 11);
out.size += 11;
for _ in 0..trailing_packet_count {
let packet = Self::parse(input);
out.size += packet.size;
out.sub_packets.push(packet);
}
}
_ => unreachable!(),
}
}
};
out
}
fn value(&self) -> u64 {
match self.header.type_id {
0 => self.sub_packets.iter().fold(0, |a, x| a + x.value()),
1 => self.sub_packets.iter().fold(1, |a, x| a * x.value()),
2 => self.sub_packets.iter().map(|x| x.value()).min().unwrap(),
3 => self.sub_packets.iter().map(|x| x.value()).max().unwrap(),
4 => self.literal.unwrap(),
5 => {
let value1 = self.sub_packets[0].value();
let value2 = self.sub_packets[1].value();
if value1 > value2 {
1
} else {
0
}
}
6 => {
let value1 = self.sub_packets[0].value();
let value2 = self.sub_packets[1].value();
if value1 < value2 {
1
} else {
0
}
}
7 => {
let value1 = self.sub_packets[0].value();
let value2 = self.sub_packets[1].value();
if value1 == value2 {
1
} else {
0
}
}
_ => unreachable!(),
fn solution((xr, yr): (RangeInclusive<i32>, RangeInclusive<i32>)) -> i32 {
let mut y_max = 0;
for x in 0..250 {
for y in -250..=250 {
if let Some(lymax) = check(x, y, (xr.clone(), yr.clone())) {
y_max = y_max.max(lymax);
}
}
}
fn take_u8(ip: &mut BitSlice, offset: usize) -> u8 {
let (num, left) = ip.split_at(offset);
*ip = left;
read_as_u8(num)
}
fn take_u64(ip: &mut BitSlice, offset: usize) -> u64 {
let (num, left) = ip.split_at(offset);
*ip = left;
read_as_u64(num)
}
fn read_as_u64(ip: BitSlice) -> u64 {
let mut out = 0;
for bit in ip {
out = out << 1 | if *bit { 1 } else { 0 };
}
out
}
fn read_as_u8(ip: BitSlice) -> u8 {
let mut out = 0;
for bit in ip {
out = out << 1 | if *bit { 1 } else { 0 };
}
out
}
fn solution(input: &'static str) -> u64 {
let packet = Packet::new(input.trim());
packet.value()
y_max
}
fn main() {
for input in INPUTS {
let input = parse(input);
let result = solution(input);
println!("Result = {}", result);
}
@ -202,8 +86,9 @@ fn main() {
#[bench]
fn solution_bench(b: &mut test::Bencher) {
let input = parse(INPUTS[1]);
b.iter(|| {
let result = solution(INPUTS[1]);
let result = solution(input.clone());
test::black_box(result);
})
}