aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarvin Borner2024-03-03 15:03:41 +0100
committerMarvin Borner2024-03-03 22:29:24 +0100
commit6ae44d09faa0ae353c0818705503cad42127d102 (patch)
treea923d00d520f85a608f51416184e5b3b6f178549
parent03155d6e515c76d5ab59f814592484c849313130 (diff)
Even more samples
wtf
-rw-r--r--docs/wiki_src/coding/examples.md3
-rw-r--r--samples/aoc/2016/01/solve.bruijn2
-rw-r--r--samples/aoc/2017/01/solve.bruijn2
-rw-r--r--samples/aoc/2018/01/solve.bruijn2
-rw-r--r--samples/aoc/2019/01/solve.bruijn2
-rw-r--r--samples/aoc/2020/01/solve.bruijn2
-rw-r--r--samples/aoc/2021/01/solve.bruijn2
-rw-r--r--samples/aoc/2022/01/solve.bruijn2
-rw-r--r--samples/aoc/2023/01/solve.bruijn2
-rw-r--r--samples/fun/thue-morse.bruijn2
-rw-r--r--samples/rosetta/99_bottles_of_beer.bruijn15
-rw-r--r--samples/rosetta/a+b.bruijn6
-rw-r--r--samples/rosetta/balanced_ternary.bruijn100
-rw-r--r--samples/rosetta/binary_search.bruijn20
-rw-r--r--samples/rosetta/comments.bruijn1
-rw-r--r--samples/rosetta/fibonacci_sequence.bruijn20
-rw-r--r--samples/rosetta/fizzbuzz.bruijn11
-rw-r--r--samples/rosetta/hamming_numbers.bruijn28
-rw-r--r--samples/rosetta/loops_infinite.bruijn4
-rw-r--r--samples/rosetta/palindrome_detection.bruijn6
-rw-r--r--samples/rosetta/test_a_function.bruijn6
-rw-r--r--samples/rosetta/variadic_fixed-point_combinator.bruijn22
-rw-r--r--samples/rosetta/y_combinator.bruijn15
-rw-r--r--src/Helper.hs4
-rw-r--r--std/Math.bruijn2
-rw-r--r--std/Number/Binary.bruijn2
-rw-r--r--std/Number/Ternary.bruijn10
-rw-r--r--std/Option.bruijn2
-rw-r--r--std/String.bruijn15
29 files changed, 280 insertions, 30 deletions
diff --git a/docs/wiki_src/coding/examples.md b/docs/wiki_src/coding/examples.md
index f4d0b62..7303fef 100644
--- a/docs/wiki_src/coding/examples.md
+++ b/docs/wiki_src/coding/examples.md
@@ -1,5 +1,8 @@
# Examples
+You can find a lot more examples on [Rosetta
+code](https://rosettacode.org/wiki/Category:Bruijn).
+
## Hello world!
Hello world using [lists](../coding/data-structures.md#lists-stdlist)
diff --git a/samples/aoc/2016/01/solve.bruijn b/samples/aoc/2016/01/solve.bruijn
index 525d311..efdaaaa 100644
--- a/samples/aoc/2016/01/solve.bruijn
+++ b/samples/aoc/2016/01/solve.bruijn
@@ -7,7 +7,7 @@
:import std/Number .
:import std/List .
-direction! [^0 : (S.number! ~0)] ⧗ (List Char) → Direction
+direction! [^0 : (S.string→number ~0)] ⧗ (List Char) → Direction
:test (direction! "R42") ('R' : (+42))
diff --git a/samples/aoc/2017/01/solve.bruijn b/samples/aoc/2017/01/solve.bruijn
index dac0ed6..db29872 100644
--- a/samples/aoc/2017/01/solve.bruijn
+++ b/samples/aoc/2017/01/solve.bruijn
@@ -19,5 +19,5 @@ part2 [(sum ∘ eqs ∘ pairs) 0]
:test (part1 ((+1) : ((+1) : ((+2) : {}(+2))))) ((+3))
main [parts nums]
- nums C.number! <$> ^(lines 0)
+ nums C.char→number <$> ^(lines 0)
parts [(part1 0) : (part2 0)]
diff --git a/samples/aoc/2018/01/solve.bruijn b/samples/aoc/2018/01/solve.bruijn
index cb47892..0fd0448 100644
--- a/samples/aoc/2018/01/solve.bruijn
+++ b/samples/aoc/2018/01/solve.bruijn
@@ -11,5 +11,5 @@ part2 z [[[[rec]]]] S.empty (+0) ⧗ (List FrequencyDiff) → Frequency
case-end 1
main [parts nums]
- nums signed-number! <$> (init (lines 0))
+ nums string→signed-number <$> (init (lines 0))
parts [(part1 0) : (part2 (cycle 0))]
diff --git a/samples/aoc/2019/01/solve.bruijn b/samples/aoc/2019/01/solve.bruijn
index 518d198..3ec99ac 100644
--- a/samples/aoc/2019/01/solve.bruijn
+++ b/samples/aoc/2019/01/solve.bruijn
@@ -23,5 +23,5 @@ part1 ∑‣ ∘ (map fuel) ⧗ (List Mass) → Fuel
part2 ∑‣ ∘ (map fuelfuel) ⧗ (List Mass) → Fuel
main [parts nums]
- nums number! <$> ~(<~>(lines 0))
+ nums string→number <$> ~(<~>(lines 0))
parts [(part1 0) : (part2 0)]
diff --git a/samples/aoc/2020/01/solve.bruijn b/samples/aoc/2020/01/solve.bruijn
index 39bfcbc..7e4c0d2 100644
--- a/samples/aoc/2020/01/solve.bruijn
+++ b/samples/aoc/2020/01/solve.bruijn
@@ -18,5 +18,5 @@ part2 z [[rec]]
case-cont 1 ~0
main [parts nums]
- nums number! <$> ~(<~>(lines 0))
+ nums string→number <$> ~(<~>(lines 0))
parts [(part1 (cross 0 0)) : (part2 (cross3 0 0 0))]
diff --git a/samples/aoc/2021/01/solve.bruijn b/samples/aoc/2021/01/solve.bruijn
index d48acff..1c14b3b 100644
--- a/samples/aoc/2021/01/solve.bruijn
+++ b/samples/aoc/2021/01/solve.bruijn
@@ -6,7 +6,7 @@ part1 [{ [[(1 <? 0) (+1) (+0)]] | 0 , ~0 }]
part2 [{ [[(1 <? 0) (+1) (+0)]] | 0 , ~(~(~0)) }]
main [parts nums]
- nums number! <$> (lines 0)
+ nums string→number <$> (lines 0)
parts [∑(part1 0) : ∑(part2 0)]
# equivalent alternative using std/Pair P
diff --git a/samples/aoc/2022/01/solve.bruijn b/samples/aoc/2022/01/solve.bruijn
index 94b4cf7..7b2eaf6 100644
--- a/samples/aoc/2022/01/solve.bruijn
+++ b/samples/aoc/2022/01/solve.bruijn
@@ -2,7 +2,7 @@
:import std/String .
main [answer]
- numbers number! <$> (lines 0)
+ numbers string→number <$> (lines 0)
parts split-list-by =?‣ numbers
sums sum <$> parts
answer build (sort-desc sums)
diff --git a/samples/aoc/2023/01/solve.bruijn b/samples/aoc/2023/01/solve.bruijn
index 5fdfa88..74361a2 100644
--- a/samples/aoc/2023/01/solve.bruijn
+++ b/samples/aoc/2023/01/solve.bruijn
@@ -2,6 +2,6 @@
:import std/String .
:import std/Char C
-part1 [[^0 ⋅ (+10) + _0] (filter (gre? (+9)) (C.number! <$> 0))]
+part1 [[^0 ⋅ (+10) + _0] (filter (gre? (+9)) (C.char→number <$> 0))]
main [∑(part1 <$> (lines 0))]
diff --git a/samples/fun/thue-morse.bruijn b/samples/fun/thue-morse.bruijn
index 3f40e01..83e93fe 100644
--- a/samples/fun/thue-morse.bruijn
+++ b/samples/fun/thue-morse.bruijn
@@ -5,6 +5,6 @@
:import std/Logic .
:import std/String .
-main [take (number! 0) tm]
+main [take (string→number 0) tm]
xpd z [[[[0 2 [0 [[5 0 1]] (2 4)]]]]]
tm z [xpd true (0 false)]
diff --git a/samples/rosetta/99_bottles_of_beer.bruijn b/samples/rosetta/99_bottles_of_beer.bruijn
index 7ff3371..afaffdd 100644
--- a/samples/rosetta/99_bottles_of_beer.bruijn
+++ b/samples/rosetta/99_bottles_of_beer.bruijn
@@ -2,11 +2,10 @@
:import std/Number .
:import std/String .
-main y [[rec]] (+99)
- rec =?0 case-end case-rec
- case-rec n ++ t1 ++ n ++ t2 ++ t3 ++ n ++ t1 ++ "\n" ++ (1 --0)
- n number→string 0
- t1 " bottles of beer on the wall\n"
- t2 " bottles of beer\n"
- t3 "Take one down, pass it around\n"
- case-end empty
+main [y [[=?0 case-end case-rec]] (+99)]
+ case-rec n ++ t1 ++ n ++ t2 ++ t3 ++ n ++ t1 ++ "\n" ++ (1 --0)
+ n number→string 0
+ t1 " bottles of beer on the wall\n"
+ t2 " bottles of beer\n"
+ t3 "Take one down, pass it around\n"
+ case-end empty
diff --git a/samples/rosetta/a+b.bruijn b/samples/rosetta/a+b.bruijn
new file mode 100644
index 0000000..e6be660
--- /dev/null
+++ b/samples/rosetta/a+b.bruijn
@@ -0,0 +1,6 @@
+:import std/Combinator .
+:import std/String .
+:import std/Number .
+:import std/Char C
+
+main (split-by (C.eq? ' ')) → &(add ⋔ string→number)
diff --git a/samples/rosetta/balanced_ternary.bruijn b/samples/rosetta/balanced_ternary.bruijn
new file mode 100644
index 0000000..5f7aa99
--- /dev/null
+++ b/samples/rosetta/balanced_ternary.bruijn
@@ -0,0 +1,100 @@
+:import std/Combinator .
+:import std/Logic .
+:import std/Pair .
+
+# negative trit indicating coefficient of (-1)
+t⁻ [[[2]]]
+
+# positive trit indicating coefficient of (+1)
+t⁺ [[[1]]]
+
+# zero trit indicating coefficient of 0
+t⁰ [[[0]]]
+
+# shifts a negative trit into a balanced ternary number
+↑⁻‣ [[[[[2 (4 3 2 1 0)]]]]]
+
+# shifts a positive trit into a balanced ternary number
+↑⁺‣ [[[[[1 (4 3 2 1 0)]]]]]
+
+# shifts a zero trit into a balanced ternary number
+↑⁰‣ [[[[[0 (4 3 2 1 0)]]]]]
+
+# shifts a specified trit into a balanced ternary number
+…↑… [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]]
+
+# negates a balanced ternary number
+-‣ [[[[[4 3 1 2 0]]]]]
+
+# increments a balanced ternary number (can introduce leading 0s)
+++‣ [~(0 z a⁻ a⁺ a⁰)]
+ z (+0) : (+1)
+ a⁻ &[[↑⁻1 : ↑⁰1]]
+ a⁺ &[[↑⁺1 : ↑⁻0]]
+ a⁰ &[[↑⁰1 : ↑⁺1]]
+
+# decrements a balanced ternary number (can introduce leading 0s)
+--‣ [~(0 z a⁻ a⁺ a⁰)]
+ z (+0) : (-1)
+ a⁻ &[[↑⁻1 : ↑⁺0]]
+ a⁺ &[[↑⁺1 : ↑⁰1]]
+ a⁰ &[[↑⁰1 : ↑⁻1]]
+
+# converts the normal balanced ternary representation into abstract form
+→^‣ [0 z a⁻ a⁺ a⁰]
+ z (+0)
+ a⁻ [[[[[2 4]]]]]
+ a⁺ [[[[[1 4]]]]]
+ a⁰ [[[[[0 4]]]]]
+
+# converts the abstracted balanced ternary representation back to normal
+→_‣ y [[0 z a⁻ a⁺ a⁰]]
+ z (+0)
+ a⁻ [↑⁻(2 0)]
+ a⁺ [↑⁺(2 0)]
+ a⁰ [↑⁰(2 0)]
+
+# adds two balanced ternary numbers (can introduce leading 0s)
+…+… [[[c (0 z a⁻ a⁺ a⁰)] 1 →^0]]
+ b⁻ [1 ↑⁺(3 0 t⁻) ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁰)]
+ b⁰ [1 ↑ (3 0 t⁰)]
+ b⁺ [1 ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁺) ↑⁺(3 0 t⁰)]
+ a⁻ [[[1 (b⁻ 1) b⁻' b⁰ b⁻]]]
+ b⁻' [1 ↑⁰(3 0 t⁻) ↑⁻(3 0 t⁰) ↑⁺(3 0 t⁻)]
+ a⁺ [[[1 (b⁺ 1) b⁰ b⁺' b⁺]]]
+ b⁺' [1 ↑⁺(3 0 t⁰) ↑⁰(3 0 t⁺) ↑⁻(3 0 t⁺)]
+ a⁰ [[[1 (b⁰ 1) b⁻ b⁺ b⁰]]]
+ z [[0 --(→_1) ++(→_1) →_1]]
+ c [[1 0 t⁰]]
+
+# subtracts two balanced ternary numbers (can introduce leading 0s)
+…-… [[1 + -0]]
+
+# multiplicates two balanced ternary numbers (can introduce leading 0s)
+…⋅… [[1 z a⁻ a⁺ a⁰]]
+ z (+0)
+ a⁻ [↑⁰0 - 1]
+ a⁺ [↑⁰0 + 1]
+ a⁰ [↑⁰0]
+
+# true if balanced ternary number is zero
+=?‣ [0 true [false] [false] i]
+
+# true if two balanced ternary numbers are equal
+# → ignores leading 0s!
+…=?… [[[0 z a⁻ a⁺ a⁰] 1 →^0]]
+ z [=?(→_0)]
+ a⁻ [[0 false [2 0] [false] [false]]]
+ a⁺ [[0 false [false] [2 0] [false]]]
+ a⁰ [[0 (1 0) [false] [false] [2 0]]]
+
+main [[0]]
+
+# --- tests/examples ---
+
+:test ((-42) + (-1) =? (-43)) (true)
+:test ((+1) + (+2) =? (+3)) (true)
+:test ((-42) - (-1) =? (-41)) (true)
+:test ((+1) - (+2) =? (-1)) (true)
+:test ((-1) ⋅ (+42) =? (-42)) (true)
+:test ((+3) ⋅ (+11) =? (+33)) (true)
diff --git a/samples/rosetta/binary_search.bruijn b/samples/rosetta/binary_search.bruijn
new file mode 100644
index 0000000..87f01ba
--- /dev/null
+++ b/samples/rosetta/binary_search.bruijn
@@ -0,0 +1,20 @@
+:import std/Combinator .
+:import std/Math .
+:import std/List .
+:import std/Option .
+
+binary-search [y [[[[[2 <? 3 none go]]]]] (+0) --(∀0) 0]
+ go [compare-case eq lt gt (2 !! 0) 1] /²(3 + 2)
+ eq some 0
+ lt 5 4 --0 2 1
+ gt 5 ++0 3 2 1
+
+# example using sorted list of x^3, x=[-50,50]
+find [[map-or "not found" [0 : (1 !! 0)] (binary-search 0 1)] lst]
+ lst take (+100) ((\pow (+3)) <$> (iterate ++‣ (-50)))
+
+:test (find (+100)) ("not found")
+:test ((head (find (+125))) =? (+55)) ([[1]])
+:test ((head (find (+117649))) =? (+99)) ([[1]])
+
+main [[0]]
diff --git a/samples/rosetta/comments.bruijn b/samples/rosetta/comments.bruijn
new file mode 100644
index 0000000..7dd15c1
--- /dev/null
+++ b/samples/rosetta/comments.bruijn
@@ -0,0 +1 @@
+# This is a comment
diff --git a/samples/rosetta/fibonacci_sequence.bruijn b/samples/rosetta/fibonacci_sequence.bruijn
new file mode 100644
index 0000000..d2e4752
--- /dev/null
+++ b/samples/rosetta/fibonacci_sequence.bruijn
@@ -0,0 +1,20 @@
+:import std/Combinator .
+:import std/Math .
+:import std/List .
+
+# unary/Church fibonacci (moderately fast but very high space complexity)
+fib-unary [0 [[[2 0 [2 (1 0)]]]] k i]
+
+:test (fib-unary (+6u)) ((+8u))
+
+# ternary fibonacci using infinite list iteration (very fast)
+fib-list \index fibs
+ fibs head <$> (iterate &[[0 : (1 + 0)]] ((+0) : (+1)))
+
+:test (fib-list (+6)) ((+8))
+
+# recursive fib (very slow)
+fib-rec y [[0 <? (+1) (+0) (0 <? (+2) (+1) rec)]]
+ rec (1 --0) + (1 --(--0))
+
+:test (fib-rec (+6)) ((+8))
diff --git a/samples/rosetta/fizzbuzz.bruijn b/samples/rosetta/fizzbuzz.bruijn
new file mode 100644
index 0000000..7f61704
--- /dev/null
+++ b/samples/rosetta/fizzbuzz.bruijn
@@ -0,0 +1,11 @@
+:import std/Combinator .
+:import std/String .
+:import std/Number .
+
+main [y [[0 =? (+101) case-end case-rec]] (+1)]
+ case-rec str ++ "\n" ++ (1 ++0)
+ str fizzbuzz "FizzBuzz" (fizz "Fizz" (buzz "Buzz" (number→string 0)))
+ fizz =?(0 % (+3))
+ buzz =?(0 % (+5))
+ fizzbuzz fizz buzz fizz
+ case-end empty
diff --git a/samples/rosetta/hamming_numbers.bruijn b/samples/rosetta/hamming_numbers.bruijn
new file mode 100644
index 0000000..426223d
--- /dev/null
+++ b/samples/rosetta/hamming_numbers.bruijn
@@ -0,0 +1,28 @@
+:import std/Combinator .
+:import std/Number .
+:import std/List .
+
+merge y [[[∅?1 0 (1 [[2 [[go]]]])]]]
+ go 3 <? 1 (3 : (6 2 4)) (1 : (6 5 0))
+
+# classic version while avoiding duplicate generation
+hammings-classic (+1) : (foldr u empty ((+2) : ((+3) : {}(+5))))
+ u [[y [merge 1 ((mul 2) <$> ((+1) : 0))]]]
+
+:test ((hammings-classic !! (+42)) =? (+162)) ([[1]])
+
+# enumeration by a chain of folded merges (faster)
+hammings-folded ([(0 ∘ a) ∘ (0 ∘ b)] (foldr merge1 empty)) $ c
+ merge1 [[1 [[1 : (merge 0 2)]]]]
+ a iterate (map (mul (+5)))
+ b iterate (map (mul (+3)))
+ c iterate (mul (+2)) (+1)
+
+:test ((hammings-folded !! (+42)) =? (+162)) ([[1]])
+
+# --- output ---
+
+main [first-twenty : (n1691 : {}n1000000)]
+ first-twenty take (+20) hammings-folded
+ n1691 hammings-folded !! (+1690)
+ n1000000 hammings-folded !! (+999999)
diff --git a/samples/rosetta/loops_infinite.bruijn b/samples/rosetta/loops_infinite.bruijn
new file mode 100644
index 0000000..badcec1
--- /dev/null
+++ b/samples/rosetta/loops_infinite.bruijn
@@ -0,0 +1,4 @@
+:import std/String .
+
+main [spam spam]
+ spam ["SPAM\n" ++ (0 0)]
diff --git a/samples/rosetta/palindrome_detection.bruijn b/samples/rosetta/palindrome_detection.bruijn
new file mode 100644
index 0000000..f4c05b2
--- /dev/null
+++ b/samples/rosetta/palindrome_detection.bruijn
@@ -0,0 +1,6 @@
+:import std/String .
+
+main [<~>0 =? 0]
+
+:test (main "tacocat") ([[1]])
+:test (main "bruijn") ([[0]])
diff --git a/samples/rosetta/test_a_function.bruijn b/samples/rosetta/test_a_function.bruijn
new file mode 100644
index 0000000..dc76eeb
--- /dev/null
+++ b/samples/rosetta/test_a_function.bruijn
@@ -0,0 +1,6 @@
+:import std/String .
+
+main [<~>0 =? 0]
+
+:test (main "tacocat") ([[1]])
+:test (main "bruijn") ([[1]])
diff --git a/samples/rosetta/variadic_fixed-point_combinator.bruijn b/samples/rosetta/variadic_fixed-point_combinator.bruijn
new file mode 100644
index 0000000..cf50875
--- /dev/null
+++ b/samples/rosetta/variadic_fixed-point_combinator.bruijn
@@ -0,0 +1,22 @@
+:import std/Number .
+:import std/List .
+
+y* [[[0 1] <$> 0] ([[1 <! ([[1 2 0]] <$> 0)]] <$> 0)]
+
+# --- example usage ---
+# mutual recurrence relation of odd?/even?
+
+# even x = if x == 0 then true else odd? (x-1)
+g [[[=?0 [[1]] (1 --0)]]]
+
+# odd x = if x == 0 then false else even? (x-1)
+h [[[=?0 [[0]] (2 --0)]]]
+
+even? ^(y* (g : {}h))
+
+odd? _(y* (g : {}h))
+
+:test (even? (+5)) ([[0]])
+:test (odd? (+5)) ([[1]])
+
+main [[0]]
diff --git a/samples/rosetta/y_combinator.bruijn b/samples/rosetta/y_combinator.bruijn
new file mode 100644
index 0000000..95a985b
--- /dev/null
+++ b/samples/rosetta/y_combinator.bruijn
@@ -0,0 +1,15 @@
+:import std/Number .
+
+# sage bird combinator
+y [[1 (0 0)] [1 (0 0)]]
+
+# factorial using y
+factorial y [[=?0 (+1) (0 ⋅ (1 --0))]]
+
+:test ((factorial (+6)) =? (+720)) ([[1]])
+
+# (very slow) fibonacci using y
+fibonacci y [[0 <? (+1) (+0) (0 <? (+2) (+1) rec)]]
+ rec (1 --0) + (1 --(--0))
+
+:test ((fibonacci (+6)) =? (+8)) ([[1]])
diff --git a/src/Helper.hs b/src/Helper.hs
index 3c1f2f2..b4b48e1 100644
--- a/src/Helper.hs
+++ b/src/Helper.hs
@@ -365,7 +365,7 @@ humanifyString :: Expression -> Maybe String
humanifyString e = do
es <- unlistify e
str <- mapM binaryToChar' es
- pure $ show str
+ pure str
humanifyPair :: Expression -> Maybe String
humanifyPair e = do
@@ -438,7 +438,7 @@ binaryToChar e = show <$> binaryToChar' e
binaryToChar' :: Expression -> Maybe Char
binaryToChar' e = do
n <- binaryToDecimal' e
- if n < 255 then Just $ chr $ fromIntegral n else Nothing
+ if n > 31 && n < 127 || n == 10 then Just $ chr $ fromIntegral n else Nothing
binaryToDecimal' :: Expression -> Maybe Integer
binaryToDecimal' e = do
diff --git a/std/Math.bruijn b/std/Math.bruijn
index d9a8c5e..58da709 100644
--- a/std/Math.bruijn
+++ b/std/Math.bruijn
@@ -145,7 +145,7 @@ arrow z [[[[rec]]]] ⧗ Number → Number → Number → Number
# fibonacci sequence
# TODO: faster fib?
-fibs head <$> (iterate [~0 : (^0 + ~0)] ((+0) : (+1))) ⧗ (List Number)
+fibs head <$> (iterate &[[0 : (1 + 0)]] ((+0) : (+1))) ⧗ (List Number)
fib [fibs !! ++0] ⧗ Number
diff --git a/std/Number/Binary.bruijn b/std/Number/Binary.bruijn
index fcbe264..a056538 100644
--- a/std/Number/Binary.bruijn
+++ b/std/Number/Binary.bruijn
@@ -348,7 +348,7 @@ compare-case [[[(T.compare-case 2 1 0) ⋔ binary→ternary]]] ⧗ a → b → c
# returns 1 if a>b, -1 if a<b and 0 if a=b
# also: spaceship operator
-compare compare-case (+0) (+1) (-1) ⧗ Binary → Binary → Binary
+compare compare-case (+0) (+1) (-1) ⧗ Binary → Binary → Number
:test (compare (+2b) (+2b)) ((+0))
:test (compare (+2b) (+1b)) ((+1))
diff --git a/std/Number/Ternary.bruijn b/std/Number/Ternary.bruijn
index f63d9ac..20a89e8 100644
--- a/std/Number/Ternary.bruijn
+++ b/std/Number/Ternary.bruijn
@@ -59,11 +59,11 @@ t⁰? [0 false false true] ⧗ Trit → Boolean
:test (↑⁰(+42)) ((+126))
# shifts a specified trit into a balanced ternary number
-up [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]] ⧗ Trit → Number → Number
+…↑… [[[[[[5 2 1 0 (4 3 2 1 0)]]]]]] ⧗ Trit → Number → Number
-:test (up t⁻ (+42)) (↑⁻(+42))
-:test (up t⁺ (+42)) (↑⁺(+42))
-:test (up t⁰ (+42)) (↑⁰(+42))
+:test (t⁻ ↑ (+42)) (↑⁻(+42))
+:test (t⁺ ↑ (+42)) (↑⁺(+42))
+:test (t⁰ ↑ (+42)) (↑⁰(+42))
# infinity
# WARNING: using this mostly results in undefined behavior! (TODO?)
@@ -249,7 +249,7 @@ dec [~(0 z a⁻ a⁺ a⁰)] ⧗ Number → Number
add [[abs 1 →^0]] ⧗ Number → Number → Number
abs [c (0 z a⁻ a⁺ a⁰)]
b⁻ [1 ↑⁺(3 0 t⁻) ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁰)]
- b⁰ [up 1 (3 0 t⁰)]
+ b⁰ [1 ↑ (3 0 t⁰)]
b⁺ [1 ↑⁰(3 0 t⁰) ↑⁻(3 0 t⁺) ↑⁺(3 0 t⁰)]
a⁻ [[[1 (b⁻ 1) b⁻' b⁰ b⁻]]]
b⁻' [1 ↑⁰(3 0 t⁻) ↑⁻(3 0 t⁰) ↑⁺(3 0 t⁻)]
diff --git a/std/Option.bruijn b/std/Option.bruijn
index 20e4a19..257b5f8 100644
--- a/std/Option.bruijn
+++ b/std/Option.bruijn
@@ -28,7 +28,7 @@ map [[0 none [some (2 0)]]] ⧗ (a → b) → (Option a) → (Option b)
:test (map [[1]] none) (none)
# applies a function to the value in option or returns first arg if none
-map-or v ⧗ (a → b) → (Option a) → (Option c)
+map-or v ⧗ a → (b → c) → (Option b) → c
:test (map-or [[[2]]] [[1]] (some [[0]])) ([[[0]]])
:test (map-or [[[2]]] [[1]] none) ([[[2]]])
diff --git a/std/String.bruijn b/std/String.bruijn
index 76121ee..5af9574 100644
--- a/std/String.bruijn
+++ b/std/String.bruijn
@@ -29,17 +29,26 @@ ni? \in? ⧗ String → Char → Boolean
:test ("ab" ∋ 'c') (false)
# converts a string of digits into a number
-string→number from-digits ∘ (map C.char→number) ⧗ String → Number
+string→unsigned-number from-digits ∘ (map C.char→number) ⧗ String → Number
-:test (%(string→number "123")) ((+123))
+:test (%(string→unsigned-number "123")) ((+123))
# converts a signed string of digits into a number
-string→signed-number [(sign ^0) (string→number ~0)] ⧗ String → Number
+string→signed-number [(sign ^0) (string→unsigned-number ~0)] ⧗ String → Number
sign [(B.eq? 0 '-') -‣ i]
:test (%(string→signed-number "+123")) ((+123))
:test (%(string→signed-number "-123")) ((-123))
+# converts signed/unsigned number strings to a number
+string→number [C.les? ^0 '0' signed unsigned] ⧗ String → Number
+ signed string→signed-number 0
+ unsigned string→unsigned-number 0
+
+:test (%(string→number "123")) ((+123))
+:test (%(string→number "+123")) ((+123))
+:test (%(string→number "-123")) ((-123))
+
# converts a number to a string
number→string (map C.number→char) ∘ digits ⧗ Number → String