5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 21

Advent of code 2015 Day 10 Part 1 & Part 2 を Livebook で楽しむ

Last updated at Posted at 2024-11-25

はじめに

Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます

本記事では Day 10 の Part 1 と Part 2 を解きます

問題文はこちら

実装したノートブックはこちら

セットアップ

Kino AOC をインストールします

Mix.install([
  {:kino_aoc, "~> 0.1"}
])

Kino AOC の使い方はこちらを参照

入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 10 の入力を取得します

スクリーンショット 2024-11-25 13.51.46.png

私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

Part 1

回答

正規表現 (.)\1* は1文字以上の繰り返しに該当します

Regex.scan により、これに該当するものを全て取得します

例えば "111221" を入力として、以下のように処理します

Regex.scan(~r/(.)\1*/, "111221")

実行結果は以下のようになります

[["111", "1"], ["22", "2"], ["1", "1"]]

各繰り返しについて、最も長い該当箇所と、最も短い該当箇所が返ってきます

[max, min] で取得される各繰り返しについて、 max の長さを繰り返し回数、 min を繰り返されている文字として扱えば問題を解くことができます

問題を解くための関数を定義します

get_char_group_list = fn input ->
  Regex.scan(~r/(.)\1*/, input)
  |> Enum.map(fn [max, min] ->
    "#{String.length(max)}#{min}"
  end)
  |> Enum.join()
end

試しに "111221" を入力として実行してみます

get_char_group_list.("111221")

結果は以下のように正しく返ってきます

"312211"

あとはこれを 40 回繰り返し、文字列長を取得するだけです

1..40
|> Enum.reduce(puzzle_input, fn _, acc_input ->
  get_char_group_list.(acc_input)
end)
|> String.length()

Part 2

回答

Part 2 は、まさかの繰り返し回数を増やすだけでした

1..50
|> Enum.reduce(puzzle_input, fn _, acc_input ->
  get_char_group_list.(acc_input)
end)
|> String.length()

まとめ

実は当初は文字列の繰り返しを律儀に数える実装をしていたのですが、一旦解けた後に別の解法を考えつきました

入力のパース処理はできるだけ正規表現でやった方が良いですね

5
1
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
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?