Really good use of doctests!
Thanks! If I had known about Stream.drop/1
, my part2_with_stream_iteration
function would have looked like @sasajuric 's solution.
My solution is eerily similar to a lot of the posts here:
I did go back and replace the tests with doctests. Should help keep things clear going forward. Great idea!
My solutions for Day 1
- Part 1: https://github.com/debajit/advent-of-code-2019/blob/master/day_01_rocket_equation/lib/part1.ex
- Part 2: https://github.com/debajit/advent-of-code-2019/blob/master/day_01_rocket_equation/lib/part2.ex
I wrote them in a way that I thought was easy for me to reason about. I havenāt seen the answers above yet (Iām going to do that later tonight ā I always learn so much new that way ). Snippets below:
Part 1
defmodule Part1 do
@doc """
iex> fuel_for_mass(12)
2
iex> fuel_for_mass(14)
2
iex> fuel_for_mass(1969)
654
iex> fuel_for_mass(100756)
33583
"""
def fuel_for_mass(mass) do
div(mass, 3) - 2
end
def total_fuel(input_file) do
File.stream!(input_file)
|> Stream.map(&String.trim/1)
|> Stream.map(&String.to_integer/1)
|> Stream.map(&fuel_for_mass/1)
|> Enum.sum()
end
end
Part 2
defmodule Part2 do
@doc """
iex> fuel_for_mass(12)
2
iex> fuel_for_mass(14)
2
iex> fuel_for_mass(1969)
654
iex> fuel_for_mass(100756)
33583
"""
def fuel_for_mass(mass) do
div(mass, 3) - 2
end
@doc """
iex(9)> total_fuel_for_mass(14)
2
iex(10)> total_fuel_for_mass(1969)
966
iex(11)> total_fuel_for_mass(100756)
50346
"""
def total_fuel_for_mass(mass_or_fuel) do
fuel = fuel_for_mass(mass_or_fuel)
if fuel > 0 do
fuel + total_fuel_for_mass(fuel)
else
0
end
end
def total_fuel(input_file) do
File.stream!(input_file)
|> Stream.map(&String.trim/1)
|> Stream.map(&String.to_integer/1)
|> Stream.map(&total_fuel_for_mass/1)
|> Enum.sum()
end
end
Iām learning Elixir with doing AOC and got improved a lot. Thanks to this post, I borrowed a lot of brilliant ideas from @sasajuric @dimitarvp and improved my repo.
Hereās the day1 solution I end up with:
defmodule AOC.Y2019.Day01 do
@masses "2019/day01.txt"
|> AOC.Input.stream(&String.to_integer/1)
|> Enum.to_list()
def part1 do
@masses
|> Enum.reduce(0, &(div(&1, 3) - 2 + &2))
end
def part2 do
@masses
|> Enum.reduce(0, &(fuel(&1) + &2))
end
def fuel(mass) do
case div(mass, 3) - 2 do
x when x > 0 ->
x + fuel(x)
_ ->
0
end
end
end
Here is mine
defmodule AOC.Day1 do
def part1(file_stream) do
file_stream
|> Enum.reduce(0, fn n, acc -> acc + calculate_fuel(n) end)
end
def part2(file_stream) do
file_stream
|> Enum.reduce(0, fn n, acc -> acc + additional_fuel(n, 0) end)
end
defp calculate_fuel(n), do: div(n, 3) - 2
defp additional_fuel(fuel, additional) when fuel < 6, do: additional
defp additional_fuel(fuel, additional) do
new_fuel = calculate_fuel(fuel)
additional_fuel(new_fuel, additional + new_fuel)
end
end
And here is test. I create file stream in the test
defmodule Day1Test do
use ExUnit.Case
alias AOC.Day1
test "solution day 1 part 1" do
input = read_input("test/input/day1_input")
assert Day1.part1(input) == 3_152_919
end
test "solution day 1 part 2" do
input = read_input("test/input/day1_input")
assert Day1.part2(input) == 4_726_527
end
defp read_input(file) do
file
|> File.stream!([], :line)
|> Stream.map(fn line ->
{integer, _leftover} = Integer.parse(line)
integer
end)
end
end
Repo: https://github.com/gsarwate/advent_of_code_2019/blob/master/lib/aoc/day1.ex
and incorporating great suggestions in this thread, my āfinalā day 1 looks like:
defmodule AOC.Day1 do
def part1 do
AOC.integer_stream(1)
|> Enum.reduce(0, fn mass, acc -> fuel(mass) + acc end)
end
def part2 do
AOC.integer_stream(1)
|> Stream.map(&fuel/1)
|> Enum.reduce(0, fn mass, acc -> add_fuel(mass) + acc end)
end
def fuel(mass) do
max(0, trunc(mass / 3) - 2)
end
def add_fuel(mass) do
case fuel(mass) do
0 -> 0
f -> mass + add_fuel(f)
end
end
end
Thatās a great idea. Does the site let you start late or do you have to keep up every day?
Are you going to do some videos like last year?
Yep, you can solve the tasks whenever youād like, esp. if you donāt care about your place in the leaderboard
I decided to record my Erlang solutions this year, to show how much I can fail in trying to find a decently effective solution and how I come up with code.
Hereās Day 1: