Skip to content

Commit 0c5a13f

Browse files
author
Ben Schmeckpeper
committed
Exercise 2.56
1 parent 21b8a71 commit 0c5a13f

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

exercise_2.56.exs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
defmodule Derivative do
2+
def of(exp, var) do
3+
cond do
4+
is_number(exp) -> 0
5+
is_var(exp) and exp == var -> 1
6+
is_var(exp) -> 0
7+
is_sum(exp) ->
8+
make_sum(
9+
of(addend(exp), var),
10+
of(augend(exp), var)
11+
)
12+
is_product(exp) ->
13+
make_sum(
14+
make_product(multiplier(exp), of(multiplicand(exp), var)),
15+
make_product(of(multiplier(exp), var), multiplicand(exp))
16+
)
17+
is_exponentiation(exp) ->
18+
make_product(
19+
make_product(exponent(exp),
20+
make_exponentiation(base(exp), exponent(exp) - 1)),
21+
of(base(exp), var)
22+
)
23+
true -> { :error }
24+
end
25+
end
26+
27+
def is_var(x), do: is_atom x
28+
29+
def make_sum(a1, 0), do: a1
30+
def make_sum(0, a2), do: a2
31+
def make_sum(a1, a2) when is_number(a1) and is_number(a2), do: a1 + a2
32+
def make_sum(a1, a2), do: [:+, a1, a2]
33+
34+
def is_sum([:+ | _]), do: true
35+
def is_sum(_), do: false
36+
37+
def addend(sum), do: hd tl sum
38+
def augend(sum), do: hd tl tl sum
39+
40+
def make_product(_, 0), do: 0
41+
def make_product(0, _), do: 0
42+
def make_product(m1, 1), do: m1
43+
def make_product(1, m2), do: m2
44+
def make_product(m1, m2) when is_number(m1) and is_number(m2), do: m1 * m2
45+
def make_product(m1, m2), do: [:*, m1, m2]
46+
47+
def is_product([:* | _]), do: true
48+
def is_product(_), do: false
49+
50+
def multiplier(p), do: hd tl p
51+
def multiplicand(p), do: hd tl tl p
52+
53+
def make_exponentiation(_, 0), do: 1
54+
def make_exponentiation(u, 1), do: u
55+
def make_exponentiation(u, n), do: [:^, u, n]
56+
57+
def is_exponentiation([:^ | _]), do: true
58+
def is_exponentiation(_), do: false
59+
60+
def base(exp), do: hd tl exp
61+
def exponent(exp), do: hd tl tl exp
62+
end
63+
64+
ExUnit.start
65+
66+
defmodule DerivativeTests do
67+
use ExUnit.Case, async: true
68+
69+
test "it can take derviatives of sums" do
70+
assert(Derivative.of([:+, :x, 3], :x) == 1)
71+
end
72+
73+
test "it can take derivatives of products" do
74+
assert(Derivative.of([:*, :x, :y], :x) == :y)
75+
end
76+
77+
test "it can do complicated stuff" do
78+
expression = [:*, [:*, :x, :y], [:+, :x, 3]]
79+
derivative = [:+, [:*, :x, :y], [:*, :y, [:+, :x, 3]]]
80+
assert(Derivative.of(expression, :x) == derivative)
81+
end
82+
83+
test "it can take derivatives of exponents" do
84+
expression = [:^, :x, 3]
85+
derivative = [:*, 3, [:^, :x, 2]]
86+
assert(Derivative.of(expression, :x) == derivative)
87+
end
88+
end

0 commit comments

Comments
 (0)