woolfred

woolfred

It is that time of the year again: Advent of Code 2022 :christmas_tree:

Day 1

Leaderboard:

Showing Posts 1 to 10

woolfred

woolfred OP

Here is my first attempt, which uses specific reduces for the task at hand: advent-of-code/elixir/lib/aoc22/day01.ex at b4357a22f3a53bb46e4a98852eef4049ab1b1ec6 · woolfred/advent-of-code · GitHub

Afterwards I refactored it a bit, which makes it less efficient for Part 1, but favours readability:
https://github.com/woolfred/advent-of-code/blob/master/elixir/lib/aoc22/day01.ex

mudasobwa

mudasobwa

Creator of Cure

Isn’t this code losing the latest elf?

- |> elem(1)
+ |> then(fn {c, e} -> [c | e] end)
woolfred

woolfred OP

Good catch! This would be the case if the last elf wouldn’t end with an empty line like the others.
But luckily this is the case and therefore the elf is also added to the elves list.

Edit:
From the specs:

Each Elf separates their own inventory from the previous Elf’s inventory (if any) by a blank line.

So @mudasobwa you are right and if the input generator would be working like this, there shouldn’t be a empty line after the last elf.

egze

egze

There is a leaderboard from last year that we can reuse. (shared with users of Erlang Forums ) /cc @bjorng

https://adventofcode.com/2022/leaderboard/private/view/370884

The entry code is:
370884-a6a71927

Arzar

Arzar

Here is my attempt

calories = File.stream!("input01") |>
Stream.map(&String.trim/1) |>
Stream.chunk_by(fn(x) -> x != "" end) |>
Stream.reject(fn(x) -> x == [""] end) |>
Enum.map(&( Enum.reduce(&1, 0, fn s, acc -> acc + String.to_integer(s) end)))

most = calories |> Enum.max
top3 = calories |> Enum.sort(:desc) |> Enum.take(3) |> Enum.sum()

It took me longer than expected, because I though Stream or Enum already have a function that split a list by token, so I spend a long time looking for it. In the end I settled on chunk_by + reject,

kwando

kwando

I used Stream.chunk_every :slight_smile:

input = File.stream!("/Users/kwando/projects/AoC2022/01/input.txt")
|> Stream.map(&String.trim/1)
|> Stream.chunk_while(
  0,
  fn 
    "", chunk ->
      {:cont, chunk, 0}
    value, chunk ->
      {:cont, String.to_integer(value) + chunk}
  end,
  fn chunk -> {:cont, chunk, 0} end
)
pesnk

pesnk

I used a very naive approach, I believe using chunk can turn out to be a better solution

Part 1

String.split(input, "\n\n")
|> Stream.map(fn(x) ->
  String.split(x)
  |> Stream.map(&String.to_integer/1)
  |> Enum.sum()
end)
|> Enum.max()

Part 2

String.split(input, "\n\n")
|> Stream.map(fn(x) ->
  String.split(x)
  |> Stream.map(&String.to_integer/1)
  |> Enum.sum()
end)
|> Enum.sort(:desc)
|> Stream.take(3)
|> Enum.sum()
weeksseth

weeksseth

Mine is similar to @pesnk. Code and blog

defmodule Day01 do
  use AOC

  def part1 do
    input(1)
    ~> String.split("\n\n")
    ~> Enum.map(fn elf ->
      elf
      ~> String.split("\n")
      ~> Enum.reduce(0, fn a, b -> String.to_integer(a) + b end)
    end)
    ~> Enum.max()
  end

  def part2 do
    input(1)
    ~> String.split("\n\n")
    ~> Enum.map(fn elf ->
      elf
      ~> String.split("\n")
      ~> Enum.reduce(0, fn a, b -> String.to_integer(a) + b end)
    end)
    ~> Enum.sort(:desc)
    ~> Enum.slice(0, 3)
    ~> Enum.reduce(0, fn a, b -> a + b end)
  end

end
Menkir

Menkir

Quickly in IEX

# elves = """
# ...
#"""

# Part 1
elves
|> String.split("\n\n")
|> Enum.map(& String.split(&1, "\n"))
|> Enum.map(fn calories ->
  calories
  |> Enum.map(& String.trim/1)
  |> Enum.reject(& &1 == "")
  |> Enum.map(& String.to_integer/1)
  |> Enum.sum
end)
|> Enum.with_index(1)
|> Enum.max(& >=/2, fn {calories, index} -> calories end)

# Part 2
elves
|> String.split("\n\n")
|> Enum.map(& String.split(&1, "\n"))
|> Enum.map(fn calories->
  calories
  |> Enum.map(& String.trim/1)
  |> Enum.reject(& &1 == "")
  |> Enum.map(& String.to_integer/1)
  |> Enum.sum
end)
|> Enum.with_index(1)
|> Enum.sort_by(fn {calories, _} -> calories end, :desc)
|> Enum.take(3)
|> Enum.map(fn {calories, _} -> calories end)
|> Enum.sum
jazzyer

jazzyer

Pretty quick one here:

  def part_one do
    @input
    |> read_file()
    # reduce instead of doing Enum.max at the end should be potentially faster
    |> Enum.reduce(0, fn l, acc ->
      sum = Enum.sum(l)
      if sum > acc, do: sum, else: acc
    end)
  end

  def part_two do
    [l, m, s | _] =
      @input
      |> read_file()
      |> Enum.map(&Enum.sum(&1))
      |> Enum.sort(:desc)

    l + m + s
  end

  defp read_file(file) do
    file
    |> File.read!()
    |> String.split("\n\n")
    |> Enum.map(fn s ->
      s |> String.split("\n", trim: true) |> Enum.map(&String.to_integer/1)
    end)
  end

Where Next? Top

Trending in Challenges Top

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews