Skip to content

Instantly share code, notes, and snippets.

@DKordic
Created July 24, 2016 11:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DKordic/6016d743c4c124a1c04fc12accf7ef17 to your computer and use it in GitHub Desktop.
Save DKordic/6016d743c4c124a1c04fc12accf7ef17 to your computer and use it in GitHub Desktop.
Be rational :p .
# Just an example.
[de nop []
NIL ]
[def 'frac.min.l 'version '[2016 07 22]]
# [symbols 'frac.min.l 'pico]
[de rename [S1 S2]
[cond
[(str? S1)
(name S1 S2) ]
[(sym? S1)
(zap S1)
(name S1 S2)
[if (== S1 [setq S2 (intern S1)])
S1
(zap S2)
(intern S1) ] ]
[T
(throw 'rename S1) ] ] ]
[let L '[
num? "int?"
+ "add"
- "sub"
* "mul"
/ "div"
# % "rem"
= "eq"
<> "ne"
< "lt"
<= "le"
>= "ge"
> "gt"
bin "0b"
hex "0x"
oct "0o"
# and "then"
# or "else"
]
[while L
(rename (pop 'L) (pop 'L)) ] ]
# From [path "@lib/frac.l"]:
[de GCD [A B]
[until (=0 B)
[let M (% A B)
[setq A B B M] ] ]
(abs A) ]
[de LCM [A B]
(*/ A B (GCD A B)) ]
[de quotient [Dividend Divisor]
'(= (quotient N D)
(floor (/ N D)) )
[div [if (xor (lt0 Dividend) (lt0 Divisor)) # Result is negative?
[sub Dividend Divisor [if (lt0 Divisor) 1 -1]]
Dividend ]
Divisor ] ]
[de modulo [N D]
'(= (modulo N D)
(remainder 'quotient N D) )
[if (xor (lt0 [setq N (% N D)]) (lt0 D))
[add N D]
N ] ]
[de remainder ["div" N D]
(- N (* D ("div" N D))) ]
[de floor [F]
(quotient (numerator F) (denominator F)) ]
[de ceiling [F]
[let [N (numerator F)
D (denominator F) ]
[div [if (xor (lt0 N) (lt0 D)) # Result is negative?
[add N D [if (lt0 D) -1 1]]
N ]
D ] ] ]
[local ,round]
[de round [F]
[*/ (numerator F) (denominator F)] ]
[de truncate [F]
[div (numerator F) (denominator F)] ]
'[de fractional [F]
(- F (truncate F)) ]
[de fractional [F]
[let [D (denominator F)]
[list '/
[% (numerator F) D]
D ] ] ]
[de cmp [N1 N2]
(sgn (- E1 E2)) ]
#FixMe: These are useless!
[de = [N1 N2]
(=0 (cmp N1 N2)) ]
[de /= [E1 E2]
(not (= E1 E2)) ]
[de <= [N1 N2]
(le0 (cmp N1 N2)) ]
[de < [E1 E2]
[and (/= E1 E2) (<= E1 E2)] ]
[de > [E1 E2]
(<= E2 E1) ]
[de >= [E1 E2]
(< E2 E1) ]
[de num? .
complex? ]
[de complex? [A]
[or (== 'C# (.tag A))
(real? A) ] ]
[de real? . rational?] #FixMe: Useless!
[de rational? [A]
[or (int? A)
# (float? A)
(fraction? A) ] ]
[de fraction? [A]
(== '/ (.tag A)) ]
[de nat0? . ge0]
[de nat? . gt0]
[de neg [N]
[cond
[(int? N)
[sub N] ]
[(fraction? N)
~[nop
(/ (neg (numerator N))
(denominator N) ) ]
[list '/ [sub (cadr N)] (caddr N)] ]
[(complex? N)
[list 'C# (neg (cadr N)) (neg (caddr N))] ]
[T
(throw 'neg N) ] ] ]
[de sgn [N]
[cond
[(lt0 N)
-1 ]
[(=0 N)
0 ]
[(gt0 N)
1 ]
[(fraction? N)
(sgn (cadr N)) ]
[(complex? N)
(/ N (abs N)) ]
[T
(throw 'sgn N) ] ] ]
[local ,abs]
[de abs [N]
[cond
[(lt0 N)
[sub N] ]
[(int? N)
N ]
[(fraction? N)
[list '/ (abs (cadr N)) (caddr N)] ]
[(complex? N)
[let [R (cadr N) I (caddr N)]
(** (+ (* R R) (* I I))
(/ 1 2) ) ] ]
[T
(throw 'abs N) ] ] ]
[de inv [N]
# Very simple version.
[cond
[(=0 N)
(throw 'inv N) ]
[(rational? N)
[let [D (denominator N) N (numerator N)]
# [xchg 'N 'D]
[when (lt0 N)
[setq N [sub N] D [sub D]] ]
[if (=1 N)
D
[list '/ D N] ] ] ]
[(complex? N)
~[nop
[let [C (conjugate N)]
(/ C
(* N C) ) ] ]
[let [R (cadr N) I (caddr N) D (+ (** R 2) (** I 2))]
(C# (/ R D) (/ (neg I) D)) ] ]
[T
(throw 'inv N) ] ] ]
[de numerator [N]
[cond
[(int? N)
N ]
[(fraction? N)
(cadr N) ]
[T
(throw 'fraction? N) ] ] ]
[de denominator [N]
[cond
[(int? N)
1 ]
[(fraction? N)
(caddr N) ]
[T
(throw 'fraction? N) ] ] ]
[de * [N1 N2]
[cond
[[and (rational? N1) (rational? N2)]
[let [D1 (denominator N1)
N1 (numerator N1)
D2 (denominator N2)
N2 (numerator N2)
GCD1 (GCD N1 D2)
GCD2 (GCD N2 D1) ]
[setq
N1 (mul (div N1 GCD1)
(div N2 GCD2) )
D1 (mul (div D1 GCD2)
(div D2 GCD1) ) ]
[if (=1 D1)
N1
[list '/ N1 D1] ] ] ]
[T
[let [R1 (Re N1) I1 (Im N1)
R2 (Re N2) I2 (Im N2) ]
(C# (- (* R1 R2) (* I1 I2))
(+ (* R1 I2) (* I1 R2)) ) ] ] ] ]
[de / [N D]
(* N (inv D)) ]
[de + [N1 N2]
[cond
[[and (rational? N1) (rational? N2)]
[let [D1 (denominator N1)
N1 (numerator N1)
D2 (denominator N2)
N2 (numerator N2)
GCD1 (GCD D1 D2) ]
(/ (add (mul (div D2 GCD1) N1)
(mul [setq D1 (div D1 GCD1)] N2) )
(mul D1 D2) ) ] ]
[T
[let [R1 (Re N1) I1 (Im N1)
R2 (Re N2) I2 (Im N2) ]
(C# (+ R1 R2) (+ I1 I2)) ] ] ] ]
[de - [N1 N2]
(+ N1 (neg N2)) ]
[undef '**]
[de ** [B E]
[cond
[[eq 0 E B]
(throw '** B) ]
[(nat0? E)
[if (fraction? B)
# Assuming Fractions are already reduced, `*' will calculate GCDs for no reason.
[list '/
(** (numerator B) E)
(** (denominator B) E) ]
[let [R 1 "*" [if (int? B) 'mul '*]]
[while (nat? E)
[when (bit? 1 E)
[setq R ("*" B R)] ]
[setq
B ("*" B B)
E (>> 1 E) ] ]
R ] ] ]
[(< E 0)
(** (inv B) (neg E)) ]
[T
(throw '** E) ] ] ]
# For the lulz.
[de i .
(C# 0 1) ]
[de C# [R I]
(?! 'real? R)
(?! 'real? I)
[if (=0 I)
R
[list 'C# R I] ] ]
[de Re [N]
[if (== 'C# (.tag N))
(cadr N)
(?! 'real? N) ] ]
[de Im [N]
[if (== 'C# (.tag N))
(caddr N)
(?! 'real? N) 0 ] ]
[de conjugate [N]
(C# (Re N) (neg (Im N))) ]
# sgn abs
[de .tag [E]
[and (pair E) (car E)] ]
[de ?! ["?" A]
[if ("?" A)
A
(throw "?" A) ] ]
[de foldl [F A L]
[if L
(foldl F (F A (car L)) (cdr L))
A ] ]
[de foldr [F A L]
[if L
# (F (foldr F (car L) (cdr L)) A) # Why not this way?
(F (car L) (foldr F A (cdr L)))
A ] ]
[de n! . factoriel]
[de factoriel [N]
(?! 'nat0? N)
[if (=0 N)
1
(mul (factoriel (sub N 1)) N) ] ]
[de nPr [N R]
(div (n! N) (n! (sub N R))) ]
[de nCr [N R]
(div (nPr N R) (n! R)) ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment