diff --git a/_build/test/lib/list_ops/.compile.elixir b/_build/test/lib/list_ops/.compile.elixir index 25c25af..3eb5246 100644 --- a/_build/test/lib/list_ops/.compile.elixir +++ b/_build/test/lib/list_ops/.compile.elixir @@ -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}. diff --git a/_build/test/lib/list_ops/ebin/Elixir.ListOps.beam b/_build/test/lib/list_ops/ebin/Elixir.ListOps.beam index 7f8520c..06c4055 100644 Binary files a/_build/test/lib/list_ops/ebin/Elixir.ListOps.beam and b/_build/test/lib/list_ops/ebin/Elixir.ListOps.beam differ diff --git a/lib/list_ops.ex b/lib/list_ops.ex index 3010084..de5e0b1 100644 --- a/lib/list_ops.ex +++ b/lib/list_ops.ex @@ -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 diff --git a/test/list_ops_test.exs b/test/list_ops_test.exs index 99f06ff..db343fa 100644 --- a/test/list_ops_test.exs +++ b/test/list_ops_test.exs @@ -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