LoginSignup
0

posted at

updated at

Organization

Advent Of Code 2021 (Day 6: Lanternfish)をElixirで楽しむ

滝の音は絶えて久しくなりぬれど名こそ流れてなほ聞こえけれ

Advent Calendar 2022 107日目1の記事です。
I'm looking forward to 12/25,2022 :santa::santa_tone1::santa_tone2::santa_tone3::santa_tone4::santa_tone5:
私のAdvent Calendar 2022 一覧


はじめに

この記事は、Advent Of Code 2021 Day 6: LanternfishElixirで楽しんでみます。

スクリーンショット 2022-04-23 0.47.14.png

私はGitHubでログインしました。

私の回答

私の回答です。
今回は割とすんなり解けた気がします。
問題の意味がわかるまで英文と格闘していました。

私の回答
input = "3,4,3,1,2"

Part 1

internal_timers =
  input 
  |> String.split(",", trim: true) 
  |> Enum.map(&String.to_integer/1) 
  |> Enum.reduce(%{}, fn internal_timer, acc -> 
    Map.update(acc, internal_timer, 1, & &1 + 1)
  end)

defmodule Recursion do
  def recur(internal_timers, 0), do: internal_timers

  def recur(internal_timers, day) do
    internal_timers
    |> Enum.reduce(%{}, fn 
      {0, value}, acc -> {0, value}, acc -> Map.merge(acc, %{6 => value, 8 => value}, fn _k, v1, v2 -> v1 + v2 end)
      {internal_timer, value}, acc -> Map.update(acc, internal_timer - 1, value, & &1 + value)
    end)
    |> recur(day - 1)
  end
end


Recursion.recur(internal_timers, 80)
|> Map.values()
|> Enum.sum()

Part 2

internal_timers =
  input 
  |> String.split(",", trim: true) 
  |> Enum.map(&String.to_integer/1) 
  |> Enum.reduce(%{}, fn internal_timer, acc -> 
    Map.update(acc, internal_timer, 1, & &1 + 1)
  end)

defmodule Recursion do
  def recur(internal_timers, 0), do: internal_timers

  def recur(internal_timers, day) do
    internal_timers
    |> Enum.reduce(%{}, fn 
      {0, value}, acc -> {0, value}, acc -> Map.merge(acc, %{6 => value, 8 => value}, fn _k, v1, v2 -> v1 + v2 end)
      {internal_timer, value}, acc -> Map.update(acc, internal_timer - 1, value, & &1 + value)
    end)
    |> recur(day - 1)
  end
end


Recursion.recur(internal_timers, 256)
|> Map.values()
|> Enum.sum()

Mapを使ったのが吉でした。
当初Listを使っていたところ、ものすごく処理時間がかかっていました。
メモリもたくさんつかっていたようです。

It works!
Amazing!

後述するJosé Valimさんのお手本はとても勉強になります。
お見逃し無く!

お手本

José ValimさんがLivebook楽しまれている動画があります。
José Valimさんは、Elixirの作者です!

いきなり正解を書くわけではなく、少しずつ試しながら作っていって、リファクタしていくさまがJosé Valimさんの息遣いでみれるのでとても参考になります。
私は英語をよく聞き取れてはいませんが、コードが進化していくさまをみるのはとても勉強になります。

お手本

Part 1

input = "3,4,3,1,2"

fishes = input |> String.split(",") |> Enum.map(&String.to_integer/1)

defmodule Recursion do
  def recur(fishes) do
    recur(fishes, [])
  end

  defp recur([0 | fishes], children), do: [6 | recur(fishes, [8 | children])]
  defp recur([fish | fishes], children), do: [fish - 1 | recur(fishes, children)]
  defp recur([], children), do: Enum.reverse(children)
end

1..80
|> Enum.reduce(fishes, fn _, fishes -> Recursion.recur(fishes) end)
|> length()

Part 2

input = "3,4,3,1,2"

fishes = input |> String.split(",") |> Enum.map(&String.to_integer/1)

defmodule Recursion2 do
  def recur({day0, day1, day2, day3, day4, day5, day6, day7, day8}) do
    {day1, day2, day3, day4, day5, day6, day7 + day0, day8, day0}
  end
end

frequencies = Enum.frequencies(fishes) |> IO.inspect()
amounts = Enum.map(0..8, fn i -> frequencies[i] || 0 end) |> List.to_tuple()

1..256
|> Enum.reduce(amounts, fn _, amounts -> Recursion2.recur(amounts) end)
|> Tuple.sum()

お手本は感動です!!!
しびれます!

@kts_h さんがRubyでの実装をしてくださいました!


Wrapping up :lgtm::lgtm::lgtm::lgtm::lgtm:

Advent Of Code 2021 Day 6: LanternfishElixirで楽しんでみました。
Day 25まであるので引き続き楽しんでいきたいとおもいます。
私にとっては、Day 3、Day 4の方が難しかった印象です。

It works!
Amazing!

自分で解いてみて、なんだかイマイチだなあとおもいながら、動画をみることでJosé Valimさんに特別家庭教師をしてもらっている気に勝手になっています :sweat_smile:
海綿が水を吸うように、Elixirのイケている書き方を吸収しています。
伸びしろしかありません。

Enjoy Elixir:bangbang::bangbang::bangbang:
$\huge{Enjoy\ Elixir🚀}$

以上です。


I organize autoracex.
And I take part in NervesJP, fukuoka.ex, EDI, tokyo.ex, Pelemay.
I hope someday you'll join us.

We Are The Alchemists, my friends!


  1. @kaizen_nagoya さんの「「@e99h2121 アドベントカレンダーではありますまいか Advent Calendar 2020」の改訂版ではありますまいか Advent Calendar 2022 1日目 Most Breakthrough Generator」から着想を得て、模倣いたしました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0