cblavier

cblavier

Advent of Code 2020 - Day 11

Hey there :wave:

CleanShot 2020-12-11 at 10.59.25@2x

No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3sec for part2).

But at least I managed to made my code readable and to reuse most of part1 for part2.

My code: part1 / part2

Most Liked

LostKobrakai

LostKobrakai

Recursion if it’s truely while do or do while:

My other goto for evaluation (does not always fit) is Stream.unfold:

cblavier

cblavier

I ended up writing a generator to create my adventofcode files for each challenge and to download the puzzle as well. You can use the code if you want to

Papey

Papey

I ended up with something nice for finding neighbours on part 2, but wow, this is veeeerryyyy slooooow (~4 seconds)

  def neighbours(current, {x, y}) do
    Enum.reduce(@dirs, 0, fn {dx, dy}, acc ->
      [v] =
        Stream.iterate(1, &(&1 + 1))
        |> Stream.map(fn mul -> {x + dx * mul, y + dy * mul} end)
        |> Stream.map(fn {xx, yy} -> Map.get(current, {xx, yy}) end)
        |> Stream.drop_while(&(&1 == @floor))
        |> Enum.take(1)

      if v == @occupied, do: acc + 1, else: acc
    end)
  end

I was thinking about the fact that the current map is RO, did someone try to add some concurrency into the mix ?

felix-alonso

felix-alonso

I think I had a similar experience today. Worked out okay, but a bit slower than I would like (~1s/~3s).

defmodule Day11 do

  defguard in_bounds(x, list) when 0 <= x and x < length(list)

  def part_1, do: solve(&by_adjacency/4)
  def part_2, do: solve(&by_visibility/4)

  def solve(method) do
    load()
    |> find_stable(method)
    |> count_occupied()
  end

  def count_occupied(seats) do
    seats
    |> Enum.map(fn row -> Enum.count(row, &(&1 == ?#)) end)
    |> Enum.sum()
  end

  def find_stable(seats, transform) do
    case next_gen(seats, transform) do
      next when next == seats -> next
      next -> find_stable(next, transform)
    end
  end

  def next_gen(seats, transform) do
    for {row, r_idx} <- Enum.with_index(seats) do
      for {seat, c_idx} <- Enum.with_index(row) do
        transform.(seats, seat, r_idx, c_idx)
      end
    end
  end

  def by_visibility(_, ?., _, _), do: ?.
  def by_visibility(seats, ?L, row, col) do
    if visible(seats, row, col) == 0, do: ?#, else: ?L
  end
  def by_visibility(seats, ?#, row, col) do
      if visible(seats, row, col) >= 5, do: ?L, else: ?#
  end

  def visible(seats, r_idx, c_idx) do
    directions()
    |> Enum.count(fn {x, y} -> next(seats, r_idx + x, c_idx + y, x, y) end)
  end

  def next(_, row, col, _, _) when row < 0 or col < 0, do: false
  def next(seats, row, col, drow, dcol) do
    case get_seat(seats, row, col) do
      ?. -> next(seats, row + drow, col + dcol, drow, dcol)
      x -> x == ?#
    end
  end

  def by_adjacency(_, ?., _, _), do: ?.
  def by_adjacency(seats, ?L, row, col) do
    if adjacent(seats, row, col) == 0, do: ?#, else: ?L
  end
  def by_adjacency(seats, ?#, row, col) do
      if adjacent(seats, row, col) >= 4, do: ?L, else: ?#
  end

  def adjacent(seats, row, col) do
    directions()
    |> Enum.count(fn {x, y} -> get_seat(seats, row + x, col + y) == ?#  end)
  end

  def directions do
    for x <- -1..1, y <- -1..1, not_origin(x, y), do: {x, y}
  end

  def not_origin(x, y), do: not(x == 0 and y == 0)

  def get_seat(seats=[fst|_], row, col)
    when in_bounds(row, seats) and in_bounds(col, fst),
    do: seats |> Enum.at(row) |> Enum.at(col) 
  def get_seat(_, _, _), do: nil

  def load do
    File.read!("day-11.input")
    |> String.split("\n", trim: true)
    |> Enum.map(&String.to_charlist/1)
  end
end

Code on github

Where Next?

Popular in Challenges Top

Qqwy
Note by the Moderators: This topic is to talk about Day 6 of the Advent of Code. For general discussion about the Advent of Code 2018 an...
New
stevensonmt
Trying to get more facility with dynamic programming concepts on Leetcode and having an issue I can’t find a way around. It’s a chutes an...
New
Aetherus
This topic is about the Advent of Code 2021 - Day 4. Thanks to @bjorng , we now have a new Private Leaderboard. The entry code is: 370...
New
Aetherus
Don’t know why the regex ~r/[\W && [^\.]]/x does not work in Elixir. It works pretty well in Ruby. Anyway, here is my solution:
New
New
bjorng
Note: This topic is to talk about Day 23 of the Advent of Code. For general discussion about the Advent of Code 2018 and links to topics...
New
bjorng
This topic is about Day 1 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums): https://adven...
New
cblavier
Hey there :wave: No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3se...
New
bjorng
Note: This topic is to talk about Day 18 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
bjorng
Here is my solution for day 1 of Advent of Code: defmodule Day01 do def part1(input) do all = parse(input) {first, second} = E...
New

Other popular topics Top

freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement