blob: e72b6a95b49fb3b1a50a1fdc239cb8610727cffd (
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# ideas by u/DaVinci103
# MIT License, Copyright (c) 2024 Marvin Borner
# (p : q) ⇔ (1 / (q + 1))
:import std/Logic .
: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)
reduce [[[(N.div 2 0) : N.--(N.div 1 0)] (N.gcd 1 0)]]
add' &[[&[[reduce p q]]]]
p N.add (N.mul 3 N.++0) (N.mul 1 N.++2)
q N.mul N.++0 N.++2
# 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)
gt? &[[&[[(N.gt? 1 3) ⋀? (N.gt? 0 2)]]]]
lt? &[[&[[(N.lt? 1 3) ⋀? (N.lt? 0 2)]]]]
# increments a rational number
inc add (+1.0) ⧗ Rational → Rational
++‣ inc
# decrements a rational number
dec \sub (+1.0) ⧗ Rational → Rational
--‣ dec
# TODO: Regression? Importing this into . won't find Q.eq? anymore
:import std/List L
# power function: rational^number
pow-n [L.nth-iterate (mul 0) (+1.0)] ⧗ Rational → Number → Rational
|