Skip to content

Commit b742431

Browse files
authored
[#724] New practice exercise rational-numbers (#755)
1 parent c25ca49 commit b742431

File tree

10 files changed

+649
-0
lines changed

10 files changed

+649
-0
lines changed

config.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,22 @@
23982398
"cond"
23992399
],
24002400
"difficulty": 9
2401+
},
2402+
{
2403+
"slug": "rational-numbers",
2404+
"name": "Rational Numbers",
2405+
"uuid": "e2777a03-d890-453e-af5b-d61f60adbbf5",
2406+
"prerequisites": [
2407+
"pattern-matching",
2408+
"basics",
2409+
"integers",
2410+
"floating-point-numbers",
2411+
"guards"
2412+
],
2413+
"practices": [
2414+
"basics"
2415+
],
2416+
"difficulty": 4
24012417
}
24022418
],
24032419
"foregone": [
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Description
2+
3+
A rational number is defined as the quotient of two integers `a` and `b`, called the numerator and denominator, respectively, where `b != 0`.
4+
5+
The absolute value `|r|` of the rational number `r = a/b` is equal to `|a|/|b|`.
6+
7+
The sum of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂` is `r₁ + r₂ = a₁/b₁ + a₂/b₂ = (a₁ * b₂ + a₂ * b₁) / (b₁ * b₂)`.
8+
9+
The difference of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂` is `r₁ - r₂ = a₁/b₁ - a₂/b₂ = (a₁ * b₂ - a₂ * b₁) / (b₁ * b₂)`.
10+
11+
The product (multiplication) of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂` is `r₁ * r₂ = (a₁ * a₂) / (b₁ * b₂)`.
12+
13+
Dividing a rational number `r₁ = a₁/b₁` by another `r₂ = a₂/b₂` is `r₁ / r₂ = (a₁ * b₂) / (a₂ * b₁)` if `a₂` is not zero.
14+
15+
Exponentiation of a rational number `r = a/b` to a non-negative integer power `n` is `r^n = (a^n)/(b^n)`.
16+
17+
Exponentiation of a rational number `r = a/b` to a negative integer power `n` is `r^n = (b^m)/(a^m)`, where `m = |n|`.
18+
19+
Exponentiation of a rational number `r = a/b` to a real (floating-point) number `x` is the quotient `(a^x)/(b^x)`, which is a real number.
20+
21+
Exponentiation of a real number `x` to a rational number `r = a/b` is `x^(a/b) = root(x^a, b)`, where `root(p, q)` is the `q`th root of `p`.
22+
23+
Implement the following operations:
24+
- addition, subtraction, multiplication and division of two rational numbers,
25+
- absolute value, exponentiation of a given rational number to an integer power, exponentiation of a given rational number to a real (floating-point) power, exponentiation of a real number to a rational number.
26+
27+
Your implementation of rational numbers should always be reduced to lowest terms. For example, `4/4` should reduce to `1/1`, `30/60` should reduce to `1/2`, `12/8` should reduce to `3/2`, etc. To reduce a rational number `r = a/b`, divide `a` and `b` by the greatest common divisor (gcd) of `a` and `b`. So, for example, `gcd(12, 8) = 4`, so `r = 12/8` can be reduced to `(12/4)/(8/4) = 3/2`.
28+
29+
Assume that the programming language you are using does not have an implementation of rational numbers.
30+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"blurb": "Implement rational numbers.",
3+
"authors": [
4+
"jiegillet"
5+
],
6+
"contributors": [
7+
"angelikatyborska"
8+
],
9+
"files": {
10+
"solution": [
11+
"lib/rational_numbers.ex"
12+
],
13+
"test": [
14+
"test/rational_numbers_test.exs"
15+
],
16+
"example": [
17+
".meta/example.ex"
18+
]
19+
},
20+
"source": "Wikipedia",
21+
"source_url": "https://en.wikipedia.org/wiki/Rational_number"
22+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
defmodule RationalNumbers do
2+
@type rational :: {integer, integer}
3+
4+
@doc """
5+
Add two rational numbers
6+
"""
7+
@spec add(a :: rational, b :: rational) :: rational
8+
def add({a, b}, {c, d}), do: {a * d + c * b, b * d} |> reduce
9+
10+
@doc """
11+
Subtract two rational numbers
12+
"""
13+
@spec subtract(a :: rational, b :: rational) :: rational
14+
def subtract(a, {x, y}), do: add(a, {-x, y})
15+
16+
@doc """
17+
Multiply two rational numbers
18+
"""
19+
@spec multiply(a :: rational, b :: rational) :: rational
20+
def multiply({a, b}, {c, d}), do: {a * c, b * d} |> reduce
21+
22+
@doc """
23+
Divide two rational numbers
24+
"""
25+
@spec divide_by(num :: rational, den :: rational) :: rational
26+
def divide_by(num, {a, b}), do: multiply(num, {b, a})
27+
28+
@doc """
29+
Absolute value of a rational number
30+
"""
31+
@spec abs(a :: rational) :: rational
32+
def abs({a, b}), do: {Kernel.abs(a), Kernel.abs(b)} |> reduce
33+
34+
@doc """
35+
Exponentiation of a rational number by an integer
36+
"""
37+
@spec pow_rational(a :: rational, n :: integer) :: rational
38+
def pow_rational({a, b}, n) when n < 0, do: pow_rational({b, a}, -n)
39+
40+
def pow_rational({a, b}, n),
41+
do: {:math.pow(a, n) |> round, :math.pow(b, n) |> round} |> reduce
42+
43+
@doc """
44+
Exponentiation of a real number by a rational number
45+
"""
46+
@spec pow_real(x :: float, n :: rational) :: float
47+
def pow_real(x, {a, b}), do: :math.pow(x, a / b)
48+
49+
@doc """
50+
Reduce a rational number to its lowest terms
51+
"""
52+
@spec reduce(a :: rational) :: rational
53+
def reduce({a, b}) when b < 0, do: reduce({-a, -b})
54+
55+
def reduce({a, b}) do
56+
gcd = Integer.gcd(a, b)
57+
{div(a, gcd), div(b, gcd)}
58+
end
59+
end
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# This is an auto-generated file. Regular comments will be removed when this
2+
# file is regenerated. Regenerating will not touch any manually added keys,
3+
# so comments can be added in a "comment" key.
4+
5+
[0ba4d988-044c-4ed5-9215-4d0bb8d0ae9f]
6+
description = "Add two positive rational numbers"
7+
8+
[88ebc342-a2ac-4812-a656-7b664f718b6a]
9+
description = "Add a positive rational number and a negative rational number"
10+
11+
[92ed09c2-991e-4082-a602-13557080205c]
12+
description = "Add two negative rational numbers"
13+
14+
[6e58999e-3350-45fb-a104-aac7f4a9dd11]
15+
description = "Add a rational number to its additive inverse"
16+
17+
[47bba350-9db1-4ab9-b412-4a7e1f72a66e]
18+
description = "Subtract two positive rational numbers"
19+
20+
[93926e2a-3e82-4aee-98a7-fc33fb328e87]
21+
description = "Subtract a positive rational number and a negative rational number"
22+
23+
[a965ba45-9b26-442b-bdc7-7728e4b8d4cc]
24+
description = "Subtract two negative rational numbers"
25+
26+
[0df0e003-f68e-4209-8c6e-6a4e76af5058]
27+
description = "Subtract a rational number from itself"
28+
29+
[34fde77a-75f4-4204-8050-8d3a937958d3]
30+
description = "Multiply two positive rational numbers"
31+
32+
[6d015cf0-0ea3-41f1-93de-0b8e38e88bae]
33+
description = "Multiply a negative rational number by a positive rational number"
34+
35+
[d1bf1b55-954e-41b1-8c92-9fc6beeb76fa]
36+
description = "Multiply two negative rational numbers"
37+
38+
[a9b8f529-9ec7-4c79-a517-19365d779040]
39+
description = "Multiply a rational number by its reciprocal"
40+
41+
[d89d6429-22fa-4368-ab04-9e01a44d3b48]
42+
description = "Multiply a rational number by 1"
43+
44+
[0d95c8b9-1482-4ed7-bac9-b8694fa90145]
45+
description = "Multiply a rational number by 0"
46+
47+
[1de088f4-64be-4e6e-93fd-5997ae7c9798]
48+
description = "Divide two positive rational numbers"
49+
50+
[7d7983db-652a-4e66-981a-e921fb38d9a9]
51+
description = "Divide a positive rational number by a negative rational number"
52+
53+
[1b434d1b-5b38-4cee-aaf5-b9495c399e34]
54+
description = "Divide two negative rational numbers"
55+
56+
[d81c2ebf-3612-45a6-b4e0-f0d47812bd59]
57+
description = "Divide a rational number by 1"
58+
59+
[5fee0d8e-5955-4324-acbe-54cdca94ddaa]
60+
description = "Absolute value of a positive rational number"
61+
62+
[3cb570b6-c36a-4963-a380-c0834321bcaa]
63+
description = "Absolute value of a positive rational number with negative numerator and denominator"
64+
65+
[6a05f9a0-1f6b-470b-8ff7-41af81773f25]
66+
description = "Absolute value of a negative rational number"
67+
68+
[5d0f2336-3694-464f-8df9-f5852fda99dd]
69+
description = "Absolute value of a negative rational number with negative denominator"
70+
71+
[f8e1ed4b-9dca-47fb-a01e-5311457b3118]
72+
description = "Absolute value of zero"
73+
74+
[ea2ad2af-3dab-41e7-bb9f-bd6819668a84]
75+
description = "Raise a positive rational number to a positive integer power"
76+
77+
[8168edd2-0af3-45b1-b03f-72c01332e10a]
78+
description = "Raise a negative rational number to a positive integer power"
79+
80+
[e2f25b1d-e4de-4102-abc3-c2bb7c4591e4]
81+
description = "Raise zero to an integer power"
82+
83+
[431cac50-ab8b-4d58-8e73-319d5404b762]
84+
description = "Raise one to an integer power"
85+
86+
[7d164739-d68a-4a9c-b99f-dd77ce5d55e6]
87+
description = "Raise a positive rational number to the power of zero"
88+
89+
[eb6bd5f5-f880-4bcd-8103-e736cb6e41d1]
90+
description = "Raise a negative rational number to the power of zero"
91+
92+
[30b467dd-c158-46f5-9ffb-c106de2fd6fa]
93+
description = "Raise a real number to a positive rational number"
94+
95+
[6e026bcc-be40-4b7b-ae22-eeaafc5a1789]
96+
description = "Raise a real number to a negative rational number"
97+
98+
[9f866da7-e893-407f-8cd2-ee85d496eec5]
99+
description = "Raise a real number to a zero rational number"
100+
101+
[0a63fbde-b59c-4c26-8237-1e0c73354d0a]
102+
description = "Reduce a positive rational number to lowest terms"
103+
104+
[f87c2a4e-d29c-496e-a193-318c503e4402]
105+
description = "Reduce a negative rational number to lowest terms"
106+
107+
[3b92ffc0-5b70-4a43-8885-8acee79cdaaf]
108+
description = "Reduce a rational number with a negative denominator to lowest terms"
109+
110+
[c9dbd2e6-5ac0-4a41-84c1-48b645b4f663]
111+
description = "Reduce zero to lowest terms"
112+
113+
[297b45ad-2054-4874-84d4-0358dc1b8887]
114+
description = "Reduce an integer to lowest terms"
115+
116+
[a73a17fe-fe8c-4a1c-a63b-e7579e333d9e]
117+
description = "Reduce one to lowest terms"
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
defmodule RationalNumbers do
2+
@type rational :: {integer, integer}
3+
4+
@doc """
5+
Add two rational numbers
6+
"""
7+
@spec add(a :: rational, b :: rational) :: rational
8+
def add(a, b) do
9+
end
10+
11+
@doc """
12+
Subtract two rational numbers
13+
"""
14+
@spec subtract(a :: rational, b :: rational) :: rational
15+
def subtract(a, b) do
16+
end
17+
18+
@doc """
19+
Multiply two rational numbers
20+
"""
21+
@spec multiply(a :: rational, b :: rational) :: rational
22+
def multiply(a, b) do
23+
end
24+
25+
@doc """
26+
Divide two rational numbers
27+
"""
28+
@spec divide_by(num :: rational, den :: rational) :: rational
29+
def divide_by(num, den) do
30+
end
31+
32+
@doc """
33+
Absolute value of a rational number
34+
"""
35+
@spec abs(a :: rational) :: rational
36+
def abs(a) do
37+
end
38+
39+
@doc """
40+
Exponentiation of a rational number by an integer
41+
"""
42+
@spec pow_rational(a :: rational, n :: integer) :: rational
43+
def pow_rational(a, n) do
44+
end
45+
46+
@doc """
47+
Exponentiation of a real number by a rational number
48+
"""
49+
@spec pow_real(x :: float, n :: rational) :: float
50+
def pow_real(x, n) do
51+
end
52+
53+
@doc """
54+
Reduce a rational number to its lowest terms
55+
"""
56+
@spec reduce(a :: rational) :: rational
57+
def reduce(a) do
58+
end
59+
end
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
defmodule RationalNumbers.MixProject do
2+
use Mix.Project
3+
4+
def project do
5+
[
6+
app: :rational_numbers,
7+
version: "0.1.0",
8+
# elixir: "~> 1.8",
9+
start_permanent: Mix.env() == :prod,
10+
deps: deps()
11+
]
12+
end
13+
14+
# Run "mix help compile.app" to learn about applications.
15+
def application do
16+
[
17+
extra_applications: [:logger]
18+
]
19+
end
20+
21+
# Run "mix help deps" to learn about dependencies.
22+
defp deps do
23+
[
24+
# {:dep_from_hexpm, "~> 0.3.0"},
25+
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
26+
]
27+
end
28+
end

0 commit comments

Comments
 (0)