Skip to content

Commit

Permalink
feat: advent of code 2022 day one
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric allen committed Dec 1, 2022
1 parent 0c7ae58 commit 859cd5e
Show file tree
Hide file tree
Showing 9 changed files with 2,448 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
@@ -0,0 +1,3 @@
{
"rust-analyzer.linkedProjects": [ "2022/advent/Cargo.toml" ]
}
31 changes: 31 additions & 0 deletions 2022/README.md
@@ -0,0 +1,31 @@
# Advent of Code 2022

This directory contains solutions for the [2022 Advent of Code](https://adventofcode.com/2022).

**Note**: This year I used the Advent of Code event as an excuse to learn about [Rust](https://www.rust-lang.org/).

## Solutions

The `advent` directory contains the actual code for solving each day's puzzle and can be run via:

```sh
# $day and $part are the integers that represent the day and part (1 or 2) that you would like to solve
cargo run -- $day $part
```

### Testing

To run the solution with the example data you can provide the test flag as the first parameter:

```sh
# this will test the Day 1 Part 2 solution with the example input
cargo run -- test 1 2
```

**TODO**: Integrate the testing better and have it use the [`assert!()` macro](https://doc.rust-lang.org/std/macro.assert.html) to test against the example solution.

## Input Data

The `inputs` directory contains static `.dat` files with the actual puzzle input for each day, named like `day-{N}.dat` where `N` is the day. It also contains `.test` files with the example input from the description for that day to allow easy checking of the logic with the example input and solution before applying it to the real data.


7 changes: 7 additions & 0 deletions 2022/advent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions 2022/advent/Cargo.toml
@@ -0,0 +1,8 @@
[package]
name = "advent"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
46 changes: 46 additions & 0 deletions 2022/advent/src/days/day_one.rs
@@ -0,0 +1,46 @@
use crate::PART_TWO_INDICATOR;

static NUMBER_OF_ELVES_TO_RETURN: usize = 3;

fn calculate_elf_calories(meals: Vec<&str>) -> i32 {
return meals.iter().flat_map(|x| x.parse::<i32>()).sum()
}

fn part_one(input: String) -> String {
let mut most_calories:i32 = 0;

let elves: Vec<&str> = input.split("\n\n").collect();

for elf in elves {
let meals: Vec<&str> = elf.split_whitespace().collect();

let total_calories: i32 = calculate_elf_calories(meals);

if total_calories > most_calories {
most_calories = total_calories
}
}

return format!("The elf with the most calories has:\n{}", most_calories);
}


fn part_two(input: String) -> String {
let elves: Vec<&str> = input.split("\n\n").collect();

let mut total_calories: Vec<i32> = elves.iter().map(|x| calculate_elf_calories(x.split_whitespace().collect())).collect();

total_calories.sort_by(|a, b| b.cmp(a));

let top_calories: i32 = total_calories.iter().take(NUMBER_OF_ELVES_TO_RETURN).sum();

return format!("The {} elves with the most calories have\n{:?}", NUMBER_OF_ELVES_TO_RETURN, top_calories);
}


pub fn main(input: String, part: &str) -> String {
match part {
PART_TWO_INDICATOR => return part_two(input),
_ => return part_one(input)
}
}
12 changes: 12 additions & 0 deletions 2022/advent/src/days/days.rs
@@ -0,0 +1,12 @@
#[path = "./day_one.rs"] mod day_one;

static ERROR_MESSAGE: &str = "No Solution Found for Day";

const DAY_ONE: &str = "1";

pub fn main(day: &str, part: &str, input: String) -> String {
match day {
DAY_ONE => return day_one::main(input, part),
_ => return format!("{} {}", ERROR_MESSAGE, day)
}
}
72 changes: 72 additions & 0 deletions 2022/advent/src/main.rs
@@ -0,0 +1,72 @@
use std::env;
use std::fs;

#[path = "./days/days.rs"] mod days;

static DEBUGGING: bool = true;

static DEFAULT_DAY: &'static str = "1";
static DEFAULT_PART: &'static str = "1";

const PART_TWO_INDICATOR: &'static str = "2";

const TEST_FLAG: &'static str = "test";

fn main() {
let args: Vec<String> = env::args().collect();

let actual_args = &args[1..args.len()];

if DEBUGGING {
println!("Arguments:\n{:?}", actual_args);
}

let is_test: bool = actual_args[0] == TEST_FLAG;

if DEBUGGING {
println!("Testing: {}", is_test);
}

let day = if actual_args.len() > 2 {
&actual_args[1]
} else if args.len() > 0 && !is_test {
&actual_args[0]
} else {
DEFAULT_DAY
};

let part = if actual_args.len() > 2 {
&actual_args[2]
} else if actual_args.len() > 1 && !is_test {
&actual_args[1]
} else {
DEFAULT_PART
};

if DEBUGGING {
println!("Day: {}\nPart: {}", day, part);
}

let input: String = read_input(day, is_test);

println!("{}", days::main(day, part, input));
}

fn read_input(day: &str, is_test: bool) -> String {
let file_extension = match is_test {
true => "test",
_ => "dat"
};

let file_path = format!("../inputs/day-{}.{}", day, file_extension);

if DEBUGGING {
println!("In file {}", file_path);
}

// borrowed from: https://doc.rust-lang.org/book/ch12-02-reading-a-file.html
let contents = fs::read_to_string(file_path)
.expect("Should have been able to read the file");

return contents;
}

0 comments on commit 859cd5e

Please sign in to comment.