3
0

More than 1 year has passed since last update.

Advent Of Code 2021 (Day 8: Seven Segment Search)をElixirで楽しむ

Last updated at Posted at 2022-04-30

めぐりあひて見しやそれともわかぬまに雲隠れにし夜はの月かな

Advent Calendar 2022 109日目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 8: Seven Segment SearchElixirで楽しんでみます。

スクリーンショット 2022-04-30 23.23.24.png

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

私の回答

私の回答です。

私の回答
input = """
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
"""

Part 1

input
|> String.split("\n", trim: true)
|> Enum.reduce([], fn s, acc ->
  [_left, right] = s
  |> String.split("|")
  |> Enum.map(& String.split(&1, " ", trim: true) |> Enum.map(fn s -> String.length(s) end))

  [right | acc]
end)
|> List.flatten
|> Enum.filter(& &1 == 2 or &1 == 4 or &1 == 3 or &1 == 7)
|> Enum.count

Part 2

defmodule Recursion do
  def recur(row) do
    recur(row, %{})
  end
  
  defp recur({[], right}, map) do
    IO.inspect map
    reversed_map = map
      |> Enum.to_list()
      |> Enum.map(fn {k, v} -> {v, k} end)
      |> Map.new()
    
    [a, b, c, d] = right |> Enum.map(& reversed_map[&1])
    1000 * a + 100 * b + 10 * c + d
  end
  
  defp recur({[head | tail], right}, map) do
    do_recur({tail, right}, head, Enum.count(head), map)
  end
  
  defp do_recur({tail, right}, head, 2, map) do
    recur({tail, right}, Map.merge(map, %{1 => head}))
  end
  
  defp do_recur({tail, right}, head, 4, map) do
    recur({tail, right}, Map.merge(map, %{4 => head}))
  end
  
  defp do_recur({tail, right}, head, 3, map) do
    recur({tail, right}, Map.merge(map, %{7 => head}))
  end
  
  defp do_recur({tail, right}, head, 7, map) do
    recur({tail, right}, Map.merge(map, %{8 => head}))
  end
  
  defp do_recur({tail, right}, head, 5, map) do
    cond do
      map[1] && MapSet.subset?(map[1], head) -> recur({tail, right}, Map.merge(map, %{3 => head}))
      map[3] && map[9] && MapSet.subset?(head, map[9]) -> recur({tail, right}, Map.merge(map, %{5 => head}))
      map[3] && map[9] && !MapSet.subset?(head, map[9]) -> recur({tail, right}, Map.merge(map, %{2 => head}))
      true -> recur({tail ++ [head], right}, map)
    end
  end
  
  defp do_recur({tail, right}, head, 6, map) do
    cond do
      map[4] && MapSet.subset?(map[4], head) -> recur({tail, right}, Map.merge(map, %{9 => head}))
      map[9] && map[5] && MapSet.subset?(map[5], head) -> recur({tail, right}, Map.merge(map, %{6 => head}))
      map[9] && map[5] && !MapSet.subset?(map[5], head) -> recur({tail, right}, Map.merge(map, %{0 => head}))
      true -> recur({tail ++ [head], right}, map)
    end
  end
end


input |> String.split("\n", trim: true) |> Enum.reduce([], fn s, acc ->
  [left, right] = s
  |> String.split("|")
  |> Enum.map(& String.split(&1, " ", trim: true) |> Enum.map(fn s -> String.codepoints(s) |> MapSet.new() end))

  [{left, right} | acc]
end)
|> Enum.map(&Recursion.recur/1)
|> Enum.sum

It works!
Amazing!

お手本

Day 8のお手本(José Valimさんの動画)があります :rocket:

お手本
input = """
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
"""

Part 1

parsed =
  input
  |> String.split([" |\n", " | ", "\n"], trim: true) 
  |> Enum.chunk_every(2) 
  |> Enum.map(fn [input, output] -> 
    {String.split(input), String.split(output)}
  end)

parsed
|> Enum.map(fn {_input, output} -> 
  Enum.count(output, &byte_size(&1) in [2, 7, 3, 4])
end)
|> Enum.sum()

Part 2

parsed =
  input
  |> String.split([" |\n", " | ", "\n"], trim: true) 
  |> Enum.chunk_every(2) 
  |> Enum.map(fn [input, output] -> 
    {input |> String.split() |> Enum.group_by(&byte_size/1, &String.to_charlist/1),
     output |> String.split() |> Enum.map(&String.to_charlist/1)}
  end)

Enum.map(parsed, fn {input, output} ->
  %{
    2 => [one],
    3 => [seven],
    4 => [four],
    5 => two_three_five,
    6 => zero_six_nine,
    7 => [eight]
  } = input

  [nine] = Enum.filter(zero_six_nine, &match?([], four -- &1))
  [zero] = Enum.filter(zero_six_nine, &match?([], seven -- &1)) -- [nine]
  [six] = Enum.filter(zero_six_nine, &match?([_], seven -- &1))

  [three] = Enum.filter(two_three_five, &match?([], seven -- &1))
  [five] = Enum.filter(two_three_five, &match?([_], six -- &1))
  [two] = two_three_five -- [three, five]

  numbers = %{
    Enum.sort(zero) => 0,
    Enum.sort(one) => 1,
    Enum.sort(two) => 2,
    Enum.sort(three) => 3,
    Enum.sort(four) => 4,
    Enum.sort(five) => 5,
    Enum.sort(six) => 6,
    Enum.sort(seven) => 7,
    Enum.sort(eight) => 8,
    Enum.sort(nine) => 9,
  }

  [d1, d2, d3, d4] = output

  numbers[Enum.sort(d1)] * 1000 + numbers[Enum.sort(d2)] * 100 +
    numbers[Enum.sort(d3)] * 10 + numbers[Enum.sort(d4)]
end)
|> Enum.sum()

美しい! 短い!


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

Advent Of Code 2021 Day 8: Seven Segment SearchElixirで楽しんでみました。
Day 25まであるので引き続き楽しんでいきたいとおもいます。

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」から着想を得て、模倣いたしました。

3
0
0

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
  3. You can use dark theme
What you can do with signing up
3
0