84 lines
2.2 KiB
Rust
84 lines
2.2 KiB
Rust
#[derive(Debug, PartialEq)]
|
|
pub struct Packet {
|
|
pub version: usize,
|
|
pub kind: Kind,
|
|
}
|
|
|
|
impl Packet {
|
|
pub fn sum_of_version_numbers(&self) -> usize {
|
|
match &self.kind {
|
|
Kind::Operator(op) => {
|
|
op.sub_packets
|
|
.iter()
|
|
.map(|sub| sub.sum_of_version_numbers())
|
|
.sum::<usize>()
|
|
+ self.version
|
|
}
|
|
Kind::LiteralValue(_) => self.version,
|
|
}
|
|
}
|
|
|
|
pub fn calculate(&self) -> usize {
|
|
match &self.kind {
|
|
Kind::Operator(op) => match op.operation {
|
|
Operation::Sum => op.sub_packets.iter().map(|p| p.calculate()).sum(),
|
|
Operation::Product => op.sub_packets.iter().map(|p| p.calculate()).product(),
|
|
Operation::Minimum => op.sub_packets.iter().map(|p| p.calculate()).min().unwrap(),
|
|
Operation::Maximum => op.sub_packets.iter().map(|p| p.calculate()).max().unwrap(),
|
|
Operation::GreaterThan => {
|
|
if op.sub_packets[0].calculate() > op.sub_packets[1].calculate() {
|
|
1
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
Operation::LessThan => {
|
|
if op.sub_packets[0].calculate() < op.sub_packets[1].calculate() {
|
|
1
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
Operation::EqualTo => {
|
|
if op.sub_packets[0].calculate() == op.sub_packets[1].calculate() {
|
|
1
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
},
|
|
Kind::LiteralValue(val) => *val,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum Kind {
|
|
Operator(Operator),
|
|
LiteralValue(usize),
|
|
}
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub struct Operator {
|
|
pub operation: Operation,
|
|
pub length: Length,
|
|
pub sub_packets: Vec<Packet>,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum Length {
|
|
Count(usize),
|
|
Length(usize),
|
|
}
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum Operation {
|
|
Sum,
|
|
Product,
|
|
Minimum,
|
|
Maximum,
|
|
GreaterThan,
|
|
LessThan,
|
|
EqualTo,
|
|
}
|