Skip to content

Commit 019d229

Browse files
committed
[2025] Solution for Day 1
1 parent 21e700c commit 019d229

File tree

9 files changed

+148
-1
lines changed

9 files changed

+148
-1
lines changed

2025/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
/target/
4+
5+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
7+
Cargo.lock
8+
9+
# These are backup files generated by rustfmt
10+
**/*.rs.bk

2025/Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "aoc2025"
3+
version = "0.1.0"
4+
authors = ["Kyle Farnung <[email protected]>"]
5+
edition = "2021"
6+
7+
[dependencies]
8+
regex = "1"

2025/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Advent of Code 2025
2+
3+
https://adventofcode.com/2025
4+
5+
## Language
6+
7+
Implemented in [Rust](https://www.rust-lang.org/).
8+
9+
## Preparation
10+
11+
Install
12+
[Rust](https://doc.rust-lang.org/cargo/getting-started/installation.html).
13+
14+
## Running tests
15+
16+
Run tests using `cargo`:
17+
18+
```console
19+
cargo test
20+
```

2025/src/bin/day01.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use aoc2025::days::day01::{part1, part2};
2+
use std::env;
3+
use std::fs;
4+
use std::process;
5+
6+
fn main() {
7+
let args: Vec<String> = env::args().collect();
8+
if args.len() < 2 {
9+
println!("Missing required arguments");
10+
process::exit(1);
11+
}
12+
13+
let contents = fs::read_to_string(&args[1]).expect("Something went wrong");
14+
println!("Part 1: {}", part1(&contents));
15+
println!("Part 2: {}", part2(&contents));
16+
}

2025/src/days.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod day01;

2025/src/days/day01.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::str::FromStr;
2+
3+
pub fn part1(contents: &str) -> i64 {
4+
let mut current: i64 = 50;
5+
let mut count = 0;
6+
for (dir, dist) in contents.lines().map(|line| parse_line(line)) {
7+
match dir {
8+
'L' => current = (current - dist).rem_euclid(100),
9+
'R' => current = (current + dist).rem_euclid(100),
10+
_ => panic!("Invalid direction"),
11+
}
12+
13+
if current == 0 {
14+
count += 1;
15+
}
16+
}
17+
count
18+
}
19+
20+
pub fn part2(contents: &str) -> i64 {
21+
let mut current = 50;
22+
let mut count = 0;
23+
for (dir, dist) in contents.lines().map(|line| parse_line(line)) {
24+
match dir {
25+
'L' => {
26+
count += (current - dist).div_euclid(100).abs();
27+
if current == 0 && dist > 0 {
28+
// Moving left again will wrap around and count as another zero
29+
// crossing. Remove one here to avoid double-counting.
30+
count -= 1;
31+
}
32+
33+
current = (current - dist).rem_euclid(100);
34+
if current == 0 {
35+
// The division doesn't count landing on zero as a crossing,
36+
// so we need to increment the count here.
37+
count += 1;
38+
}
39+
}
40+
'R' => {
41+
count += (current + dist).div_euclid(100);
42+
current = (current + dist).rem_euclid(100);
43+
}
44+
_ => panic!("Invalid direction"),
45+
}
46+
}
47+
count
48+
}
49+
50+
fn parse_line(line: &str) -> (char, i64) {
51+
let (dir, dist) = line.split_at(1);
52+
(dir.chars().next().unwrap(), i64::from_str(dist).unwrap())
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use std::vec;
58+
59+
use super::*;
60+
61+
#[test]
62+
fn test_part1() {
63+
let lines = vec![
64+
"L68", "L30", "R48", "L5", "R60", "L55", "L1", "L99", "R14", "L82",
65+
];
66+
67+
assert_eq!(part1(&lines.join("\n")), 3);
68+
}
69+
70+
#[test]
71+
fn test_part2() {
72+
let lines = vec![
73+
"L68", "L30", "R48", "L5", "R60", "L55", "L1", "L99", "R14", "L82",
74+
];
75+
76+
assert_eq!(part2(&lines.join("\n")), 6);
77+
}
78+
}

2025/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod days;

2025/tests/day01.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use aoc2025::days::day01::{part1, part2};
2+
3+
#[test]
4+
fn test_part1() {
5+
let content = std::include_str!("../../private/inputs/2025/day01.txt");
6+
assert_eq!(part1(&content), 1118);
7+
}
8+
9+
#[test]
10+
fn test_part2() {
11+
let content = std::include_str!("../../private/inputs/2025/day01.txt");
12+
assert_eq!(part2(&content), 6289);
13+
}

private

0 commit comments

Comments
 (0)