DEV Community

Cover image for Advent of Code 2019 Solution Megathread - Day 1: The Tyranny of the Rocket Equation
Jon Bristow
Jon Bristow

Posted on • Edited on

Advent of Code 2019 Solution Megathread - Day 1: The Tyranny of the Rocket Equation

Well, we're off to a running start! Since the leaderboard is safely locked, we can go ahead and post our solutions now!

Day 1 - The Problem

Looks like Santa got himself in a bit of trouble this year! Seems like we're not dealing with time shenanigans, printer trouble, high-precision clock fueling or weather machine woes. This year we need to get Santa and his sleigh back from the edge of space.

But first... we need to get to him. Getting to him requires fuel. Let's calculate how much we'll need to make the trip.

Part 1 of this problem was a nice straightforward warmup. Part 2 was only a little bit trickier than the first, but I overthought it and gave myself the wrong answer anyway.

Ongoing Meta

Dev.to List of Leaderboards

If you were part of Ryan Palo's leaderboard last year, you're still a member of that!

If you want me to add your leaderboard code to this page, reply to one of these posts and/or send me a DM containing your code and any theming or notes you’d like me to add. (You can find your private leaderboard code on your "Private Leaderboard" page.)

I'll edit in any leaderboards that people want to post, along with any description for the kinds of people you want to have on it. (My leaderboard is being used as my office's leaderboard.) And if I get something wrong, please call me out or message me and I’ll fix it ASAP.

There's no limit to the number of leaderboards you can join, so there's no problem belonging to a "Beginner" and a language specific one if you want.

Neat Statistics

I'm planning on adding some statistics, but other than "what languages did we see yesterday" does anyone have any ideas?

Latest comments (33)

Collapse
 
bretthancox profile image
bretthancox • Edited

I wrote my day 1 up here:

Day 1

Written in Clojure

Collapse
 
thibpat profile image
Thibaut Patel

Here is my solution in JavaScript:

Collapse
 
yordiverkroost profile image
Yordi Verkroost

Day 1, always good to start nice and easy!

Solution for part two:

defmodule Aoc19.Day1b do
  @moduledoc false

  alias Aoc19.Utils.Common
  alias Aoc19.Utils.Day1, as: Day1Utils

  def start(input_location) do
    input_location
    |> Common.read_numbers()
    |> Enum.reduce(0, &fuel/2)
    |> trunc()
  end

  def fuel(0, total), do: total

  def fuel(mass, total) do
    fuel =
      mass
      |> Day1Utils.fuel()
      |> Kernel.max(0)

    fuel(fuel, total + fuel)
  end
end

And here is part one

Collapse
 
lkk2 profile image
lKk2 • Edited

Elixir way

Day 01

defmodule Day01 do
  def mass_calc([]), do: 0
  def mass_calc([ head | tail]), do: fuel(head) + mass_calc(tail)
  def fuel(mass), do: floor(mass / 3) - 2
end

Day01.mass_calc([146561, 98430, 131957, 81605, 70644, 55060, 93217, 107158, 110769, 94650, 141070, 72381, 100736, 105705, 99003, 94057, 110662, 74429, 55509, 63492, 102007, 72627, 95183, 112072, 122313, 116884, 125451, 106093, 140678, 121751, 149018, 58459, 138306, 149688, 82927, 72676, 95010, 88439, 51807, 103175, 107633, 126439, 128879, 112054, 52873, 114493, 77365, 76768, 60838, 89692, 66217, 96060, 100338, 139063, 126869, 106490, 128967, 116312, 56822, 52422, 124579, 117120, 106245, 105255, 66975, 115340, 145764, 
149427, 64228, 64237, 67887, 103345, 134901, 50226, 126991, 122314, 140818, 129687, 149792, 101148, 73411, 87078, 121272, 108804, 96063, 81155, 62058, 112684, 134263, 128454, 99455, 91689, 141448, 143892, 103257, 64352, 90769, 78307, 111855, 130153])
Collapse
 
jb_ profile image
Joshua Blewitt

This is my solution to Part 1 in Ruby - working on Part 2!

#advent of code day 1
#lets open the input file
target = File.open("input.txt")
#part 1
def calculation (file)
    total = 0
    file.each{|number|
    number = number.to_i / 3 - 2
    total += number 
    }
    puts "Our total is - #{total}"
end

calculation(target)
target.close
Collapse
 
rizzu26 profile image
Rizwan

Bit late to the party!

Here is my solution in swift. Incase anyone would like followup code can be found here in Github

func fuel(forMass mass: Int) -> Int {
    return Int((Double(mass) / 3).rounded(.down) - 2)
}

func partOne() {
    var total = 0
    input.components(separatedBy: .newlines).map{ input in
        total = total + fuel(forMass: Int(input) ?? 0)
    }
    print(total)
}

func fuel(forMass mass: Int, includesFuelMass: Bool) -> Int {
    if !includesFuelMass {
        return fuel(forMass: mass)
    }

    var currentFuel = mass
    var total = 0
    while true {
        let fuels = fuel(forMass: currentFuel)
        if fuels < 0 {
            break
        }
        currentFuel = fuels
        total = total + currentFuel
    }
    return total
}

func partTwo() {
    var total = 0
    input.components(separatedBy: .newlines).map{ input in
        total = total + fuel(forMass: Int(input) ?? 0, includesFuelMass: true)
    }
    print(total)
}

partOne()
partTwo()
Collapse
 
xgyrosx profile image
dimitri • Edited

I'm also participating this year. I want to solve everything in JS, as I'm new to web development (mostly frontend with React) on my job, too.

gitlab.com/xgyrosx/adventofcode

Part1

var fs = require("fs");
var text = fs.readFileSync("./data.txt").toString('utf-8');
var textByLine = text.split("\n");

var sum = 0;

for(i=0; i < textByLine.length; i++){
    textByLine[i] = parseInt(textByLine[i]);
    textByLine[i] = Math.floor(textByLine[i]/3)-2;
    sum += textByLine[i];
}
console.log(sum);

Part2

var fs = require("fs");
var text = fs.readFileSync("./data.txt").toString('utf-8');
var textByLine = text.split("\n");

var sum = 0;
var fuels = [];

function calculateFuel(module){
    if(module > 0) {
        module = Math.floor(module/3)-2;
        if (module > 0) {
            fuels.push(module)
        } else {
            return null;
        }
        calculateFuel(module);
    } else {
        return null;
    }
}

for(i=0; i < textByLine.length; i++){
    textByLine[i] = parseInt(textByLine[i]);
    textByLine[i] = calculateFuel(textByLine[i]);
}

for(j=0; j < fuels.length; j++){
    sum += fuels[j];
}

console.log(sum);

It took my quiet some time, especially for the file IO as there are so many approaches.

Collapse
 
lindakatcodes profile image
Linda Thompson

Hey folks - for anyone who's joined the leader board so far - I have a question!

So there are two main ways to sort our leader board, and I'm wondering which option would be best for us.

Option 1 - It counts how many people belong to the leader board (n), then the first user to get each star gets N points, the second gets N-1, and the last gets 1.

Option 2 - It counts how many stars you have, and then any ties are broken by the time you got the star. So if everyone gets all of the stars, the ones who get them the fastest are higher up.

I think either way is likely fine, but feel like maybe the star sort option might be best - it seems like it would encourage completion of the challenges more so than simply getting them done fastest, but still includes some speed needed to be higher up. Would love to hear some other thoughts on this, and whichever option seems most popular is what I'll sort it by!

Collapse
 
savagepixie profile image
SavagePixie

Same here, option 2 sounds better.

Collapse
 
jbristow profile image
Jon Bristow

In the check for 5 digits or less.

Collapse
 
avalander profile image
Avalander

I like option 2 a bit better. I'd rather see the people that manage to solve the more complicated problems at the top than those who solved the first few problems the fastest.

Collapse
 
fossheim profile image
Sarah

I joined the leaderboard, but since I'm in a EU timezone and only have time to work on them in the evenings I'm expecting my scores to be quite low 😅

Here's my solution for day 1 with Python (explained my thinking behind it here):

Part 1:

input = np.array([input])
output = np.sum(np.floor(input / 3) - 2)

Part 2:

for module in input_array:
    new_fuel = mod
    while True:
        new_fuel = np.floor(new_fuel / 3) - 2
        if new_fuel > 0:
            total_fuel += new_fuel
        else:
            break
Collapse
 
neilgall profile image
Neil Gall

Yay, Advent of Code is back. I'm not going to stick to one programming language this year, in fact I'm going to try to use lots, even some I've not used before. I'm not quite hardcore enough to do the different-language-every-day challenge however. Not this year anyway.

Day 1 in Haskell:

import Test.Hspec

load :: String -> [Int]
load = map read . lines

moduleFuel :: Int -> Int
moduleFuel mass = (mass `div` 3) - 2

fuelFuel :: Int -> Int
fuelFuel fuel = fuel + fuel' (moduleFuel fuel)
  where
    fuel' f = if f <= 0 then 0 else fuelFuel f 

part1 :: [Int] -> Int
part1 = sum . map moduleFuel

part2 :: [Int] -> Int
part2 = sum . map (fuelFuel . moduleFuel)

testModuleFuel = do
  moduleFuel 12 `shouldBe` 2
  moduleFuel 14 `shouldBe` 2
  moduleFuel 1969 `shouldBe` 654
  moduleFuel 100756 `shouldBe` 33583

testFuelFuel = do
  fuelFuel 2 `shouldBe` 2
  fuelFuel 654 `shouldBe` 966
  fuelFuel 33583 `shouldBe` 50346

test = do
  testModuleFuel
  testFuelFuel

main = do
  test
  input <- fmap load $ readFile "input.txt"
  putStrLn $ "Part 1 : " ++ (show $ part1 input)
  putStrLn $ "Part 2 : " ++ (show $ part2 input)

Once it was solved I did it again in Python just for fun:

from typing import Sequence

def load(file):
    with open(file, "rt") as f:
        return list(int(line) for line in f.readlines())

def moduleFuel(mass: int) -> int:
    return (mass // 3) - 2

def fuelFuel(mass: int) -> int:
    f = moduleFuel(mass)
    return mass + (0 if f <= 0 else fuelFuel(f))

def testModuleFuel():
    assert(moduleFuel(12) == 2)
    assert(moduleFuel(14) == 2)
    assert(moduleFuel(1969) == 654)
    assert(moduleFuel(100756) == 33583)

def testFuelFuel():
    assert(fuelFuel(2) == 2)
    assert(fuelFuel(654) == 966)
    assert(fuelFuel(33583) == 50346)


def part1(modules: Sequence[int]) -> int:
    return sum(moduleFuel(f) for f in modules)

def part2(modules: Sequence[int]) -> int:
    return sum(fuelFuel(moduleFuel(f)) for f in modules)

if __name__ == "__main__":
    testModuleFuel()
    testFuelFuel()
    input = load("input.txt")
    print(f"Part 1 : {part1(input)}")
    print(f"Part 2 : {part2(input)}")

And in the spirit of what I wrote at the top, I did it once more in Julia, my first ever code in that language. First impressions very positive and interestingly it came out shortest. I love the built-in unit testing.

using Test

load(file::AbstractString) = [parse(Int, line) for line in readlines(file)]

moduleFuel(mass::Int) = div(mass, 3) - 2

function fuelFuel(mass::Int)
  f = moduleFuel(mass)
  mass + if f <= 0 0 else fuelFuel(f) end
end

@testset "ModuleFuel" begin
  @test moduleFuel(12) == 2
  @test moduleFuel(14) == 2
  @test moduleFuel(1969) == 654
  @test moduleFuel(100756) == 33583
end

@testset "FuelFuel" begin
  @test fuelFuel(2) == 2
  @test fuelFuel(654) == 966
  @test fuelFuel(33583) == 50346
end

part1(modules) = sum(moduleFuel(m) for m in modules)

part2(modules) = sum(fuelFuel(moduleFuel(m)) for m in modules)

input = load("input.txt")
println("Part 1 : $(part1(input))")
println("Part 2 : $(part2(input))")