Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion _build/test/lib/list_ops/.compile.elixir
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ v2.
{<<"_build/test/lib/list_ops/ebin/Elixir.ListOps.beam">>,'Elixir.ListOps',
module,<<"lib/list_ops.ex">>,
['Elixir.Kernel'],
[],[],nil}.
[erlang],
[],nil}.
Binary file modified _build/test/lib/list_ops/ebin/Elixir.ListOps.beam
Binary file not shown.
52 changes: 52 additions & 0 deletions lib/list_ops.ex
Original file line number Diff line number Diff line change
@@ -1,2 +1,54 @@
defmodule ListOps do

def count(list), do: do_count(list, 0)

def do_count([head|tail], count), do: do_count(tail, count + 1)
def do_count([], count), do: count


def reverse(list), do: do_reverse(list, [])

def do_reverse([head|tail], result), do: do_reverse(tail, [head|result])
def do_reverse([], result), do: result


def map(list, function), do: do_map(list, function, [])

def do_map([head|tail], function, result), do: do_map(tail, function, [function.(head)|result])
def do_map([], _, result), do: reverse(result)


def filter(list, function), do: do_filter(list, function, [])

def do_filter([head|tail], function, result) do
if function.(head) do
do_filter(tail, function, [head|result])
else
do_filter(tail, function, result)
end
end
def do_filter([], _function, result), do: reverse(result)


def reduce(list, initial, function), do: do_reduce(list, initial, function)

def do_reduce([head|tail], memo, function), do: do_reduce(tail, function.(head,memo), function)
def do_reduce([], memo, _function), do: memo


def append(list1, list2), do: do_append(list1, list2, [])

def do_append([head|tail], list2, result), do: do_append(tail, list2, [head|result])
def do_append([], [head|tail], result), do: do_append([], tail, [head|result])
def do_append([], [], result), do: reverse(result)


def concat(lists), do: do_concat(lists, [])

def do_concat([[head|tail]|tail2], result), do: do_concat([tail|tail2], [head|result])
def do_concat([[],[head|tail]|tail2], result), do: do_concat([tail|tail2], [head|result])
def do_concat([[]|tail2], result), do: do_concat(tail2, result)
def do_concat([], result), do: reverse(result)


end
162 changes: 81 additions & 81 deletions test/list_ops_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -27,85 +27,85 @@ defmodule ListOpsTest do
assert ListOps.reverse(Enum.to_list(1..1_000_000)) == Enum.to_list(1_000_000..1)
end

# test "map of empty list" do
# assert ListOps.map([], &(&1+1)) == []
# end
#
# test "map of normal list" do
# assert ListOps.map([1,3,5,7], &(&1+1)) == [2,4,6,8]
# end
#
# test "map of huge list" do
# assert ListOps.map(Enum.to_list(1..1_000_000), &(&1+1)) ==
# Enum.to_list(2..1_000_001)
# end
#
# test "filter of empty list" do
# assert ListOps.filter([], &odd?/1) == []
# end
#
# test "filter of normal list" do
# assert ListOps.filter([1,2,3,4], &odd?/1) == [1,3]
# end
#
# test "filter of huge list" do
# assert ListOps.filter(Enum.to_list(1..1_000_000), &odd?/1) ==
# Enum.map(1..500_000, &(&1*2-1))
# end
#
# test "reduce of empty list" do
# assert ListOps.reduce([], 0, &(&1+&2)) == 0
# end
#
# test "reduce of normal list" do
# assert ListOps.reduce([1,2,3,4], -3, &(&1+&2)) == 7
# end
#
# test "reduce of huge list" do
# assert ListOps.reduce(Enum.to_list(1..1_000_000), 0, &(&1+&2)) ==
# Enum.reduce(1..1_000_000, 0, &(&1+&2))
# end
#
# test "reduce with non-commutative function" do
# assert ListOps.reduce([1,2,3,4], 10, fn x, acc -> acc - x end) == 0
# end
#
# test "append of empty lists" do
# assert ListOps.append([], []) == []
# end
#
# test "append of empty and non-empty list" do
# assert ListOps.append([], [1,2,3,4]) == [1,2,3,4]
# end
#
# test "append of non-empty and empty list" do
# assert ListOps.append([1,2,3,4], []) == [1,2,3,4]
# end
#
# test "append of non-empty lists" do
# assert ListOps.append([1,2,3], [4,5]) == [1,2,3,4,5]
# end
#
# test "append of huge lists" do
# assert ListOps.append(Enum.to_list(1..1_000_000), Enum.to_list(1_000_001..2_000_000)) ==
# Enum.to_list(1..2_000_000)
# end
#
# test "concat of empty list of lists" do
# assert ListOps.concat([]) == []
# end
#
# test "concat of normal list of lists" do
# assert ListOps.concat([[1,2],[3],[],[4,5,6]]) == [1,2,3,4,5,6]
# end
#
# test "concat of huge list of small lists" do
# assert ListOps.concat(Enum.map(1..1_000_000, &[&1])) ==
# Enum.to_list(1..1_000_000)
# end
#
# test "concat of small list of huge lists" do
# assert ListOps.concat(Enum.map(0..9, &Enum.to_list((&1*100_000+1)..((&1+1)*100_000)))) ==
# Enum.to_list(1..1_000_000)
# end
test "map of empty list" do
assert ListOps.map([], &(&1+1)) == []
end

test "map of normal list" do
assert ListOps.map([1,3,5,7], &(&1+1)) == [2,4,6,8]
end

test "map of huge list" do
assert ListOps.map(Enum.to_list(1..1_000_000), &(&1+1)) ==
Enum.to_list(2..1_000_001)
end

test "filter of empty list" do
assert ListOps.filter([], &odd?/1) == []
end

test "filter of normal list" do
assert ListOps.filter([1,2,3,4], &odd?/1) == [1,3]
end

test "filter of huge list" do
assert ListOps.filter(Enum.to_list(1..1_000_000), &odd?/1) ==
Enum.map(1..500_000, &(&1*2-1))
end

test "reduce of empty list" do
assert ListOps.reduce([], 0, &(&1+&2)) == 0
end

test "reduce of normal list" do
assert ListOps.reduce([1,2,3,4], -3, &(&1+&2)) == 7
end

test "reduce of huge list" do
assert ListOps.reduce(Enum.to_list(1..1_000_000), 0, &(&1+&2)) ==
Enum.reduce(1..1_000_000, 0, &(&1+&2))
end

test "reduce with non-commutative function" do
assert ListOps.reduce([1,2,3,4], 10, fn x, acc -> acc - x end) == 0
end

test "append of empty lists" do
assert ListOps.append([], []) == []
end

test "append of empty and non-empty list" do
assert ListOps.append([], [1,2,3,4]) == [1,2,3,4]
end

test "append of non-empty and empty list" do
assert ListOps.append([1,2,3,4], []) == [1,2,3,4]
end

test "append of non-empty lists" do
assert ListOps.append([1,2,3], [4,5]) == [1,2,3,4,5]
end

test "append of huge lists" do
assert ListOps.append(Enum.to_list(1..1_000_000), Enum.to_list(1_000_001..2_000_000)) ==
Enum.to_list(1..2_000_000)
end

test "concat of empty list of lists" do
assert ListOps.concat([]) == []
end

test "concat of normal list of lists" do
assert ListOps.concat([[1,2],[3],[],[4,5,6]]) == [1,2,3,4,5,6]
end

test "concat of huge list of small lists" do
assert ListOps.concat(Enum.map(1..1_000_000, &[&1])) ==
Enum.to_list(1..1_000_000)
end

test "concat of small list of huge lists" do
assert ListOps.concat(Enum.map(0..9, &Enum.to_list((&1*100_000+1)..((&1+1)*100_000)))) ==
Enum.to_list(1..1_000_000)
end
end