Making it even less readable for some reason.
This commit is contained in:
parent
8a63be7ba3
commit
0d62d145ab
1 changed files with 16 additions and 20 deletions
|
|
@ -1,35 +1,31 @@
|
||||||
defmodule Day7 do
|
defmodule Day7 do
|
||||||
def run do
|
def run do
|
||||||
lines =
|
lines =
|
||||||
File.read!("test.txt")
|
File.read!("data.txt")
|
||||||
|> String.trim()
|
|> String.trim()
|
||||||
|> String.split("\n")
|
|> String.split("\n")
|
||||||
|> Enum.map(fn l -> String.split(l, ~r{\D+}) |> Enum.map(&String.to_integer(&1)) end)
|
|> Enum.map(fn l -> String.split(l, ~r{\D+}) |> Enum.map(&String.to_integer(&1)) end)
|
||||||
|> Enum.map(fn [head | tail] -> {head, tail} end)
|
|> Enum.map(fn [head | tail] -> {head, tail} end)
|
||||||
|
|
||||||
[part1, part2] =
|
[
|
||||||
Enum.map([1, 2], fn part ->
|
[&*/2, &+/2], # part 1's operatons: * and +
|
||||||
# filter valid lines for parts 1 and 2, grab their targets, and sum them
|
[&*/2, &+/2, &("#{&1}#{&2}" |> String.to_integer())] # part 2's operatons: *, +, and concat
|
||||||
Enum.filter(lines, &valid?(&1, part)) |> Enum.map(&elem(&1, 0)) |> Enum.sum()
|
]
|
||||||
end)
|
|> Enum.map(fn ops ->
|
||||||
|
# filter valid lines for parts 1 and 2, grab their targets, and sum them
|
||||||
dbg({part1, part2})
|
Enum.filter(lines, &valid?(&1, ops)) |> Enum.map(&elem(&1, 0)) |> Enum.sum()
|
||||||
|
end)
|
||||||
|
|> Enum.map(&dbg(&1))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp valid?({total, [a, b | rest]}, part) do
|
# base case, when there are 2 operands. returns true if applying any of the ops returns the target
|
||||||
# if we're in part 1, just check a * b and a + b. in part 2, we'll also check a <> b
|
defp valid?({total, [a, b]}, ops) do
|
||||||
branches = if part == 1, do: [a * b, a + b], else: [a * b, a + b, concat(a, b)]
|
Enum.any?(ops, fn op -> op.(a, b) == total end)
|
||||||
|
|
||||||
case [a, b | rest] do
|
|
||||||
# base case is 2 elements. if any succeed, return true
|
|
||||||
[_, _] -> Enum.any?(branches, fn n -> n == total end)
|
|
||||||
# recurse by trying each branch, subbing the first 2 elements with the new combined element
|
|
||||||
[_, _ | _] -> Enum.any?(branches, &valid?({total, [&1 | rest]}, part))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp concat(a, b) do
|
# apply each operation to the first two operands, prepend and recurse
|
||||||
"#{a}#{b}" |> String.to_integer()
|
defp valid?({total, [a, b | rest]}, ops) do
|
||||||
|
Enum.any?(ops, &valid?({total, [&1.(a, b) | rest]}, ops))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue