#Day 01 - Solutions

135 messages · Page 1 of 1 (latest)

granite frigate
#

Solutions thread for day 01

carmine sable
#

can i post non-go answers?

mental bear
plain ledge
#

@mental bear FYI:

    sort.Slice(elf, func(i, j int) bool {
        return elf[i] > elf[j]
    })

Can be written:

    sort.Sort(sort.Reverse(sort.IntSlice(elf)))
#

I don't really know which one is clearer

mental bear
plain ledge
hybrid ridge
#

someone post a haskell solution

bright crow
#

Unless some of them start getting longer so that dev speed between languages won’t matter as much

hybrid ridge
#

yeah of course

#

personally I will do in go because Im learning go

#

but I think the perfect languages for aoc are functional ones tbh

plain ledge
#

@bright crow they rarely have things were computing speed matter, they have many where you can get tricked into writing O(n**k) code but even writing rust wont help you against exponential complexcity

bright crow
bright crow
#

Like python is a lot faster to write up something quick than most other languages

plain ledge
#

I'm not going for speed I just like python

hybrid ridge
#

@plain ledge is there a way to avoid isolating the last append here

for scanner.Scan() {
    if scanner.Text() != "" {
        i, err := strconv.ParseInt(scanner.Text(), 10, 64)
        if err != nil {
            log.Fatal(err)
        }
        sum += i
    } else {
        calories = append(calories, sum)
        sum = 0
    }
}
if sum != 0 { // because there is no blank line at the EOF
    calories = append(calories, sum)
}
plain ledge
#

@bright crow if you are going for speed ruby is the true goat imo

bright crow
#

Nice

#

Haven’t used Ruby

plain ledge
# hybrid ridge <@183309006767521792> is there a way to avoid isolating the last append here ```...
 for scanner.Scan() {
     if scanner.Text() != "" {
         i, err := strconv.ParseInt(scanner.Text(), 10, 64)
         if err != nil {
             log.Fatal(err)
         }
         sum += i
     } else {
         calories = append(calories, sum)
         sum = 0
     }
 }
-if sum != 0 { // because there is no blank line at the EOF
-    calories = append(calories, sum)
+calories = append(calories, sum)
-}

They tell you in the excersise that it will not finish by a trailing empty new line I think

#

at least I assumed so and I got it right

#
def splitList(g, s):
    r = []
    for i in g:
        if i != s:
            r.append(i)
            continue
        yield r
        r = []
    yield r # <- see no if on that line, I just always yield
hybrid ridge
#

yes exactly thats why I had to add that last line

plain ledge
hybrid ridge
#

checking for sum just in case but its unnecessary

#

I removed it

alpine rain
near ocean
#

You don't need to sort here cause you only care about the top 3

plain ledge
near ocean
#

Not really, lower time and space complexity

plain ledge
near ocean
#

Well yes but you only need to sort 3 things instead of n things

plain ledge
#

AOC isn't about optimizing performance, it's about solving increasingly difficult problems 🙂

#

You can go ahead and try to optimize it if you want, I don't think it would be particularly intresting tho. Most of thoses problems aren't the one you need to discover more stuff to optimise.

near ocean
#

I don't care about the underlying language's speed but if there's a algorithmic better way that I see then I think it's better to do it that way

plain ledge
near ocean
#

I don't get your point really, Im just saying you don't have to sort the calories like here but only track the top 3

plain ledge
# near ocean I don't get your point really, Im just saying you don't have to sort the calorie...

no it's just that only keeping track of the top 3 is borring.
Unlike AoC, you can find other problems on internet where the creator left intresting optimizations possibility and where optimizing your code will teach you more about the problem.
IMO when you solve an AoC problem you often know about everything there is to know about this particular problem, and wont learn more intresting stuff by optimizing more.

near ocean
#

ok

#

Then don't optimise

spare hamlet
granite frigate
alpine rain
# hybrid ridge someone post a haskell solution

Here you go:

d1p1 :: [[Integer]] -> Integer
d1p1 = maximum . map sum

d1p2 :: [[Integer]] -> Integer
d1p2 = sum . lastN 3 . sort . map sum

-- From my utils
lastN :: Int -> [a] -> [a]
lastN n xs = drop (length xs - n) xs
near ocean
granite frigate
#

used some dirty awk and bash for today

#

awk 'BEGIN{FS="\n"; RS="\n\n"} {sum=0; for (i=1; i<=NF; i++){sum+=$i;}; print sum;}' input.txt| sort -rh | head -1

#

awk 'BEGIN{FS="\n"; RS="\n\n"} {sum=0; for (i=1; i<=NF; i++){sum+=$i;}; print sum;}' input.txt| sort -rh | head -3 | awk '{s+=$1} END{print s}'

#

part 1 and 2 respectively

granite frigate
plain ledge
#

I know what I should do, I should write one in LLVM ir

hard elk
#

idk why I used sprintf but whatever

celest horizon
#
open System.IO

let rec collectItems acc item = match (acc, item) with
                                | (acc, "") -> [] :: acc
                                | (head :: tail, item) -> (int item :: head) :: tail
                                | ([], item) -> [[int item]]

File.ReadLines("./01/input.txt")
|> List.ofSeq
|> List.fold(collectItems) []
|> List.map(List.sum)
|> List.sortDescending
|> List.take 3
|> List.sum
#

maybe I'll learn how F# syntax works by the end of this month

fast fulcrum
covert wigeon
hybrid ridge
fast fulcrum
hybrid ridge
#

why isnt your solution in zig tho?

fast fulcrum
hybrid ridge
#

thats the based way to go tbh

winter plaza
winter plaza
alpine rain
# granite frigate how do you do input parsing with this?

That needs some uglier code

main :: IO ()
main = do
  input <-
    map (map (fst . fromRight undefined . T.decimal) . T.lines)
      . T.splitOn (pack "\n\n")
      <$> T.readFile "01.txt"
  print $ d1p1 input
  print $ d1p2 input

d1p1 :: [[Integer]] -> Integer
d1p1 = maximum . map sum

d1p2 :: [[Integer]] -> Integer
d1p2 = sum . take 3 . sortBy (flip compare) . map sum
granite frigate
#

could do lines and map to int, then take until 0

plain ledge
rigid comet
#
print((lambda m=[0]:[m.append(m.pop()+int(i)if i[0].isdigit()else 0)for i in __import__('sys').stdin][:0]+[sum(sorted(m)[-x:])for x in(1,3)])())
```probably not ideal, but fairly concise
#

also didn't use walrus, that might help in a few cases

hybrid ridge
rigid comet
wheat dagger
#

I did something like this. Probably not efficient

from threading import Thread

with open('input.txt', 'r') as f:
    input = f.read().split("\n\n")
    Elves = list()

    def worker(Elves,elf):
        totalCalories = 0
        for calori in elf:
            totalCalories += int(calori.strip())
        Elves.append(totalCalories)

    for elf in input:
        Thread(target=worker, args=(Elves,elf.split("\n"))).start()
    result = max(Elves)
    print(result)
#

i tried multiprocessing module and it crashed my laptop

#

🤡

hard elk
#

I wonder why...

carmine sable
#
open STDIN, 'day1.txt';

$/ = "";
@x = reverse sort map { eval join $" = '+', split } <>;
print $x[0], "\n", eval "@x[0..2]";
hybrid ridge
#

I figured a rather nice solution in js but for some reason I get NaN as the first element of calories

const fs = require("fs");

let calories = fs
  .readFileSync("input", "utf8")
  .split("\n\n")
  .map((chunk) =>
    chunk
      .split("\n")
      .map((x) => Number.parseInt(x))
      .reduce((x, y) => x + y)
  )
  .sort()
  .reverse();

console.log(calories[1]);
console.log(calories[1] + calories[2] + calories[3]);
rigid comet
#

i think there may be a "" at the end, which gets turned into NaN

fast fulcrum
#

moral of the story: use typescript B)

hybrid ridge
#

how would typescript help?

fast fulcrum
rigid comet
#

not sure that applies lol

#

pretty much everything here is well typed

#

NaN is a Number, so it wouldn't fail any typechecking

#

im pretty sure at least

hybrid ridge
#

I'm suspecting its something with reduce

rigid comet
#

nah look

#

u split "1\n2\n\n3\n" on "\n\n", you get ["1\n2", "3\n"]

#

then split "3\n" on "\n", you get ["3", ""]

#

Number.parseInt("") is NaN

hybrid ridge
#

there is no "\n" at the end tho?

rigid comet
hybrid ridge
#

let me test that

#

seems like you're right lol

rigid comet
#

nice

hybrid ridge
#

are you like some sort of genius?

rigid comet
#

nah, had the same issue

hybrid ridge
#

did you also go full functional?

rigid comet
#

it's not as bad as it looks

hybrid ridge
#

it looks unreadable because its a one liner

rigid comet
#

aye lol

#

anyway add a .trim() before .split("\n")

#

should fix it

hybrid ridge
#

yeah its fixed thanks a lot

rigid comet
#

oh apparently i rewrote it lmao

#
import sys
m = [0]
for i in sys.stdin:
    i = i.strip()
    m.append(m.pop() + int(i) if i else 0)
m.sort()
print(m[-1], sum(m[-3:]))
#

ez

hybrid ridge
#

that looks so much better

rigid comet
#

trying to do 2021 day 3 now lol

#

i solved it but i feel like i could do it faster

livid bolt
#

Okay, weird question here, I completed the task and then went about trying to benchmark and optimise my solution and found a weird case: ```go
func computeCalories() int {
8 data, err := os.Open("input.txt")
9 if err != nil {
10 panic(err)
11 }
12 defer data.Close()
13
14 scanner := bufio.NewScanner(data)
15
16 valueArray := [3]int{0, 0, 0}
17 temp := 0
18 for scanner.Scan() {
19 text := scanner.Text()
20 if text != "" {
21 cals, err := strconv.Atoi(text)
22 if err != nil {
23 panic(err)
24 }
25 temp += cals
26 } else {
27 if temp < valueArray[2] {
28 goto A
29 }
30 if temp > valueArray[2] {
31 valueArray[2] = temp
32 }
33 if temp > valueArray[1] {
34 valueArray[1], valueArray[2] = valueArray[2], valueArray[1]
35 }
36 if temp > valueArray[0] {
37 valueArray[0], valueArray[1] = valueArray[1], valueArray[0]
38 }
39 A:
40 temp = 0
41 }
42 }
43 return valueArray[0] + valueArray[1] + valueArray[2]
44 }

#

but this ```go
scanner := bufio.NewScanner(data)
24
23 valueArray := [3]int{0, 0, 0}
22 temp := 0
21 for scanner.Scan() {
20 text := scanner.Text()
19 if text != "" {
18 cals, err := strconv.Atoi(text)
17 if err != nil {
16 panic(err)
15 }
14 temp += cals
13 } else {
12 switch {
11 case temp < valueArray[2]:
10 goto A
9 case temp > valueArray[2]:
8 valueArray[2] = temp
7 fallthrough
6 case temp > valueArray[1]:
5 valueArray[1], valueArray[2] = valueArray[2], valueArray[1]
4 fallthrough
3 case temp > valueArray[0]:
2 valueArray[0], valueArray[1] = valueArray[1], valueArray[0]
1 }
41 A:
1 temp = 0
2 }
3 }
4 return valueArray[0] + valueArray[1] + valueArray[2]

#

I have pored over this and can't figure why not. it looks like the comparison is not done in order!!

finite basin
#

I feel so dumb lmao, I didn't realize part 2 was basically just 1 line of code in go

#

completely forgot that you could just sort the outputs

grand pawn
#

nu

let input = (open ../input/day1.txt | lines)
let inputs = ($input | split list "" | each { |it| $it | into int })
let sums = ($inputs | each { |it| $it | math sum })

$sums | sort | reverse | first 1
$sums | sort | reverse | first 3 | math sum
#

Meh, guess I could make it DRYer

let input = (open ../input/day1.txt | lines)
let inputs = ($input | split list "" | each { |it| $it | into int })
let sums = ($inputs | each { |it| $it | math sum })

let ordered = ($sums | sort | reverse)
$ordered | first 1
$ordered | first 3 | math sum
livid bolt
#

Sorry, amended. The second (switch with fallthrough) code doesn't properly sort the elements of the array, it looks like the operations are not synchronous!!

#

Is there some weird behaviour with case and fallthrough??

plain ledge
#

@livid bolt I think this should work:

            switch {
            case temp < valueArray[0]:
                goto A
            case temp < valueArray[1]:
                valueArray[0] = temp
            case temp < valueArray[2]:
                valueArray[0], valueArray[1] = valueArray[1], temp
            default:
                valueArray[0], valueArray[1], valueArray[2] = valueArray[1], valueArray[2], temp
            }
        A:
            temp = 0
granite frigate
#

Day 01 - Solutions

eternal matrix
#
package main

import (
    "fmt"
    "log"
    "os"
    "sort"
    "strconv"
    "strings"
)

func main() {
    f, err := os.ReadFile("food.txt")
    if err != nil {
        log.Fatal(err)
    }
    var s int
    type fs2 struct {
        v int
        i int
    }
    fs := []fs2{}
    i := strings.Split(string(f), "\r\n")
    c := 0
    for j := 0; j < len(i); j++ {
        n, _ := strconv.Atoi(i[j])
        s += n
        if n == 0 {
            fs = append(fs, fs2{s, c})
            s = 0
            c++
        }
    }
    sort.Slice(fs, func(i, j int) bool {
        return fs[i].v > fs[j].v
    })
    fmt.Printf("✅ Elf %v is the best. They have %v calories", fs[0].i, fs[0].v)
}
tame dome
proud yacht
#
package main

import (
    "bufio"
    "fmt"
    "os"
    "sort"
    "strconv"
)

func main() {
    inputFile, err := os.Open("input.txt")
    if err != nil {
        fmt.Println("File reading error:", err)
        return
    }
    defer inputFile.Close()

    largestCalories := make([]int, 3)
    totalCalories := processFile(inputFile, &largestCalories)

    fmt.Println("Largest Three Elves' Calories:", largestCalories)
    fmt.Println("Total Calories:", totalCalories)
}

func processFile(file *os.File, largestCalories *[]int) int {
    scanner := bufio.NewScanner(file)
    currentCalories := 0

    for scanner.Scan() {
        line := scanner.Text()

        if line == "" {
            updateLargestCalories(currentCalories, largestCalories)
            currentCalories = 0
        } else {
            calories, err := strconv.Atoi(line)
            if err != nil {
                fmt.Println("Error converting string to int:", err)
                continue
            }
            currentCalories += calories
        }
    }

    updateLargestCalories(currentCalories, largestCalories)

    return sum(*largestCalories)
}

func updateLargestCalories(current int, largestCalories *[]int) {
    if current > (*largestCalories)[0] {
        (*largestCalories)[0] = current
        sort.Ints(*largestCalories)
    }
}

func sum(slice []int) int {
    total := 0
    for _, value := range slice {
        total += value
    }
    return total
}
hard elk
#

judgment smh posting aoc in September