sasajuric

sasajuric

Author of Elixir In Action

Note: This topic is to talk about Day 14 of the Advent of Code.

For general discussion about the Advent of Code 2018 and links to topics of the other days, see this topic.

Showing Posts 1 to 6

sasajuric

sasajuric OP

Author of Elixir In Action

Here is my solution. It takes about 50s to finish. The long running time is because I’m dynamically building an array of about 20M elements. I resorted to using ets for this, as that works faster than using plain maps. I also briefly experimented with :array and procdict, but had no luck.

Assuming there’s no smarter algorithm, and that I didn’t make some terrible mistake, it seems that this is an example of where Erlang/Elixir are simply not performant enough. If we were able to preallocate a mutable array, this would finish much faster.

bjorng

bjorng

Erlang Core Team

Here is my solution.

It takes less than 3 seconds on my computer.

I store the recipes in a binary, appending to it using the binary syntax. An append operation to a binary is specially optimized by Erlang’s runtime system, in that it will allocate extra storage when appending so that the next append operation will be cheaper. See the section about constructing binaries in the Efficiency Guide.

sasajuric

sasajuric OP

Author of Elixir In Action

Oh, using binaries is a wonderful idea! I have to adapt my code.

JEG2

JEG2

Author of Designing Elixir Systems with OTP

Here’s my Day 14 solution:

https://github.com/JEG2/advent_of_code_2018/blob/master/day_14/chocolate_charts.exs

I wrote pretty code then uglied it up for speed. I’m unsatisfied with where I ended up, needing about five minutes for part two.

Watch the process here (for 14 days):

garyharan

garyharan

Anyone here would know why my code is so slow? It times out after 60 seconds.

defmodule Day14 do
  def next_ten(iterations) when is_integer(iterations) do
    {tuple, _index1, _index2} = Day14.generate(iterations + 10)

    tuple
    |> Tuple.to_list
    |> Enum.slice(iterations, 10)
    |> Enum.join("")
  end

  def generate(iterations) when is_integer(iterations) do
    Day14.generate({{3,7}, 0, 1, iterations})
  end

  def generate({tuple, index1, index2, 0}) do
    {tuple, index1, index2}
  end

  def generate({tuple, index1, index2, iterations}) do
    elven_digits = Integer.digits(elem(tuple, index1) + elem(tuple, index2))

    tuple = Day14.append_digits_to_tuple(tuple, elven_digits)

    Day14.generate({
      tuple,
      Day14.calculate_new_index(tuple, index1),
      Day14.calculate_new_index(tuple, index2),
      iterations - 1
    })
  end

  def append_digits_to_tuple(accumulator, [head | tail]) do
    append_digits_to_tuple(Tuple.append(accumulator, head), tail)
  end

  def append_digits_to_tuple(accumulator, []) do
    accumulator
  end

  def calculate_new_index(tuple, index) do
    len       = tuple_size(tuple)
    new_index = elem(tuple, index) + 1 + index

    if new_index >= len do
      rem(new_index, len)
    else
      new_index
    end
  end
end

Day14.next_ten(880751)

Any help would be greatly appreciated! Cheers!

sasajuric

sasajuric OP

Author of Elixir In Action

My guess is that you’re spending a lot of time in Tuple.append. Day 14 requires a lot of iterations, and modifying a tuple involves copying it, which is then going to be pretty slow.

It’s somewhat tricky to get a sensible running time here. I’ve tried with various approaches, and the best I was able to come up was around 50 seconds using ETS. However, there is a way to reduce the running time to a few seconds, as explained by @bjorng earlier in this thread.

— All posts loaded —

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
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews