Skip to content

Commit

Permalink
all in Rust!
Browse files Browse the repository at this point in the history
  • Loading branch information
rene-d committed Jan 15, 2025
1 parent 58fa2fe commit 7dbb08d
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 38 deletions.
28 changes: 1 addition & 27 deletions 2019/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
# https://adventofcode.com/2019

[workspace]
members = [
"day1",
"day2",
"day3",
"day4",
"day5",
"day6",
"day7",
"day8",
"day9",
"day10",
"day11",
"day12",
"day13",
"day14",
"day15",
"day16",
"day17",
"day18",
"day19",
"day20",
"day21",
"day22",
"day23",
"day24",
"intcode-rs",
]
members = [ "day*", "intcode-rs" ]

resolver = "2"
4 changes: 2 additions & 2 deletions 2019/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

## 2019 ([Calendar](https://adventofcode.com/2019)) ([Solutions](../2019/)) : 50⭐
Expand Down Expand Up @@ -33,4 +33,4 @@ Puzzle
[Day 22: Slam Shuffle](https://adventofcode.com/2019/day/22) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day22/day22.rs)
[Day 23: Category Six](https://adventofcode.com/2019/day/23) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day23/day23.rs) [![Python](../scripts/assets/python.png)](../2019/day23/day23.py)
[Day 24: Planet of Discord](https://adventofcode.com/2019/day/24) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day24/day24.rs) [![Python](../scripts/assets/python.png)](../2019/day24/day24.py)
[Day 25: Cryostasis](https://adventofcode.com/2019/day/25) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day25/day25.py)
[Day 25: Cryostasis](https://adventofcode.com/2019/day/25) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day25/day25.rs) [![Python](../scripts/assets/python.png)](../2019/day25/day25.py)
13 changes: 13 additions & 0 deletions 2019/day25/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "day25"
version = "0.1.0"
edition = "2021"

[dependencies]
aoc = { path = "../../aoc" }
intcode = { path = "../intcode-rs" }
regex = "1.11.1"

[[bin]]
name = "day25"
path = "day25.rs"
6 changes: 3 additions & 3 deletions 2019/day25/day25.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import argparse
import re
import sys
import typing as t
from collections import defaultdict
from pathlib import Path
import typing as t

sys.path.append(Path(__file__).parent.parent.as_posix())
from intcode.Intcode import Computer # noqa
Expand Down Expand Up @@ -155,10 +155,10 @@ def solve(software):
# find path to the detection room
path = find_path(map, start_room, "Pressure-Sensitive Floor")

# the diretion to get to Security Checkpoint from Pressure-Sensitive Floor
# the direction to get to Security Checkpoint from Pressure-Sensitive Floor
checkpoint_dir = [k for k, v in map["Security Checkpoint"].items() if v == "Pressure-Sensitive Floor"][0]

# go to the pre
# go to the Pressure-Sensitive Floor
for step in path:
run(computer, step)

Expand Down
223 changes: 223 additions & 0 deletions 2019/day25/day25.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
//! [Day 25: Cryostasis](https://adventofcode.com/2019/day/25)
use std::collections::{HashMap, HashSet};

use intcode::{Computer, State};

type Room = String;
type Direction = String;
type Map = HashMap<Room, HashMap<Direction, Room>>;

fn run(computer: &mut Computer, command: &str) -> String {
computer.input_flush();

if !command.is_empty() {
command.bytes().for_each(|byte| computer.push_byte(byte));
computer.push_byte(b'\n');
}

let mut output = String::new();
for _ in 1..10000 {
match computer.run() {
State::Output(ch) => {
output.push(char::from_u32(u32::try_from(ch).unwrap()).unwrap());
}
State::Halted | State::Input => return output,
}
}

String::new()
}

fn parse(output: &str) -> (&str, Vec<&str>, Vec<&str>) {
let mut dirs = Vec::new();
let mut items = Vec::new();
let mut room = "";

for line in output.lines() {
if let Some(s) = line.strip_prefix("== ") {
if let Some(s) = s.strip_suffix(" ==") {
if room.is_empty() {
room = s;
}
}
}

if let Some(s) = line.strip_prefix("- ") {
match s {
"north" | "east" | "south" | "west" => dirs.push(s),
_ => items.push(s),
};
}
}

(room, dirs, items)
}

fn reverse(direction: &str) -> &'static str {
match direction {
"north" => "south",
"south" => "north",
"east" => "west",
"west" => "east",
_ => "none",
}
}

fn explore(computer: &mut Computer, map: &mut Map, output: &str) {
//

let (room, dirs, items) = parse(output);

for dir in &dirs {
if map.contains_key(room) && map[room].contains_key(*dir) {
continue;
}

// go next room
let output = run(computer, dir);

let (newroom, _, _) = parse(&output);
let known = map.contains_key(newroom);

map.entry(room.to_string())
.or_default()
.insert((*dir).to_string(), newroom.to_string());
map.entry(newroom.to_string())
.or_default()
.insert(reverse(dir).to_string(), room.to_string());

if output.contains("A loud") {
continue;
}

if !known {
explore(computer, map, &output);
}

run(computer, reverse(dir));
}

for item in items {
let mut temp_computer = computer.clone();

let command = format!("take {item}");

let output = run(&mut temp_computer, &command);
if output.is_empty() {
// stuck
continue;
}

let output = run(&mut temp_computer, "inv");
if output.contains("Items in your inventory") {
run(computer, &command);
}
}
}

fn find_path<'a>(map: &'a Map, start: &str, target: &str) -> Vec<&'a str> {
let mut seen = HashSet::new();

let mut stack = Vec::new();

stack.push((start, Vec::new()));

while let Some((current, path)) = stack.pop() {
if current == target {
return path;
}

for (dir, cell) in &map[current] {
if seen.insert(cell) {
let mut new_path = path.clone();
new_path.push(dir);
stack.push((cell, new_path));
}
}
}

Vec::new()
}

fn find_weight(computer: &mut Computer, inventory: &[&str], checkpoint_dir: &str) -> u64 {
let re = regex::Regex::new(
r"You should be able to get in by typing (\d+) on the keypad at the main airlock.",
)
.unwrap();

let mut prev_code = 0i32;

for code in 0..(1 << inventory.len()) {
let gray_code = code ^ (code >> 1);
let diff = gray_code - prev_code;

if diff != 0 {
let action = if diff > 0 { "drop" } else { "take" };

let mut diff = diff.abs();
let mut item = 0;
while diff & 1 == 0 {
diff >>= 1;
item += 1;
}

let command = format!("{action} {}", inventory[item]);
run(computer, &command);
}

let output = run(computer, checkpoint_dir);

if let Some(caps) = re.captures(&output) {
return caps[1].parse().unwrap();
}

prev_code = gray_code;
}

0
}

fn solve(program: &str) -> u64 {
let mut computer = Computer::load(program);

let mut map = HashMap::new();

let output = run(&mut computer, "");
let (start_room, _, _) = parse(&output);

// visit all rooms and collect items
explore(&mut computer, &mut map, &output);

// find path to the Pressure-Sensitive Floor
let path = find_path(&map, start_room, "Pressure-Sensitive Floor");

// the direction to go to Security Checkpoint from Pressure-Sensitive Floor
let checkpoint_dir = map["Security Checkpoint"]
.iter()
.filter(|(_, room)| room == &"Pressure-Sensitive Floor")
.map(|(dir, _)| dir)
.next()
.unwrap();

// go to the Pressure-Sensitive Floor
for step in path {
run(&mut computer, step);
}

// the inventory
let inventory = run(&mut computer, "inv");
let inventory = inventory
.lines()
.filter_map(|line| line.strip_prefix("- "))
.collect::<Vec<&str>>();

// get the unlock code
find_weight(&mut computer, &inventory, checkpoint_dir)
}

fn main() {
let args = aoc::parse_args();

println!("{}", solve(&args.input));
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# [Advent of Code](https://adventofcode.com) in Rust 🦀

![Stars: 500](https://img.shields.io/badge/Stars-500⭐-blue)
![Rust: 249](https://img.shields.io/badge/Rust-249-cyan?logo=Rust)
![Rust: 250](https://img.shields.io/badge/Rust-250-cyan?logo=Rust)
![Python: 123](https://img.shields.io/badge/Python-123-cyan?logo=Python)

<img src="./scripts/assets/christmas_ferris_2015_2024.png" alt="Christmas Ferris" width="164" />

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 🎄✨.
*Complete* 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 🎄✨.

Made for fun 😎 and to practice Rust. Many thanks to [Eric Wastl](https://twitter.com/ericwastl).

Expand Down Expand Up @@ -49,7 +49,7 @@ Calendar | Solutions | Stars | Rust | Python | 🎁
[Advent of Code 2022](https://adventofcode.com/2022) | [Solutions](2022/README.md) | 50⭐ | 25 | 18 | 1
[Advent of Code 2021](https://adventofcode.com/2021) | [Solutions](2021/README.md) | 50⭐ | 25 | 12 |
[Advent of Code 2020](https://adventofcode.com/2020) | [Solutions](2020/README.md) | 50⭐ | 25 | 23 |
[Advent of Code 2019](https://adventofcode.com/2019) | [Solutions](2019/README.md) | 50⭐ | 24 | 23 | 2
[Advent of Code 2019](https://adventofcode.com/2019) | [Solutions](2019/README.md) | 50⭐ | 25 | 23 | 2
[Advent of Code 2018](https://adventofcode.com/2018) | [Solutions](2018/README.md) | 50⭐ | 25 | 4 | 1
[Advent of Code 2017](https://adventofcode.com/2017) | [Solutions](2017/README.md) | 50⭐ | 25 | 17 |
[Advent of Code 2016](https://adventofcode.com/2016) | [Solutions](2016/README.md) | 50⭐ | 25 | 0 |
Expand Down
6 changes: 3 additions & 3 deletions scripts/Dockerfile-fedora
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ RUN dnf install -y lua
# Ruby
RUN dnf install -y ruby

# Java
RUN dnf install -y java-latest-openjdk-devel

# C#
RUN dnf install -y mono-devel

Expand All @@ -35,6 +32,9 @@ RUN dnf install -y swift-lang
# JavaScript
RUN dnf install -y nodejs

# Java
RUN dnf install -y java-latest-openjdk-devel || true

# User environment
ENV Z3_SYS_Z3_HEADER=/usr/include/z3/z3.h

Expand Down
8 changes: 8 additions & 0 deletions scripts/aoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,16 @@ def aoc_install(ctx: click.Context):

cli = Path("~/.local/bin/aoc").expanduser()
cli.unlink(True)
cli.mkdir(parents=True, exist_ok=True)
cli.symlink_to(f)

if os.getuid() == 0:
# probably into a container
cli = Path("/usr/local/bin/aoc").expanduser()
cli.unlink(True)
cli.mkdir(parents=True, exist_ok=True)
cli.symlink_to(f)

click.echo("Command aoc has been installed in ~/.local/bin .")


Expand Down

0 comments on commit 7dbb08d

Please sign in to comment.