Refactor days 7-9 of AoC 2023
- Add `solve` task. - Add tests for examples.
This commit is contained in:
parent
669b914523
commit
e994381b27
40 changed files with 230 additions and 181 deletions
|
@ -1,4 +1,8 @@
|
||||||
# Day 7: Camel Cards
|
# Advent of Code 2023 day 7 solution in Elixir
|
||||||
|
|
||||||
|
## Camel Cards
|
||||||
|
|
||||||
|
[Task page](https://adventofcode.com/2023/day/7)
|
||||||
|
|
||||||
Your all-expenses-paid trip turns out to be a one-way, five-minute ride in an airship.
|
Your all-expenses-paid trip turns out to be a one-way, five-minute ride in an airship.
|
||||||
(At least it's a cool airship!) It drops you off at the edge of a vast desert and descends back to Island Island.
|
(At least it's a cool airship!) It drops you off at the edge of a vast desert and descends back to Island Island.
|
||||||
|
@ -19,7 +23,8 @@ but the machines have broken down because Desert Island recently stopped receivi
|
||||||
|
|
||||||
You've already assumed it'll be your job to figure out why the parts stopped when she asks if you can help. You agree automatically.
|
You've already assumed it'll be your job to figure out why the parts stopped when she asks if you can help. You agree automatically.
|
||||||
|
|
||||||
Because the journey will take a few days, she offers to teach you the game of Camel Cards. Camel Cards is sort of similar to poker except it's designed to be easier to play while riding a camel.
|
Because the journey will take a few days, she offers to teach you the game of Camel Cards.
|
||||||
|
Camel Cards is sort of similar to poker except it's designed to be easier to play while riding a camel.
|
||||||
|
|
||||||
In Camel Cards, you get a list of hands, and your goal is to order them based on the strength of each hand.
|
In Camel Cards, you get a list of hands, and your goal is to order them based on the strength of each hand.
|
||||||
A hand consists of five cards labeled one of `A`, `K`, `Q`, `J`, `T`, `9`, `8`, `7`, `6`, `5`, `4`, `3`, or `2`.
|
A hand consists of five cards labeled one of `A`, `K`, `Q`, `J`, `T`, `9`, `8`, `7`, `6`, `5`, `4`, `3`, or `2`.
|
||||||
|
@ -27,13 +32,14 @@ The relative strength of each card follows this order, where `A` is the highest
|
||||||
|
|
||||||
Every hand is exactly one type. From strongest to weakest, they are:
|
Every hand is exactly one type. From strongest to weakest, they are:
|
||||||
|
|
||||||
- Five of a kind, where all five cards have the same label: AAAAA
|
- Five of a kind, where all five cards have the same label: `AAAAA`
|
||||||
- Four of a kind, where four cards have the same label and one card has a different label: AA8AA
|
- Four of a kind, where four cards have the same label and one card has a different label: `AA8AA`
|
||||||
- Full house, where three cards have the same label, and the remaining two cards share a different label: 23332
|
- Full house, where three cards have the same label, and the remaining two cards share a different label: `23332`
|
||||||
- Three of a kind, where three cards have the same label, and the remaining two cards are each different from any other card in the hand: TTT98
|
- Three of a kind, where three cards have the same label, and the remaining two cards are each different
|
||||||
- Two pair, where two cards share one label, two other cards share a second label, and the remaining card has a third label: 23432
|
from any other card in the hand: `TTT98`
|
||||||
- One pair, where two cards share one label, and the other three cards have a different label from the pair and each other: A23A4
|
- Two pair, where two cards share one label, two other cards share a second label, and the remaining card has a third label: `23432`
|
||||||
- High card, where all cards' labels are distinct: 23456
|
- One pair, where two cards share one label, and the other three cards have a different label from the pair and each other: `A23A4`
|
||||||
|
- High card, where all cards' labels are distinct: `23456`
|
||||||
|
|
||||||
Hands are primarily ordered based on type; for example, every full house is stronger than any three of a kind.
|
Hands are primarily ordered based on type; for example, every full house is stronger than any three of a kind.
|
||||||
|
|
||||||
|
@ -65,13 +71,16 @@ Because there are five hands in this example, the strongest hand will have rank
|
||||||
So, the first step is to put the hands in order of strength:
|
So, the first step is to put the hands in order of strength:
|
||||||
|
|
||||||
- `32T3K` is the only one pair and the other hands are all a stronger type, so it gets rank 1.
|
- `32T3K` is the only one pair and the other hands are all a stronger type, so it gets rank 1.
|
||||||
- `KK677` and `KTJJT` are both two pair. Their first cards both have the same label, but the second card of `KK677` is stronger (K vs T), so `KTJJT` gets rank 2 and `KK677` gets rank 3.
|
- `KK677` and `KTJJT` are both two pair. Their first cards both have the same label,
|
||||||
|
but the second card of `KK677` is stronger (K vs T), so `KTJJT` gets rank 2 and `KK677` gets rank 3.
|
||||||
- `T55J5` and `QQQJA` are both three of a kind. `QQQJA` has a stronger first card, so it gets rank 5 and `T55J5` gets rank 4.
|
- `T55J5` and `QQQJA` are both three of a kind. `QQQJA` has a stronger first card, so it gets rank 5 and `T55J5` gets rank 4.
|
||||||
|
|
||||||
Now, you can determine the total winnings of this set of hands by adding up the result of multiplying each hand's bid with its rank (765 * 1 + 220 * 2 + 28 * 3 + 684 * 4 + 483 * 5). So the total winnings in this example are 6440.
|
Now, you can determine the total winnings of this set of hands by adding up the result of multiplying each hand's bid with
|
||||||
|
its rank (765 * 1 + 220 * 2 + 28 * 3 + 684 * 4 + 483 * 5). So the total winnings in this example are 6440.
|
||||||
|
|
||||||
Find the rank of every hand in your set. What are the total winnings?
|
Find the rank of every hand in your set. What are the total winnings?
|
||||||
|
|
||||||
|
|
||||||
## Part Two
|
## Part Two
|
||||||
|
|
||||||
To make things a little more interesting, the Elf introduces one additional rule.
|
To make things a little more interesting, the Elf introduces one additional rule.
|
|
@ -1,12 +1,5 @@
|
||||||
defmodule Solution do
|
defmodule Cards do
|
||||||
@spec get_total_winnings(String.t()) :: integer()
|
def get_total_winnings(hands, with_jokers \\ false) do
|
||||||
def get_total_winnings(filename, with_jokers \\ false) do
|
|
||||||
hands =
|
|
||||||
filename
|
|
||||||
|> File.stream!()
|
|
||||||
|> Enum.map(&parse_line/1)
|
|
||||||
|> Map.new()
|
|
||||||
|
|
||||||
sorted_cards =
|
sorted_cards =
|
||||||
hands
|
hands
|
||||||
|> Map.keys()
|
|> Map.keys()
|
||||||
|
@ -17,15 +10,6 @@ defmodule Solution do
|
||||||
|> Enum.reduce(0, fn {el, idx}, acc -> acc + idx * hands[el] end)
|
|> Enum.reduce(0, fn {el, idx}, acc -> acc + idx * hands[el] end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp parse_line(line) do
|
|
||||||
[hand, bid] =
|
|
||||||
line
|
|
||||||
|> String.trim()
|
|
||||||
|> String.split(" ")
|
|
||||||
|
|
||||||
{hand, String.to_integer(bid)}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Map a hand to a list that may be used for sorting.
|
# Map a hand to a list that may be used for sorting.
|
||||||
defp get_sorting_order(hand, with_jokers) do
|
defp get_sorting_order(hand, with_jokers) do
|
||||||
# Map cards to corresponding power,
|
# Map cards to corresponding power,
|
||||||
|
@ -44,13 +28,13 @@ defmodule Solution do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> Solution.get_card_power("J")
|
iex> Cards.get_card_power("J")
|
||||||
11
|
11
|
||||||
|
|
||||||
iex> Solution.get_card_power("J", true)
|
iex> Cards.get_card_power("J", true)
|
||||||
1
|
1
|
||||||
|
|
||||||
iex> Solution.get_card_power("5")
|
iex> Cards.get_card_power("5")
|
||||||
5
|
5
|
||||||
"""
|
"""
|
||||||
def get_card_power(card, with_jokers \\ false) do
|
def get_card_power(card, with_jokers \\ false) do
|
||||||
|
@ -80,25 +64,25 @@ defmodule Solution do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> Solution.get_rank("AAAAA")
|
iex> Cards.get_rank("AAAAA")
|
||||||
7
|
7
|
||||||
|
|
||||||
iex> Solution.get_rank("AA8AA")
|
iex> Cards.get_rank("AA8AA")
|
||||||
6
|
6
|
||||||
|
|
||||||
iex> Solution.get_rank("23332")
|
iex> Cards.get_rank("23332")
|
||||||
5
|
5
|
||||||
|
|
||||||
iex> Solution.get_rank("TTT98")
|
iex> Cards.get_rank("TTT98")
|
||||||
4
|
4
|
||||||
|
|
||||||
iex> Solution.get_rank("23432")
|
iex> Cards.get_rank("23432")
|
||||||
3
|
3
|
||||||
|
|
||||||
iex> Solution.get_rank("A23A4")
|
iex> Cards.get_rank("A23A4")
|
||||||
2
|
2
|
||||||
|
|
||||||
iex> Solution.get_rank("23456")
|
iex> Cards.get_rank("23456")
|
||||||
1
|
1
|
||||||
"""
|
"""
|
||||||
def get_rank(hand, with_jokers \\ false) do
|
def get_rank(hand, with_jokers \\ false) do
|
||||||
|
@ -134,13 +118,13 @@ defmodule Solution do
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
iex> Solution.replace_joker("T55J5")
|
iex> Cards.replace_joker("T55J5")
|
||||||
"T5555"
|
"T5555"
|
||||||
|
|
||||||
iex> Solution.replace_joker("KTJJT")
|
iex> Cards.replace_joker("KTJJT")
|
||||||
"KTTTT"
|
"KTTTT"
|
||||||
|
|
||||||
iex> Solution.replace_joker("JJJJJ")
|
iex> Cards.replace_joker("JJJJJ")
|
||||||
"AAAAA"
|
"AAAAA"
|
||||||
"""
|
"""
|
||||||
def replace_joker(hand) do
|
def replace_joker(hand) do
|
17
advent-of-code/2023/day_07/lib/parser.ex
Normal file
17
advent-of-code/2023/day_07/lib/parser.ex
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
defmodule Parser do
|
||||||
|
def parse_file(filename) do
|
||||||
|
filename
|
||||||
|
|> File.stream!()
|
||||||
|
|> Stream.map(&parse_line/1)
|
||||||
|
|> Map.new()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp parse_line(line) do
|
||||||
|
[hand, bid] =
|
||||||
|
line
|
||||||
|
|> String.trim()
|
||||||
|
|> String.split(" ")
|
||||||
|
|
||||||
|
{hand, String.to_integer(bid)}
|
||||||
|
end
|
||||||
|
end
|
10
advent-of-code/2023/day_07/lib/task.ex
Normal file
10
advent-of-code/2023/day_07/lib/task.ex
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
defmodule Mix.Tasks.Solve do
|
||||||
|
use Mix.Task
|
||||||
|
|
||||||
|
def run(_) do
|
||||||
|
hands = Parser.parse_file("input.txt")
|
||||||
|
|
||||||
|
IO.puts("Part 1: #{Cards.get_total_winnings(hands)}")
|
||||||
|
IO.puts("Part 2: #{Cards.get_total_winnings(hands, true)}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,18 +11,13 @@ defmodule Day07.MixProject do
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run "mix help compile.app" to learn about applications.
|
|
||||||
def application do
|
def application do
|
||||||
[
|
[
|
||||||
extra_applications: [:logger]
|
extra_applications: [:logger]
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run "mix help deps" to learn about dependencies.
|
|
||||||
defp deps do
|
defp deps do
|
||||||
[
|
[]
|
||||||
# {:dep_from_hexpm, "~> 0.3.0"},
|
|
||||||
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
14
advent-of-code/2023/day_07/test/cards_test.exs
Normal file
14
advent-of-code/2023/day_07/test/cards_test.exs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
defmodule CardsTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Cards
|
||||||
|
|
||||||
|
test "example 1" do
|
||||||
|
hands = Parser.parse_file("test/example.txt")
|
||||||
|
assert Cards.get_total_winnings(hands) == 6440
|
||||||
|
end
|
||||||
|
|
||||||
|
test "example 2" do
|
||||||
|
hands = Parser.parse_file("test/example.txt")
|
||||||
|
assert Cards.get_total_winnings(hands, true) == 5905
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,8 @@
|
||||||
# Day 8
|
# Advent of Code 2023 day 8 solution in Elixir
|
||||||
|
|
||||||
|
## Haunted Wasteland
|
||||||
|
|
||||||
|
[Task page](https://adventofcode.com/2023/day/8)
|
||||||
|
|
||||||
You're still riding a camel across Desert Island when you spot a sandstorm quickly approaching.
|
You're still riding a camel across Desert Island when you spot a sandstorm quickly approaching.
|
||||||
When you turn to warn the Elf, she disappears before your eyes! To be fair, she had just finished warning you about ghosts a few minutes ago.
|
When you turn to warn the Elf, she disappears before your eyes! To be fair, she had just finished warning you about ghosts a few minutes ago.
|
||||||
|
@ -45,6 +49,7 @@ ZZZ = (ZZZ, ZZZ)
|
||||||
|
|
||||||
Starting at AAA, follow the left/right instructions. How many steps are required to reach ZZZ?
|
Starting at AAA, follow the left/right instructions. How many steps are required to reach ZZZ?
|
||||||
|
|
||||||
|
|
||||||
## Part Two
|
## Part Two
|
||||||
|
|
||||||
The sandstorm is upon you and you aren't any closer to escaping the wasteland.
|
The sandstorm is upon you and you aren't any closer to escaping the wasteland.
|
||||||
|
@ -79,15 +84,13 @@ Repeat this process until all of the nodes you're currently on end with Z.
|
||||||
(If only some of the nodes you're on end with Z, they act like any other node and you continue as normal.)
|
(If only some of the nodes you're on end with Z, they act like any other node and you continue as normal.)
|
||||||
In this example, you would proceed as follows:
|
In this example, you would proceed as follows:
|
||||||
|
|
||||||
```
|
- Step 0: You are at 11A and 22A.
|
||||||
Step 0: You are at 11A and 22A.
|
- Step 1: You choose all of the left paths, leading you to 11B and 22B.
|
||||||
Step 1: You choose all of the left paths, leading you to 11B and 22B.
|
- Step 2: You choose all of the right paths, leading you to 11Z and 22C.
|
||||||
Step 2: You choose all of the right paths, leading you to 11Z and 22C.
|
- Step 3: You choose all of the left paths, leading you to 11B and 22Z.
|
||||||
Step 3: You choose all of the left paths, leading you to 11B and 22Z.
|
- Step 4: You choose all of the right paths, leading you to 11Z and 22B.
|
||||||
Step 4: You choose all of the right paths, leading you to 11Z and 22B.
|
- Step 5: You choose all of the left paths, leading you to 11B and 22C.
|
||||||
Step 5: You choose all of the left paths, leading you to 11B and 22C.
|
- Step 6: You choose all of the right paths, leading you to 11Z and 22Z.
|
||||||
Step 6: You choose all of the right paths, leading you to 11Z and 22Z.
|
|
||||||
```
|
|
||||||
|
|
||||||
So, in this example, you end up entirely on nodes that end in Z after 6 steps.
|
So, in this example, you end up entirely on nodes that end in Z after 6 steps.
|
||||||
|
|
|
@ -7,7 +7,6 @@ defmodule Navigator do
|
||||||
iex> Navigator.count_steps(["R"], %{"AAA" => ["AAA", "ZZZ"], "ZZZ" => ["ZZZ", "ZZZ"]})
|
iex> Navigator.count_steps(["R"], %{"AAA" => ["AAA", "ZZZ"], "ZZZ" => ["ZZZ", "ZZZ"]})
|
||||||
1
|
1
|
||||||
"""
|
"""
|
||||||
@spec count_steps(list(String.t()), map()) :: integer()
|
|
||||||
def count_steps(instructions, maps) do
|
def count_steps(instructions, maps) do
|
||||||
count_steps(instructions, instructions, maps, "AAA", 0)
|
count_steps(instructions, instructions, maps, "AAA", 0)
|
||||||
end
|
end
|
|
@ -1,16 +1,12 @@
|
||||||
defmodule NavigatorTest do
|
defmodule Mix.Tasks.Solve do
|
||||||
use ExUnit.Case
|
use Mix.Task
|
||||||
doctest Navigator
|
|
||||||
doctest Parser
|
|
||||||
|
|
||||||
test "part 1" do
|
def run(_) do
|
||||||
{instructions, maps} = Parser.parse_file("input.txt")
|
{instructions, maps} = Parser.parse_file("input.txt")
|
||||||
|
|
||||||
res = Navigator.count_steps(instructions, maps)
|
res = Navigator.count_steps(instructions, maps)
|
||||||
IO.puts("Part 1: #{res}")
|
IO.puts("Part 1: #{res}")
|
||||||
end
|
|
||||||
|
|
||||||
test "part 2" do
|
|
||||||
{instructions, maps} = Parser.parse_file("input.txt")
|
|
||||||
res = Navigator.count_ghost_steps(instructions, maps)
|
res = Navigator.count_ghost_steps(instructions, maps)
|
||||||
IO.puts("Part 2: #{res}")
|
IO.puts("Part 2: #{res}")
|
||||||
end
|
end
|
25
advent-of-code/2023/day_08/mix.exs
Normal file
25
advent-of-code/2023/day_08/mix.exs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
defmodule Day08.MixProject do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[
|
||||||
|
app: :day_08,
|
||||||
|
version: "0.1.0",
|
||||||
|
elixir: "~> 1.16",
|
||||||
|
start_permanent: Mix.env() == :prod,
|
||||||
|
deps: deps()
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def application do
|
||||||
|
[
|
||||||
|
extra_applications: [:logger]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp deps do
|
||||||
|
[
|
||||||
|
{:math, "~> 0.7.0"}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
3
advent-of-code/2023/day_08/mix.lock
Normal file
3
advent-of-code/2023/day_08/mix.lock
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
%{
|
||||||
|
"math": {:hex, :math, "0.7.0", "12af548c3892abf939a2e242216c3e7cbfb65b9b2fe0d872d05c6fb609f8127b", [:mix], [], "hexpm", "7987af97a0c6b58ad9db43eb5252a49fc1dfe1f6d98f17da9282e297f594ebc2"},
|
||||||
|
}
|
9
advent-of-code/2023/day_08/test/input-1.txt
Normal file
9
advent-of-code/2023/day_08/test/input-1.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
RL
|
||||||
|
|
||||||
|
AAA = (BBB, CCC)
|
||||||
|
BBB = (DDD, EEE)
|
||||||
|
CCC = (ZZZ, GGG)
|
||||||
|
DDD = (DDD, DDD)
|
||||||
|
EEE = (EEE, EEE)
|
||||||
|
GGG = (GGG, GGG)
|
||||||
|
ZZZ = (ZZZ, ZZZ)
|
10
advent-of-code/2023/day_08/test/input-2.txt
Normal file
10
advent-of-code/2023/day_08/test/input-2.txt
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
LR
|
||||||
|
|
||||||
|
11A = (11B, XXX)
|
||||||
|
11B = (XXX, 11Z)
|
||||||
|
11Z = (11B, XXX)
|
||||||
|
22A = (22B, XXX)
|
||||||
|
22B = (22C, 22C)
|
||||||
|
22C = (22Z, 22Z)
|
||||||
|
22Z = (22B, 22B)
|
||||||
|
XXX = (XXX, XXX)
|
15
advent-of-code/2023/day_08/test/navigator_test.exs
Normal file
15
advent-of-code/2023/day_08/test/navigator_test.exs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule NavigatorTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Navigator
|
||||||
|
doctest Parser
|
||||||
|
|
||||||
|
test "example 1" do
|
||||||
|
{instructions, maps} = Parser.parse_file("test/input-1.txt")
|
||||||
|
assert Navigator.count_steps(instructions, maps) == 2
|
||||||
|
end
|
||||||
|
|
||||||
|
test "example 2" do
|
||||||
|
{instructions, maps} = Parser.parse_file("test/input-2.txt")
|
||||||
|
assert Navigator.count_ghost_steps(instructions, maps) == 6
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,8 @@
|
||||||
# Oasis
|
# Advent of Code 2023 day 9 solution in Elixir
|
||||||
|
|
||||||
|
## Mirage Maintenance
|
||||||
|
|
||||||
|
[Task page](https://adventofcode.com/2023/day/9)
|
||||||
|
|
||||||
You ride the camel through the sandstorm and stop where the ghost's maps told you to stop.
|
You ride the camel through the sandstorm and stop where the ghost's maps told you to stop.
|
||||||
The sandstorm subsequently subsides, somehow seeing you standing at an oasis!
|
The sandstorm subsequently subsides, somehow seeing you standing at an oasis!
|
|
@ -1,30 +1,14 @@
|
||||||
defmodule Oasis do
|
defmodule Oasis do
|
||||||
@moduledoc """
|
def get_next_values_sum(lists) do
|
||||||
Day 9 of Advent of Code 2023.
|
lists
|
||||||
|
|> Stream.map(fn list -> Oasis.predict(list, &Oasis.predict_next_value/2) end)
|
||||||
Link: https://adventofcode.com/2023/day/9.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def solve() do
|
|
||||||
input =
|
|
||||||
File.stream!("input.txt")
|
|
||||||
|> Stream.map(&String.trim_trailing/1)
|
|
||||||
# Get lists of strings.
|
|
||||||
|> Stream.map(&String.split/1)
|
|
||||||
# Get lists of integers.
|
|
||||||
|> Stream.map(fn list -> Enum.map(list, &String.to_integer/1) end)
|
|
||||||
|
|
||||||
# Predict next value for each list.
|
|
||||||
input
|
|
||||||
|> Stream.map(fn list -> predict(list, &predict_next_value/2) end)
|
|
||||||
|> Enum.sum()
|
|> Enum.sum()
|
||||||
|> IO.puts()
|
end
|
||||||
|
|
||||||
# Predict previous value for each list.
|
def get_prev_values_sum(lists) do
|
||||||
input
|
lists
|
||||||
|> Stream.map(fn list -> predict(list, &predict_prev_value/2) end)
|
|> Stream.map(fn list -> Oasis.predict(list, &Oasis.predict_prev_value/2) end)
|
||||||
|> Enum.sum()
|
|> Enum.sum()
|
||||||
|> IO.puts()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
8
advent-of-code/2023/day_09/lib/parser.ex
Normal file
8
advent-of-code/2023/day_09/lib/parser.ex
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
defmodule Parser do
|
||||||
|
def parse(filename) do
|
||||||
|
File.stream!(filename)
|
||||||
|
|> Stream.map(&String.trim_trailing/1)
|
||||||
|
|> Stream.map(&String.split/1)
|
||||||
|
|> Stream.map(fn list -> Enum.map(list, &String.to_integer/1) end)
|
||||||
|
end
|
||||||
|
end
|
13
advent-of-code/2023/day_09/lib/task.ex
Normal file
13
advent-of-code/2023/day_09/lib/task.ex
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
defmodule Mix.Tasks.Solve do
|
||||||
|
use Mix.Task
|
||||||
|
|
||||||
|
def run(_) do
|
||||||
|
input = Parser.parse("input.txt")
|
||||||
|
|
||||||
|
res1 = Oasis.get_next_values_sum(input)
|
||||||
|
IO.puts("Part 1: #{res1}")
|
||||||
|
|
||||||
|
res2 = Oasis.get_prev_values_sum(input)
|
||||||
|
IO.puts("Part 2: #{res2}")
|
||||||
|
end
|
||||||
|
end
|
23
advent-of-code/2023/day_09/mix.exs
Normal file
23
advent-of-code/2023/day_09/mix.exs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
defmodule Day09.MixProject do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[
|
||||||
|
app: :day_09,
|
||||||
|
version: "0.1.0",
|
||||||
|
elixir: "~> 1.16",
|
||||||
|
start_permanent: Mix.env() == :prod,
|
||||||
|
deps: deps()
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def application do
|
||||||
|
[
|
||||||
|
extra_applications: [:logger]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp deps do
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
3
advent-of-code/2023/day_09/test/input.txt
Normal file
3
advent-of-code/2023/day_09/test/input.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
0 3 6 9 12 15
|
||||||
|
1 3 6 10 15 21
|
||||||
|
10 13 16 21 30 45
|
14
advent-of-code/2023/day_09/test/oasis_test.exs
Normal file
14
advent-of-code/2023/day_09/test/oasis_test.exs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
defmodule OasisTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Oasis
|
||||||
|
|
||||||
|
test "example 1" do
|
||||||
|
input = Parser.parse("test/input.txt")
|
||||||
|
assert Oasis.get_next_values_sum(input) == 114
|
||||||
|
end
|
||||||
|
|
||||||
|
test "example 2" do
|
||||||
|
input = Parser.parse("test/input.txt")
|
||||||
|
assert Oasis.get_prev_values_sum(input) == 2
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,22 +0,0 @@
|
||||||
defmodule SolutionTest do
|
|
||||||
use ExUnit.Case
|
|
||||||
doctest Solution
|
|
||||||
|
|
||||||
test "example 1" do
|
|
||||||
assert Solution.get_total_winnings("test/example.txt") == 6440
|
|
||||||
end
|
|
||||||
|
|
||||||
test "part 1" do
|
|
||||||
res = Solution.get_total_winnings("test/input.txt")
|
|
||||||
IO.puts("First answer: #{res}")
|
|
||||||
end
|
|
||||||
|
|
||||||
test "example 2" do
|
|
||||||
assert Solution.get_total_winnings("test/example.txt", true) == 5905
|
|
||||||
end
|
|
||||||
|
|
||||||
test "part 2" do
|
|
||||||
res = Solution.get_total_winnings("test/input.txt", true)
|
|
||||||
IO.puts("Second answer: #{res}")
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,30 +0,0 @@
|
||||||
defmodule Navigator.MixProject do
|
|
||||||
use Mix.Project
|
|
||||||
|
|
||||||
def project do
|
|
||||||
[
|
|
||||||
app: :navigator,
|
|
||||||
version: "0.1.0",
|
|
||||||
elixir: "~> 1.16",
|
|
||||||
start_permanent: Mix.env() == :prod,
|
|
||||||
deps: deps()
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run "mix help compile.app" to learn about applications.
|
|
||||||
def application do
|
|
||||||
[
|
|
||||||
extra_applications: [:logger]
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run "mix help deps" to learn about dependencies.
|
|
||||||
defp deps do
|
|
||||||
[
|
|
||||||
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
|
|
||||||
{:math, "~> 0.7.0"}
|
|
||||||
# {:dep_from_hexpm, "~> 0.3.0"},
|
|
||||||
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
%{
|
|
||||||
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
|
|
||||||
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
|
|
||||||
"math": {:hex, :math, "0.7.0", "12af548c3892abf939a2e242216c3e7cbfb65b9b2fe0d872d05c6fb609f8127b", [:mix], [], "hexpm", "7987af97a0c6b58ad9db43eb5252a49fc1dfe1f6d98f17da9282e297f594ebc2"},
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
defmodule Oasis.MixProject do
|
|
||||||
use Mix.Project
|
|
||||||
|
|
||||||
def project do
|
|
||||||
[
|
|
||||||
app: :oasis,
|
|
||||||
version: "0.1.0",
|
|
||||||
elixir: "~> 1.16",
|
|
||||||
start_permanent: Mix.env() == :prod,
|
|
||||||
deps: deps()
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run "mix help compile.app" to learn about applications.
|
|
||||||
def application do
|
|
||||||
[
|
|
||||||
extra_applications: [:logger]
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Run "mix help deps" to learn about dependencies.
|
|
||||||
defp deps do
|
|
||||||
[
|
|
||||||
# {:dep_from_hexpm, "~> 0.3.0"},
|
|
||||||
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
|
||||||
]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,4 +0,0 @@
|
||||||
defmodule OasisTest do
|
|
||||||
use ExUnit.Case
|
|
||||||
doctest Oasis
|
|
||||||
end
|
|
Loading…
Reference in a new issue