Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize project files #8

Merged
merged 8 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ref: Reorganize Day 1 files
4618c80de3fc4cbe60dc339de058ffdbea397946

# ref: Reorganize Day 2 files
5ab3e6e4510d9cd5e37786746da46e1fe7f8e440

# ref: Reorganize Day 3 files
66690ddb52c70f887f90d32830ff04faa6283589

# ref: Reorganize Day 4 files
c313bcc707b50839d2e61a36ad94284d48f743d5

# ref: Reorganize Day 5 files
04dd034d9efc23d3cdc27c91c08af418fe635c53

# ref: Reorganize Day 6 files
6ea2bb3121a127830eb5f5b393765a61a3f07278

# doc: Update README.md files
3d0d817c3198d81c2c9330adb67cd49edcfbc446
56 changes: 45 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,58 @@ The project is compose of two main parts:
- A library, located in the [`lib/`](lib/) directory, containing the code for the solutions.
- A set of tests, located in the [`test/`](test/) directory, containing the tests for the solutions.

Tests are written using the [:octocat: minitest](https://github.com/minitest/minitest) framework.
Tests are written using the [minitest](https://github.com/minitest/minitest) framework.

To run the tests, simply run the following command:

```bash
bundle install
bundle exec rake test
SKIP_SLOW_TESTS=1 bundle exec rake test
```

## Puzzles

### 2023
<a href="https://www.ruby-lang.org"><img src="https://fortnite.gg/img/items/3275/featured.png" height="350px" margin="5px" align="right"/></a>

| Day | Solution | Rank |
|-------------------------------------------:|:--------------------------------------------------------:|:-----:|
| [1️⃣](https://adventofcode.com/2023/day/1) | [`lib/puzzles/2023/day01.rb`](lib/puzzles/2023/day01.rb) | ⭐🌟✴️ |
| [2️⃣](https://adventofcode.com/2023/day/2) | [`lib/puzzles/2023/day02.rb`](lib/puzzles/2023/day02.rb) | ⭐🌟✴️ |
| [3️⃣](https://adventofcode.com/2023/day/3) | [`lib/puzzles/2023/day03.rb`](lib/puzzles/2023/day03.rb) | ⭐🌟✴️ |
| [4️⃣](https://adventofcode.com/2023/day/4) | [`lib/puzzles/2023/day04.rb`](lib/puzzles/2023/day04.rb) | ⭐🌟✴️ |
| [5️⃣](https://adventofcode.com/2023/day/5) | [`lib/puzzles/2023/day05.rb`](lib/puzzles/2023/day05.rb) | ⭐🌟✴️ |
| [6️⃣](https://adventofcode.com/2023/day/6) | [`lib/puzzles/2023/day06.rb`](lib/puzzles/2023/day06.rb) | ⭐🌟✴️ |
<details open>
<summary><b>Advent of Code - <a href="https://adventofcode.com/2023">2023</a></b></summary>
<p>
<table>
<tr>
<th>Day</th>
<th>Solution</th>
<th>Rank</th>
</tr>
<tr>
<td>1️⃣ <a href="https://adventofcode.com/2023/day/1">Trebuchet?!</a></td>
<td><a href="lib/puzzles/2023/day01"><code>lib/puzzles/2023/day01</code></a></td>
<td>🌟🌟</td>
</tr>
<tr>
<td>2️⃣ <a href="https://adventofcode.com/2023/day/2">Cube Conundrum</a></td>
<td><a href="lib/puzzles/2023/day02"><code>lib/puzzles/2023/day02</code></a></td>
<td>🌟🌟</td>
</tr>
<tr>
<td>3️⃣ <a href="https://adventofcode.com/2023/day/3">Gear Ratios</a></td>
<td><a href="lib/puzzles/2023/day03"><code>lib/puzzles/2023/day03</code></a></td>
<td>🌟🌟</td>
</tr>
<tr>
<td>4️⃣ <a href="https://adventofcode.com/2023/day/4">Scratchcards</a></td>
<td><a href="lib/puzzles/2023/day04"><code>lib/puzzles/2023/day04</code></a></td>
<td>🌟🌟</td>
</tr>
<tr>
<td>5️⃣ <a href="https://adventofcode.com/2023/day/5">If You Give A Seed A Fertilizer</a></td>
<td><a href="lib/puzzles/2023/day05"><code>lib/puzzles/2023/day05</code></a></td>
<td>🌟🌟</td>
</tr>
<tr>
<td>6️⃣ <a href="https://adventofcode.com/2023/day/6">Wait For It</a></td>
<td><a href="lib/puzzles/2023/day06"><code>lib/puzzles/2023/day06</code></a></td>
<td>🌟🌟</td>
</tr>
</table>
</p>
</details>
52 changes: 52 additions & 0 deletions lib/puzzles/2023/day01/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# [Day 1: Trebuchet?!](https://adventofcode.com/2023/day/1)

## Part One

Something is wrong with global snow production, and you've been selected to take a look. The Elves have even given you a map; on it, they've used stars to mark the top fifty locations that are likely to be having problems.

You've been doing this long enough to know that to restore snow operations, you need to check all **fifty stars** by December 25th.

Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants **one star**. Good luck!

You try to ask why they can't just use a [weather machine](https://adventofcode.com/2015/day/1) ("not powerful enough") and where they're even sending you ("the sky") and why your map looks mostly blank ("you sure ask a lot of questions") and hang on did you just say the sky ("of course, where do you think snow comes from") when you realize that the Elves are already loading you into a [trebuchet](https://en.wikipedia.org/wiki/Trebuchet) ("please hold still, we need to strap you in").

As they're making the final adjustments, they discover that their calibration document (your puzzle input) has been **amended** by a very young Elf who was apparently just excited to show off her art skills. Consequently, the Elves are having trouble reading the values on the document.

The newly-improved calibration document consists of lines of text; each line originally contained a specific **calibration value** that the Elves now need to recover. On each line, the calibration value can be found by combining the **first digit** and the **last digit** (in that order) to form a single **two-digit number**.

For example:

```
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
```

In this example, the calibration values of these four lines are `12`, `38`, `15`, and `77`. Adding these together produces `142`.

Consider your entire calibration document. **What is the sum of all of the calibration values?**

Your puzzle answer was `54450`.

## Part Two

Your calculation isn't quite right. It looks like some of the digits are actually **spelled out with letters**: `one`, `two`, `three`, `four`, `five`, `six`, `seven`, `eight`, and `nine` **also** count as valid "digits".

Equipped with this new information, you now need to find the real first and last digit on each line. For example:

```
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen
```

In this example, the calibration values are `29`, `83`, `13`, `24`, `42`, `14`, and `76`. Adding these together produces `281`.

**What is the sum of all of the calibration values?**

Your puzzle answer was `54265`.
13 changes: 13 additions & 0 deletions lib/puzzles/2023/day01/day01.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

require_relative "part1"
require_relative "part2"

module AdventOfCode
module Puzzles2023
##
# {include:file:lib/puzzles/2023/day01/README.md}
module Day01
end
end
end
File renamed without changes.
73 changes: 73 additions & 0 deletions lib/puzzles/2023/day01/part1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# frozen_string_literal: true

module AdventOfCode
module Puzzles2023
module Day01
##
# Class for solving Day 1 - Part 1 puzzle
class Part1
##
# @param file [String] file with puzzle input
def initialize(file: nil)
file ||= "#{File.dirname(__FILE__)}/input.txt"
@file_contents = File.readlines(file, chomp: true)
end

##
# Compute the answer for the puzzle.
# The answer is the sum of all calibration values.
#
# @return [Integer] answer for the puzzle
def answer
calibration_values.sum
end

##
# Compute calibration values based on file contents.
#
# @return [Array<Integer>] calibration values
def calibration_values
@calibration_values ||= file_contents.map { |line| select_number(line) }
end

protected

##
# @return [Array<String>] file contents
attr_reader :file_contents

##
# Select first and last number from line.
#
# @param line [String] line to select numbers from
#
# @return [Integer] first and last number concatenated
def select_number(line)
first_number = find_first_number(line)
last_number = find_last_number(line)
"#{first_number}#{last_number}".to_i
end

##
# Find and return the first number in a line.
#
# @param line [String] line to search
#
# @return [Integer, nil] first number found
def find_first_number(line)
line.match(%r{^\D*(\d).*})[1]&.to_i
end

##
# Find and return the last number in a line.
#
# @param line [String] line to search
#
# @return [Integer, nil] last number found
def find_last_number(line)
line.match(%r{.*?(\d)\D*$})[1]&.to_i
end
end
end
end
end
73 changes: 6 additions & 67 deletions lib/puzzles/2023/day01.rb → lib/puzzles/2023/day01/part2.rb
Original file line number Diff line number Diff line change
@@ -1,79 +1,18 @@
# frozen_string_literal: true

require_relative "part1"

module AdventOfCode
module Puzzles2023
##
# Advent of Code 2023 - Day 1
# https://adventofcode.com/2023/day/1
module Day01
##
# Class for solving Day 01 - Part 1 puzzle
class Part1
attr_reader :file_contents

##
# @param file [String] file with puzzle input
def initialize(file:)
@file_contents = File.readlines(file, chomp: true)
end

##
# Compute the answer for the puzzle.
# The answer is the sum of all calibration values.
#
# @return [Integer] answer for the puzzle
def answer
calibration_values.sum
end

##
# Compute calibration values based on file contents.
#
# @return [Array<Integer>] calibration values
def calibration_values
@calibration_values ||= file_contents.map { |line| select_number(line) }
end

protected

##
# Select first and last number from line.
#
# @param line [String] line to select numbers from
#
# @return [Integer] first and last number concatenated
def select_number(line)
first_number = find_first_number(line)
last_number = find_last_number(line)
"#{first_number}#{last_number}".to_i
end

##
# Find and return the first number in a line.
#
# @param line [String] line to search
#
# @return [Integer, nil] first number found
def find_first_number(line)
line.match(%r{^\D*(\d).*})[1]&.to_i
end

##
# Find and return the last number in a line.
#
# @param line [String] line to search
#
# @return [Integer, nil] last number found
def find_last_number(line)
line.match(%r{.*?(\d)\D*$})[1]&.to_i
end
end

##
# Class for solving Day 01 - Part 2 puzzle
# Class for solving Day 1 - Part 2 puzzle
class Part2 < Part1
protected

##
# Helper constant for translating word numbers to digits.
# @return [Hash<Symbol, Integer>] word numbers to digits
TRANSLATIONS = %i[one two three four five six seven eight nine].zip(1..9).to_h.freeze

##
Expand Down
Loading