|
| 1 | +defmodule MathCons do |
| 2 | + def cons(a, b), do: round(:math.pow(2, a) * :math.pow(3, b)) |
| 3 | + |
| 4 | + def car(z), do: div_count(z, 2, 0) |
| 5 | + def cdr(z), do: div_count(z, 3, 0) |
| 6 | + |
| 7 | + defp div_count(z, r, i) when rem(z, r) != 0, do: i |
| 8 | + defp div_count(z, r, i), do: div_count(div(z, r), r, i + 1) |
| 9 | + |
| 10 | + #defp car_iter(z, i) when rem(z, 2) != 0, do: i |
| 11 | + #defp car_iter(z, i), do: car_iter(div(z, 2), i + 1) |
| 12 | + |
| 13 | + #defp cdr_iter(z, i) when rem(z, 3) != 0, do: i |
| 14 | + #defp cdr_iter(z, i), do: cdr_iter(div(z, 3), i + 1) |
| 15 | +end |
| 16 | + |
| 17 | +ExUnit.start |
| 18 | + |
| 19 | +defmodule MathConsTest do |
| 20 | + use ExUnit.Case, async: true |
| 21 | + |
| 22 | + test "car returns the first element of the cons" do |
| 23 | + z = MathCons.cons 4, 9 |
| 24 | + assert MathCons.car(z) == 4 |
| 25 | + end |
| 26 | + |
| 27 | + test "car handles 0" do |
| 28 | + z = MathCons.cons 0, 9 |
| 29 | + assert MathCons.car(z) == 0 |
| 30 | + end |
| 31 | + |
| 32 | + test "cdr returns the last element of the cons" do |
| 33 | + z = MathCons.cons 4, 9 |
| 34 | + assert MathCons.cdr(z) == 9 |
| 35 | + end |
| 36 | + |
| 37 | + test "cdr handles 0" do |
| 38 | + z = MathCons.cons 4, 0 |
| 39 | + assert MathCons.cdr(z) == 0 |
| 40 | + end |
| 41 | +end |
0 commit comments