Skip to content

Instantly share code, notes, and snippets.

@leikind
Created October 31, 2013 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leikind/7248707 to your computer and use it in GitHub Desktop.
Save leikind/7248707 to your computer and use it in GitHub Desktop.
defmodule Rain do
def count_blocks_with_water(blocks) do
Enum.map(Enum.max(blocks)..0, &(&1)) |>
Enum.reduce 0, fn(level, sum) ->
sum +
(Enum.with_index(blocks) |>
Enum.filter(fn({block, _}) ->
block >= level
end) |>
Enum.map(fn({_, idx}) ->
idx
end) |>
each_cons |>
Enum.reduce 0, fn({from, to}, accu) ->
accu + to - from - 1
end)
end
end
def each_cons(list) do
{cons, _} = List.foldl list, {[], nil}, fn
(e, {result, nil}) -> {result, e}
(e, {result, previous}) -> {[{previous, e} | result], e}
end
Enum.reverse cons
end
end
ExUnit.start
defmodule Tests do
use ExUnit.Case
# X
# XXX
test "case 1" do
assert Rain.count_blocks_with_water([1, 2, 1]) == 0
end
# XXX
# XXX
test "case 2" do
assert Rain.count_blocks_with_water([2, 2, 2]) == 0
end
# X X
# XXX
test "case 3" do
assert Rain.count_blocks_with_water([2, 1, 2]) == 1
end
# X X
# X X
test "case 4" do
assert Rain.count_blocks_with_water([2, 0, 2]) == 2
end
# X
# X
# X X
# XX X X
# X XX XXX
# XXX XXXXXXX
test "case 5" do
assert Rain.count_blocks_with_water([1, 2, 1, 0, 0, 4, 3, 1, 1, 3, 2, 6]) == 15
end
test "case 6" do
[
{[1,0,1], 1},
{[5,0,5], 5},
{[0,1,0,1,0], 1},
{[1,0,1,0], 1},
{[1,0,1,2,0,2], 3},
{[2,5,1,2,3,4,7,7,6], 10},
{[5,1,0,1], 1},
{[2,5,1,2,3,4,7,7,6,3,5], 12}
] |> Enum.each fn({result, blocks}) ->
assert Rain.count_blocks_with_water(result) == blocks
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment