Number/Conversion.bruijn


# MIT License, Copyright (c) 2024 Marvin Borner
# convert bases to other bases

:import std/Combinator .
:import std/Number/Unary U
:import std/Number/Binary B
:import std/Number/Ternary T

# converts unary numbers to ternary
unary→ternary [0 T.inc (+0t)] ⧗ Unary → Ternary

¹³‣ unary→ternary

:test (¹³(+0u)) ((+0t))
:test (¹³(+2u)) ((+2t))

binary→unary [[0 (+0u) [U.inc (2 0)] 1]] (U.mul (+2u)) ⧗ Binary → Unary

# converts ternary numbers to unary
ternary→unary [T.apply 0 U.inc (+0u)] ⧗ Ternary → Unary

³¹‣ ternary→unary

:test (³¹(+0t)) ((+0u))
:test (³¹(+2t)) ((+2u))

# converts binary numbers to ternary
# constructs reversed path of composed functions and applies to ternary
binary→ternary [y [[[rec]]] [0] 0 (+0t)] ⧗ Binary → Ternary
	rec B.zero? 0 case-end case-rec
		case-rec B.odd? 0 (2 (1 ∘ T.inc) (B.dec 0)) (2 (1 ∘ (T.mul (+2t))) (B.div² 0))
		case-end 1

²³‣ binary→ternary

:test (T.eq? ²³(+0b) (+0t)) ([[1]])
:test (T.eq? ²³(+42b) (+42t)) ([[1]])

# converts numbers to binary
# constructs reversed path of composed functions and applies to ternary
ternary→binary [y [[[rec]]] [0] 0 (+0b)] ⧗ Ternary → Binary
	rec T.zero? 0 case-end case-rec
		case-rec T.odd? 0 (2 (1 ∘ B.inc) (T.dec 0)) (2 (1 ∘ (B.mul (+2b))) (T.div² 0))
		case-end 1

³²‣ ternary→binary

:test (B.eq? ³²(+0t) (+0b)) ([[1]])
:test (B.eq? ³²(+42t) (+42b)) ([[1]])