# MIT License, Copyright (c) 2022 Marvin Borner # experimental functions; sometimes list-based; could work on any base :input std/Number :import std/List . # adds all values in list sum foldl add (+0) ⧗ (List Number) → Number ∑‣ sum :test (∑((+1) : ((+2) : {}(+3)))) ((+6)) # returns max value of list lmax foldl1 max ⧗ (List Number) → Number :test (lmax ((+1) : ((+3) : {}(+2)))) ((+3)) # returns min value of list lmin foldl1 min ⧗ (List Number) → Number :test (lmin ((+2) : ((+1) : {}(+0)))) ((+0)) # converts number to list of its digits digits z [[rec]] ⧗ Number → (List Number) rec =?0 case-end case-rec case-rec (1 (0 / (+10))) ; (0 % (+10)) case-end empty :test (digits (+0)) (empty) # list from num to num {…→…} z [[[rec]]] ⧗ Number → Number → (List Number) rec (1 =? ++0) case-end case-list case-list 1 : (2 ++1 0) case-end empty :test ({ (+0) → (+2) }) ((+0) : ((+1) : {}(+2))) # equivalent of mathematical sum function ∑…→…|… z [[[[[rec]]]]] (+0) ⧗ Number → Number → (Number → Number) → Number rec (2 =? ++1) case-end case-sum case-sum 4 (3 + (0 2)) ++2 1 0 case-end 3 :test (∑ (+1) → (+3) | ++‣) ((+9)) # multiplies all values in list product foldl mul (+1) ⧗ (List Number) → Number ∏‣ product :test (∏((+1) : ((+2) : {}(+3)))) ((+6)) # equivalent of mathematical product function ∏…→…|… z [[[[[rec]]]]] (+1) ⧗ Number → Number → (Number → Number) → Number rec (2 =? ++1) case-end case-sum case-sum 4 (3 ⋅ (0 2)) ++2 1 0 case-end 3 :test (∏ (+1) → (+3) | ++‣) ((+24)) # greatest common divisor gcd z [[[(1 =? 0) case-eq ((1 >? 0) case-gre case-les)]]] ⧗ Number → Number → Number case-eq 1 case-gre 2 (1 - 0) 0 case-les 2 1 (0 - 1) :test ((gcd (+2) (+4)) =? (+2)) (true) :test ((gcd (+10) (+5)) =? (+5)) (true) :test ((gcd (+3) (+8)) =? (+1)) (true) # power function pow […!!… (iterate (…⋅… 0) (+1))] ⧗ Number → Number → Number …**… pow :test (((+2) ** (+3)) =? (+8)) (true) # power function using ternary exponentiation (TODO: fix, wrong..) pow* z [[[rec]]] ⧗ Number → Number → Number rec =?0 case-end case-pow case-pow =?(lst 0) ³(2 1 /³0) (³(2 1 /³0) ⋅ 1) ³‣ [0 ⋅ 0 ⋅ 0] case-end (+1) # factorial function fac [∏ (+1) → 0 | i] ⧗ Number → Number :test ((fac (+3)) =? (+6)) (true) # super factorial function superfac [∏ (+1) → 0 | fac] ⧗ Number → Number :test ((superfac (+4)) =? (+288)) ([[1]]) # hyper factorial function hyperfac [∏ (+1) → 0 | [0 ** 0]] ⧗ Number → Number :test ((hyperfac (+2)) =? (+4)) (true) :test ((hyperfac (+3)) =? (+108)) (true) :test ((hyperfac (+4)) =? (+27648)) ([[1]]) # alternate factorial function altfac y [[=?0 0 ((fac 0) - (1 --0))]] :test ((altfac (+3)) =? (+5)) ([[1]]) # exponential factorial function expfac y [[(0 =? (+1)) 0 (0 ** (1 --0))]] :test ((expfac (+4)) =? (+262144)) ([[1]]) # inverse factorial function invfac y [[[compare-case 1 (2 ++1 0) (-1) 0 (∏ (+0) → --1 | ++‣)]]] (+0) :test ((invfac (+1)) =? (+0)) ([[1]]) :test ((invfac (+2)) =? (+2)) ([[1]]) :test ((invfac (+120)) =? (+5)) ([[1]]) :test ((invfac (+119)) =? (-1)) ([[1]]) # calculates a powertower # also: [[foldr pow (+1) (replicate 0 1)]] powertower z [[[rec]]] ⧗ Number → Number → Number rec =?0 case-end case-rec case-end (+1) case-rec 1 ** (2 1 --0) :test ((powertower (+2) (+1)) =? (+2)) (true) :test ((powertower (+2) (+2)) =? (+4)) (true) :test ((powertower (+2) (+3)) =? (+16)) (true) :test ((powertower (+2) (+4)) =? (+65536)) (true) # knuth's up-arrow notation # arrow count → base → exponent arrow z [[[[rec]]]] ⧗ Number → Number → Number → Number rec =?2 case-end case-rec case-end 1 ⋅ 0 case-rec foldr (3 --2) 1 (replicate --0 1) :test ((arrow (+1) (+1) (+1)) =? (+1)) (true) :test ((arrow (+1) (+2) (+4)) =? (+16)) (true) :test ((arrow (+2) (+2) (+4)) =? (+65536)) (true) # fibonacci sequence # TODO: faster fib? fibs head <$> (iterate [~0 : (^0 + ~0)] ((+0) : (+1))) ⧗ (List Number) fib [fibs !! ++0] ⧗ Number :test (fib (+5)) ((+8)) # floored integer square root using Babylonian method sqrt [z [[[[rec]]]] (+1) 0 0] ⧗ Number → Number rec (1 >? 2) case-rec case-end case-rec [4 (1 / 0) 0 1] /²(2 + 1) case-end 1 :test ((sqrt (+0)) =? (+0)) (true) :test ((sqrt (+1)) =? (+1)) (true) :test ((sqrt (+2)) =? (+1)) (true) :test ((sqrt (+5)) =? (+2)) (true) :test ((sqrt (+9)) =? (+3)) (true) # integer logarithm log z [[[[rec]]]] (+1) ⧗ Number → Number → Number rec [((3 ≤? 1) ⋀? (1