LoginSignup
7
1

闘魂Elixir ── Advent of code 2023 Day 11 Part 1 を Livebook で楽しむ

Last updated at Posted at 2023-12-29

$\huge{元氣ですかーーーーッ!!!}$
$\huge{元氣があればなんでもできる!}$

$\huge{闘魂とは己に打ち克つこと。}$
$\huge{そして闘いを通じて己の魂を磨いていく}$
$\huge{ことだと思います}$

はじめに

@torifukukaiou さんの パク リスペクト記事です

Elixir Livebook で Advent of Code 2023 の問題を解いてみます

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

問題はこちら

セットアップ

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

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

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

入力の取得

Day 11 の入力を取得します

スクリーンショット 2023-12-29 12.04.04.png

私の答え

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

details

回答用のモジュールです

入力を扱いやすい形にするための parse と、回答を作るための resolve 関数を持っています

defmodule Resolver do
  def parse(input) do
    orig_space =
      input
      |> String.split("\n")
      |> Enum.with_index()
      |> Enum.map(fn {line, row} ->
        line
        |> String.codepoints()
        |> Enum.with_index()
        |> Enum.filter(fn {cell, _} -> cell == "#" end)
        |> Enum.map(fn {_, col} -> {row, col} end)
      end)
      |> Enum.concat()
  
    max_row =
      orig_space
      |> Enum.map(fn {row, _} -> row end)
      |> Enum.max()

    max_col =
      orig_space
      |> Enum.map(fn {col, _} -> col end)
      |> Enum.max()

    empty_rows =
      0..max_row
      |> Enum.filter(fn target_row ->
        orig_space
        |> Enum.map(fn {row, _} -> row end)
        |> Enum.member?(target_row)
        |> Kernel.!()
      end)

    empty_cols =
      0..max_col
      |> Enum.filter(fn target_col ->
        orig_space
        |> Enum.map(fn {_, col} -> col end)
        |> Enum.member?(target_col)
        |> Kernel.!()
      end)

    orig_space
    |> Enum.map(fn {row, col} ->
      ex_rows = Enum.count(empty_rows, fn empty_row -> row > empty_row end)
      ex_cols = Enum.count(empty_cols, fn empty_col -> col > empty_col end)
      
      {row + ex_rows, col + ex_cols}
    end)
  end

  def resolve(space) do
    space
    |> Enum.with_index()
    |> Enum.map(fn {{src_row, src_col}, src_index} ->
      space
      |> Enum.with_index()
      |> Enum.map(fn {{dst_row, dst_col}, dst_index} ->
        if src_index >= dst_index do
          0
        else
          abs(dst_row - src_row) + abs(dst_col - src_col)
        end
      end)
      |> Enum.sum()
    end)
    |> Enum.sum()
  end
end

parse で銀河 = "#" のところだけ座標を取得します

空白行、空白列は2倍に膨らむ = 各座標は空白行、空白列を超えている分だけ加算される、という計算をして、 parse の時点で膨張後の結果を取得しています

resolve では単純に各銀河間の距離を計算し、足しています

同じ組み合わせは計算しないよう、 src_index >= dst_index の場合は 0 にしています

まとめ

Part 1 なのでここまでは簡単ですが、、、

Part 2 はどうなることか

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