여러 마리의 게(그런데 이제 얘네들이 잠수함에 탄)가 있을 때, 이 게들이 최소한의 에너지로 모일 수 있는 한 점과 그 때 필요한 연료의 양을 계산하는 문제였다. 어제자 문제의 교훈이 있어서 일찌감치 Enum.frequencies
를 활용해서 계산했다.
2년 전에 처음 AoC에 도전할 때에는 너무 어려워서 힘들어했는데 이번에는 (적어도 지금까지는) 거의 모든 문제가 30분 남짓 하면 풀린다. 한 언어를 꾸준히 붙잡아 왔으니 실력이 조금은 늘었나 싶기도 한데, 그것보다 문제가 쉬워진 게 더 큰 듯. 저녁에 쉬면서 '오늘의 퍼즐' 푸는 감각으로 마음편히 할 수 있어서 개인적으로는 효능감이 느껴지는 난이도이긴 하다.
defmodule Day7 do
def parse_input do
path = "input/day7.txt"
File.read!(path)
|> String.split(",")
|> Enum.map(&String.to_integer/1)
end
@spec run_q1 :: {non_neg_integer, non_neg_integer}
def run_q1 do
crabs = parse_input() |> Enum.frequencies()
{min, max} = crabs |> Map.keys() |> Enum.min_max()
min_fuel_pos =
min..max
|> Enum.min_by(&get_fuel_q1(crabs, &1))
{min_fuel_pos, get_fuel_q1(crabs, min_fuel_pos)}
end
@spec run_q2 :: {non_neg_integer, non_neg_integer}
def run_q2 do
crabs = parse_input() |> Enum.frequencies()
{min, max} = crabs |> Map.keys() |> Enum.min_max()
min_fuel_pos =
min..max
|> Enum.min_by(&get_fuel_q2(crabs, &1))
{min_fuel_pos, get_fuel_q2(crabs, min_fuel_pos)}
end
defp get_fuel_q1(crabs, to_pos) do
crabs
|> Enum.map(fn {crab_pos, crab_count} ->
abs(crab_pos - to_pos) * crab_count
end)
|> Enum.sum()
end
defp get_fuel_q2(crabs, to_pos) do
crabs
|> Enum.map(fn {crab_pos, crab_count} ->
dist = abs(crab_pos - to_pos)
fuel_to_move = div(dist * (dist + 1), 2)
fuel_to_move * crab_count
end)
|> Enum.sum()
end
end
'호두나무 공방 > Advent of Code' 카테고리의 다른 글
Advent of Code 2021 Day 9 in Elixir - Smoke Basin (0) | 2021.12.09 |
---|---|
Advent of Code 2021 Day 8 in Elixir - Seven Segment Search (0) | 2021.12.08 |
Advent of Code 2021 Day 6 in Elixir - Lanternfish (0) | 2021.12.06 |
Advent of Code 2021 Day 5 in Elixir - Hydrothermal Venture (0) | 2021.12.06 |
Advent of Code 2021 Day 4 in Elixir - Giant Squid (0) | 2021.12.04 |