packages feed

egison-3.6.0: lib/core/number.egi

;;;;;
;;;;;
;;;;; Number
;;;;;
;;;;;

;;;
;;; Natural Numbers
;;;
(define $nat
  (matcher
    {[<o> []
      {[0 {[]}]
       [_ {}]}]
     [<s $> nat
      {[$tgt (match (compare tgt 0) ordering
               {[<greater> {(- tgt 1)}]
                [_ {}]})]}]
     [,$n []
      {[$tgt (if (eq? tgt n) {[]} {})]}]
     [$ [something]
      {[$tgt {tgt}]}]
     }))

(define $nats {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 @(map (+ 100 $) nats)})

(define $nats0 {0 @nats})

(define $odds {1 @(map (+ $ 2) odds)})

(define $evens {2 @(map (+ $ 2) evens)})

(define $fibs {1 1 @(map2 + fibs (cdr fibs))})

(define $prime?
  (lambda [$n]
    (eq? n (find-factor n))))

(define $primes {2 @(filter prime? (drop 2 nats))})

(define $divisor?
  (lambda [$n $d]
    (eq? 0 (remainder n d))))

(define $find-factor
  (memoized-lambda [$n]
    (match (take-while (lte? $ (floor (sqrt (itof n)))) primes) (list integer)
      {[<join _ <cons (& ?(divisor? n $) $x) _>> x]
       [_ n]})))

(define $prime-factorization
  (match-lambda integer
    {[,1 {}]
     [(& ?(lt? $ 0) $n) {-1 @(prime-factorization (neg n))}]
     [$n (let {[$p (find-factor n)]}
           {p @(prime-factorization (quotient n p))})]}))

(define $p-f prime-factorization)

(define $even?
  (lambda [$n]
    (eq? 0 (modulo n 2))))

(define $odd?
  (lambda [$n]
    (eq? 1 (modulo n 2))))

(define $fact
  (lambda [$n]
    (foldl * 1 (between 1 n))))

(define $perm
  (lambda [$n $r]
    (foldl * 1 (between (- n (- r 1)) n))))

(define $comb
  (lambda [$n $r]
    (/ (perm n r)
       (fact r))))

(define $n-adic
  (lambda [$n $x]
    (if (eq? x 0)
      {}
      (let {[$q (quotient x n)]
            [$r (remainder x n)]}
        {@(n-adic n q) r}))))

;;;
;;; Integers
;;;
(define $mod
  (lambda [$m]
    (matcher
      {[,$n []
        {[$tgt (if (eq? (modulo tgt m) (modulo n m))
                   {[]}
                   {})]}]
       [$ [something]
        {[$tgt {tgt}]}]
       })))

;;;
;;; Floats
;;;
(define $exp2
  (lambda [$x $y]
    (exp (* (log x) y))))

;;;
;;; Decimal Fractions
;;;
(define $rtod-helper
  (lambda [$m $n]
    (let {[$q (quotient (* m 10) n)]
          [$r (remainder (* m 10) n)]}
      {[q r] @(rtod-helper r n)})))

(define $rtod
  (lambda [$x]
    (let* {[$m (numerator x)]
           [$n (denominator x)]
           [$q (quotient m n)]
           [$r (remainder m n)]}
      [q (map fst (rtod-helper r n))])))

(define $rtod'
  (lambda [$x]
    (let* {[$m (numerator x)]
           [$n (denominator x)]
           [$q (quotient m n)]
           [$r (remainder m n)]
           [[$s $c] (find-cycle (rtod-helper r n))]}
      [q (map fst s) (map fst c)])))

(define $show-decimal
  (lambda [$c $x]
    (match (2#[%1 (take c %2)] (rtod x)) [integer (list integer)]
      {[[$q $sc] (foldl S.append (S.append (show q) ".") (map show sc))]})))

(define $show-decimal'
  (lambda [$x]
    (match (rtod' x) [integer (list integer) (list integer)]
      {[[$q $s $c] (foldl S.append "" {(S.append (show q) ".") @(map show s) " " @(map show c) " ..."})]})))

;;;
;;; Continued Fraction
;;;
(define $regular-continued-fraction
  (lambda [$n $as]
    (+ n
       (foldr (lambda [$a $r] (/ 1 (+ a r)))
              0
              as))))

(define $continued-fraction
  (lambda [$n $as $bs]
    (match [as bs] [(list integer) (list integer)]
      {[[<cons $a $as> <cons $b $bs>]
        (+ n (/ b (continued-fraction a as bs)))]
       [[<nil> <nil>] n]})))

(define $regular-continued-fraction-of-sqrt-helper
  (lambda [$m $a $b] ; a+b*rt(m)
    (let* {[$n (floor (+ (rtof a) (* (rtof b) (sqrt (rtof m)))))]
           [$x (- m (power n 2))]}
      (if (eq? x 0)
        {[a b n]}
        (let {[$y (- (power (- n a) 2) (* b b m))]}
          {[a b n] @(regular-continued-fraction-of-sqrt-helper m (/ (- a n) y) (neg (/ b y)))})))))

(define $regular-continued-fraction-of-sqrt
  (lambda [$m]
    (let* {[$n (floor (sqrt (rtof m)))]
           [$x (- m (power n 2))]}
      ; n+rt(m)-n
      ; n+(rt(m)-n)*(rt(m)+n)/(rt(m)+n)
      ; n+x/(rt(m)+n)
      (if (eq? x 0)
        [n {} {}]
        [n (map 3#%3 (regular-continued-fraction-of-sqrt-helper m (/ n x) (/ 1 x)))]))))

(define $regular-continued-fraction-of-sqrt'
  (lambda [$m]
    (let* {[$n (floor (sqrt (rtof m)))]
           [$x (- m (power n 2))]}
      (if (eq? x 0)
        [n {} {}]
        (let {[[$s $c] (find-cycle (regular-continued-fraction-of-sqrt-helper m (/ n x) (/ 1 x)))]}
          [n (map 3#%3 s) (map 3#%3 c)])))))