스도쿠의 룰에 더해, 연속된 몇몇 칸의 숫자 합이 추가 힌트로 주어지는 '킬러 스도쿠'라는 것이 있다. 세 칸의 합이 6이면 어떤 숫자가 어떤 칸에 들어가는지는 모르더라도 그 칸에는 1, 2, 3이 들어가겠구나 하고 유추할 수 있는 것이다. 이번 문제는 킬러 스도쿠를 푸는 도우미 함수를 작성하는 문제였다. 제외해야 할 숫자, 칸의 크기, 합을 입력하면 가능한 경우들을 반환해야 했다. 칸의 수가 유동적이라 리스트 컴프리헨션을 사용할 수도 없고 고민했는데, 결국 어찌어찌 재귀를 이용해 풀었다.
defmodule KillerSudokuHelper do
@doc """
Return the possible combinations of `size` distinct numbers from 1-9 excluding `exclude` that sum up to `sum`.
"""
@spec combinations(cage :: %{exclude: [integer], size: integer, sum: integer}) :: [[integer]]
def combinations(%{size: 0}), do: []
def combinations(%{sum: 0}), do: []
def combinations(%{exclude: exclude, size: 1, sum: sum}) do
if sum not in exclude, do: [[sum]], else: []
end
def combinations(cage) do
1..9
|> Enum.reject(fn i -> i in cage.exclude or i > cage.sum end)
|> Enum.flat_map(fn i ->
combinations(%{exclude: [i | cage.exclude], size: cage.size - 1, sum: cage.sum - i})
|> Enum.map(fn l -> [i | l] |> Enum.sort() end)
end)
|> Enum.uniq()
end
end
'호두나무 공방 > Exercism in Elixir' 카테고리의 다른 글
Diffie Hellman - Exercism in Elixir (0) | 2022.08.15 |
---|---|
Pascals Triangle - Exercism in Elixir (0) | 2022.07.29 |
Largest Series Product - Exercism in Elixir (0) | 2022.07.27 |
Allergies - Exercism in Elixir (0) | 2022.07.26 |
Isogram - Exercism in Elixir (0) | 2022.07.25 |