Skip to content

Commit

Permalink
②⓪⓪ Rust puzzles 🍾
Browse files Browse the repository at this point in the history
  • Loading branch information
rene-d committed Dec 22, 2024
1 parent e99597a commit 65aecaa
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 5 deletions.
2 changes: 1 addition & 1 deletion 2021/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# http://adventofcode.com/2021
[workspace]
members = ["day*"]
exclude = ["day16", "day18"]
exclude = ["day18"]
resolver = "2"
4 changes: 2 additions & 2 deletions 2021/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![AoC2021](https://img.shields.io/badge/Advent_of_Code-2021-8A2BE2)
![Stars: 50](https://img.shields.io/badge/Stars-50⭐-blue)
![Rust: 23](https://img.shields.io/badge/Rust-23-cyan?logo=Rust)
![Rust: 24](https://img.shields.io/badge/Rust-24-cyan?logo=Rust)
![Python: 12](https://img.shields.io/badge/Python-12-cyan?logo=Python)

## 2021 ([Calendar](https://adventofcode.com/2021)) ([Solutions](../2021/)) : 50⭐
Expand All @@ -24,7 +24,7 @@ Puzzle | Stars
[Day 13: Transparent Origami](https://adventofcode.com/2021/day/13) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2021/day13/day13.rs) [![Python](../scripts/assets/python.png)](../2021/day13/day13.py)
[Day 14: Extended Polymerization](https://adventofcode.com/2021/day/14) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2021/day14/day14.rs)
[Day 15: Chiton](https://adventofcode.com/2021/day/15) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2021/day15/day15.rs)
[Day 16: Packet Decoder](https://adventofcode.com/2021/day/16) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2021/day16/day16.py)
[Day 16: Packet Decoder](https://adventofcode.com/2021/day/16) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2021/day16/day16.rs) [![Python](../scripts/assets/python.png)](../2021/day16/day16.py)
[Day 17: Trick Shot](https://adventofcode.com/2021/day/17) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2021/day17/day17.rs)
[Day 18: Snailfish](https://adventofcode.com/2021/day/18) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2021/day18/day18.py)
[Day 19: Beacon Scanner](https://adventofcode.com/2021/day/19) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2021/day19/day19.rs)
Expand Down
11 changes: 11 additions & 0 deletions 2021/day16/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "day16"
version = "0.1.0"
edition = "2021"

[dependencies]
aoc = { path = "../../aoc" }

[[bin]]
name = "day16"
path = "day16.rs"
190 changes: 190 additions & 0 deletions 2021/day16/day16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
//! [Day 16: Packet Decoder](https://adventofcode.com/2021/day/16)
fn int_value(bits: &str) -> u32 {
bits.chars()
.map_while(|c| c.to_digit(2))
.fold(0, |acc, d| (acc << 1) + d)
}

fn read_packet(packet: &str, mut offset: usize, sum_of_versions: &mut u32) -> (usize, u64) {
assert!(offset < packet.len());

let version = int_value(&packet[offset..offset + 3]);
let type_id = int_value(&packet[offset + 3..offset + 6]);
offset += 6;

// compute part 1 answer
*sum_of_versions += version;

//
if type_id == 4 {
let mut literal_value = 0;
loop {
let last = &packet[offset..=offset];
let nibble = int_value(&packet[offset + 1..offset + 5]);
literal_value = (literal_value * 16) + u64::from(nibble);
offset += 5;
if offset > packet.len() || last == "0" {
return (offset, literal_value);
}
}
}

// subpackets
let mut values = Vec::new();

// length of subpackets
let length_id = int_value(&packet[offset..=offset]);
offset += 1;

if length_id == 0 {
//
let length = int_value(&packet[offset..offset + 15]);
offset += 15;

let end_offset: usize = offset + usize::try_from(length).unwrap();

while length != 0 && offset < end_offset {
let (new_offset, value) = read_packet(packet, offset, sum_of_versions);
values.push(value);
offset = new_offset;
}
} else {
let mut count = int_value(&packet[offset..offset + 11]);
offset += 11;

while count > 0 && offset < packet.len() {
let (new_offset, value) = read_packet(packet, offset, sum_of_versions);
values.push(value);
count -= 1;
offset = new_offset;
}
};

let computed = match type_id {
0 => values.iter().sum(),
1 => values.iter().product(),
2 => *values.iter().min().unwrap(),
3 => *values.iter().max().unwrap(),
5 => u64::from(values[0] > values[1]),
6 => u64::from(values[0] < values[1]),
7 => u64::from(values[0] == values[1]),
_ => panic!(),
};

(offset, computed)
}

struct Puzzle {
part1: u32,
part2: u64,
}

impl Puzzle {
/// Get the puzzle input.
fn solve_from_file(path: &str) -> Self {
let data = std::fs::read_to_string(path).unwrap_or_else(|_| {
eprintln!("cannot read input file {path}");
std::process::exit(1);
});

Self::solve(&data)
}

fn solve(data: &str) -> Self {
let bin_data = data
.chars()
.map_while(|c| c.to_digit(16))
.map(|d| match d {
0 => "0000",
1 => "0001",
2 => "0010",
3 => "0011",
4 => "0100",
5 => "0101",
6 => "0110",
7 => "0111",
8 => "1000",
9 => "1001",
10 => "1010",
11 => "1011",
12 => "1100",
13 => "1101",
14 => "1110",
15 => "1111",
_ => panic!(),
})
.collect::<Vec<_>>()
.join("");

let mut part1 = 0;
let (_, part2) = read_packet(&bin_data, 0, &mut part1);

Self { part1, part2 }
}
}

fn main() {
let args = aoc::parse_args();
let puzzle = Puzzle::solve_from_file(args.path.as_str());
println!("{}", puzzle.part1);
println!("{}", puzzle.part2);
}

/// Test from puzzle input
#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_bin() {
assert_eq!(int_value("a"), 0);
assert_eq!(int_value("0"), 0);
assert_eq!(int_value("01"), 1);
assert_eq!(int_value("11"), 3);
assert_eq!(int_value("10000"), 16);
assert_eq!(int_value("10101010101010101010101010101010"), 0xAAAAAAAA);
}

#[test]
fn test_part1() {
let puzzle = Puzzle::solve("8A004A801A8002F478");
assert_eq!(puzzle.part1, 16);

let puzzle = Puzzle::solve("620080001611562C8802118E34");
assert_eq!(puzzle.part1, 12);

let puzzle = Puzzle::solve("C0015000016115A2E0802F182340");
assert_eq!(puzzle.part1, 23);

let puzzle = Puzzle::solve("A0016C880162017C3686B18A3D4780");
assert_eq!(puzzle.part1, 31);
}

#[test]
fn test_part2() {
let puzzle = Puzzle::solve("C200B40A82");
assert_eq!(puzzle.part2, 3);

let puzzle = Puzzle::solve("04005AC33890");
assert_eq!(puzzle.part2, 54);

let puzzle = Puzzle::solve("880086C3E88112");
assert_eq!(puzzle.part2, 7);

let puzzle = Puzzle::solve("CE00C43D881120");
assert_eq!(puzzle.part2, 9);

let puzzle = Puzzle::solve("D8005AC2A8F0");
assert_eq!(puzzle.part2, 1);

let puzzle = Puzzle::solve("F600BC2D8F");
assert_eq!(puzzle.part2, 0);

let puzzle = Puzzle::solve("9C005AC2F8F0");
assert_eq!(puzzle.part2, 0);

let puzzle = Puzzle::solve("9C0141080250320F1802104A08");
assert_eq!(puzzle.part2, 1);
}
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# [Advent of Code](https://adventofcode.com) in Rust 🦀

![Stars: 494](https://img.shields.io/badge/Stars-494⭐-blue)
![Rust: 199](https://img.shields.io/badge/Rust-199-cyan?logo=Rust)
![Rust: 200](https://img.shields.io/badge/Rust-200-cyan?logo=Rust)
![Python: 121](https://img.shields.io/badge/Python-121-cyan?logo=Python)

Solutions of [Advent of Code](https://adventofcode.com/) in [Rust](https://www.rust-lang.org), and sometimes in [Python](https://www.python.org/) and other languages.
Expand Down Expand Up @@ -42,7 +42,7 @@ Calendar | Solutions | Stars | Rust | Python | 🎄
[Advent of Code 2024](https://adventofcode.com/2024) | [Solutions](2024/README.md) | 44⭐ | 22 | 8 | 3
[Advent of Code 2023](https://adventofcode.com/2023) | [Solutions](2023/README.md) | 50⭐ | 25 | 11 | 1
[Advent of Code 2022](https://adventofcode.com/2022) | [Solutions](2022/README.md) | 50⭐ | 24 | 18 |
[Advent of Code 2021](https://adventofcode.com/2021) | [Solutions](2021/README.md) | 50⭐ | 23 | 12 |
[Advent of Code 2021](https://adventofcode.com/2021) | [Solutions](2021/README.md) | 50⭐ | 24 | 12 |
[Advent of Code 2020](https://adventofcode.com/2020) | [Solutions](2020/README.md) | 50⭐ | 7 | 23 |
[Advent of Code 2019](https://adventofcode.com/2019) | [Solutions](2019/README.md) | 50⭐ | 8 | 23 | 2
[Advent of Code 2018](https://adventofcode.com/2018) | [Solutions](2018/README.md) | 50⭐ | 25 | 4 | 1
Expand Down

0 comments on commit 65aecaa

Please sign in to comment.