aboutsummaryrefslogtreecommitdiffhomepage
path: root/std/Math/Rational.bruijn
blob: e3842e7dbe0169ae667618468095de619ffb9406 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# ideas by u/DaVinci103
# MIT License, Copyright (c) 2024 Marvin Borner

# (p : q) ⇔ (1 / (q + 1))

:import std/Combinator .
:import std/Logic .
:import std/Pair .
:import std/Math N

# converts a balanced ternary number to a rational number
number→rational [0 : (+0)] ⧗ Number → Rational

:test (number→rational (+5)) ((+5.0))

# returns true if two rational numbers are equal
eq? &[[&[[N.eq? (N.mul 3 N.++0) (N.mul N.++2 1)]]]] ⧗ Rational → Rational → Boolean

…=?… eq?

:test (((+1) : (+3)) =? ((+2) : (+7))) (true)
:test ((+0.5) =? (+0.5)) (true)
:test ((+42.0) =? (+42.0)) (true)
:test ((+0.4) =? (+0.5)) (false)

# finds smallest equivalent representation of a rational number
compress &[[[(N.div 2 0) : N.--(N.div N.++1 0)] (N.gcd 1 N.++0)]] ⧗ Rational → Rational

%‣ compress

:test (%((+4) : (+1)) =? (+2.0)) (true)
:test (%((+4) : (+7)) =? (+0.5)) (true)

# adds two rational numbers
add &[[&[[p : q]]]] ⧗ Rational → Rational → Rational
	p N.add (N.mul 3 N.++0) (N.mul 1 N.++2)
	q N.add (N.mul 2 0) (N.add 2 0)

…+… add

:test ((+0.5) + (+0.5) =? (+1.0)) (true)
:test ((+1.8) + (+1.2) =? (+3.0)) (true)
:test ((-1.8) + (+1.2) =? (-0.6)) (true)

# subtracts two rational numbers
sub &[[&[[p : q]]]] ⧗ Rational → Rational → Rational
	p N.sub (N.mul 3 N.++0) (N.mul 1 N.++2)
	q N.add (N.mul 2 0) (N.add 2 0)

…-… sub

:test ((+0.5) - (+0.5) =? (+0.0)) (true)
:test ((+3.0) - (+1.8) =? (+1.2)) (true)
:test ((+1.8) - (-1.2) =? (+3.0)) (true)

# negates a rational number
negate &[[N.-1 : 0]] ⧗ Rational → Rational

-‣ negate

:test (-(+0.0) =? (+0.0)) (true)
:test (-(+4.2) =? (-4.2)) (true)
:test (-(-4.2) =? (+4.2)) (true)

# multiplies two rational numbers
mul &[[&[[p : q]]]] ⧗ Rational → Rational → Rational
	p N.mul 3 1
	q N.add (N.mul 2 0) (N.add 2 0)

…⋅… mul

:test ((+5.0) ⋅ (+5.0) =? (+25.0)) (true)
:test ((+1.8) ⋅ (+1.2) =? (+2.16)) (true)

# finds the multiplicative inverse of a rational number
invert &[[N.compare-case eq gt lt 1 (+0)]] ⧗ Rational → Rational
	eq Ω
	gt N.++0 : N.--1
	lt N.-(N.++0) : N.--(N.-1)

~‣ invert

:test (~(+0.5) =? (+2.0)) (true)
:test (~(-0.5) =? (-2.0)) (true)

# divides two rational numbers
div [[1 ⋅ ~0]] ⧗ Rational → Rational → Rational

…/… div

:test ((+8.0) / (+4.0) =? (+2.0)) (true)
:test ((+18.0) / (+12.0) =? (+1.5)) (true)

# TODO: Regression? Importing this into . won't find Q.eq? anymore

:import std/List L

# rational^number
pow-n [L.…!!… (L.iterate (mul 0) (+1.0))] ⧗ Rational → Number → Rational