This prompt asked you to convert back and forth to factoradic, but is very limited in scope (only decimal integers from 0 to 10!-1). Your task in this challenge is to reach just a bit further and fully implement conversion between factoradic and any other integer base.
The factoradic system is extended to the reals by using reciprocals of factorials:
43210.001234 (max value at each position, ==DEC119.991666666... and ==DEC14399/120)
= 4 3 2 1 0 . 0 0 1 2 3 4
= 4*4! + 3*3! + 2*2! + 1*1! + 0*0! + 0*1/0! + 0*1/1! + 1*1/2! + 2*1/3! + 3*1/4! + 4*1/5!
= 96 + 18 + 4 + 1 + 0 + 0 + 0 + 1/2 + 1/3 + 1/8 + 1/30
= 119+119/120 (last two here lines are in decimal; but same idea for any other base)
Because of how this is defined, any real factoradic number has at most [denominator+1] digits past the decimal. As you can see from the above example, which has significantly less than 121 digits after the decimal, the number of digits required is much less for numbers with lots of factors. To convert in the other direction, a real numer a/b -> factoradic, requires a bit more effort. There may be an easier way to do this, but I couldn't find anyone who has done this before so I had to work out the formula myself. If you come up with an easier formula feel free to add it. Since we're working in multiple bases here, clarification may be needed: a number prefixed by a 3-letter abbreviation is being represented in the base which that prefix corresponds to, I am using the notation of baseN(#)
to mean convert number # to base N
, and unspecified numbers are in decimal for convenience.
14399/120 = 119 + 119/120
whole number portion:
119 / 4! = 4 r 23
23 / 3! = 3 r 5
5 / 2! = 2 r 1
1 / 1! = 1 r 0
0 / 0! = 0 r 0
fraction portion:
119/120 = 119/5!
base5(DEC119) = 434 (43 4)
base4(QUI43) = 113 (11 3)
base3(QUA11) = 12 (1 2)
base2(TRI1) = 1 (0 1)
base1(BIN0) = 0 (0 0)
base0(UNA0) = 0 (0 0)
factorial:
43210.001234
bigger example:
123454321/11 = 11223120 + 1/11
whole number portion:
11223120 / 10! = 3 r 336720
336720 / 9! = 0 r 336720
336720 / 8! = 8 r 14160
14160 / 7! = 2 r 4080
4080 / 6! = 5 r 480
480 / 5! = 4 r 0
0 / 4! = 0 r 0
0 / 3! = 0 r 0
0 / 2! = 0 r 0
0 / 1! = 0 r 0
0 / 0! = 0 r 0
fraction portion:
1/11 = (1*(11-1)!)/11! = 3628800/11!
base11(DEC3628800) = 205940A (205940 A)
base10(ELE205940) = 329890 (32989 0)
base9(DEC32989) = 50224 (5022 4)
base8(NON5022) = 7121 (712 1)
base7(OCT712) = 1223 (122 3)
base6(SEP112) = 145 (14 5)
base5(SEX14) = 20 (2 0)
base4(QUI2) = 2 (0 2)
base3(QUA0) = 0 (0 0)
base2(TRI0) = 0 (0 0)
base1(BIN0) = 0 (0 0)
base0(UNA0) = 0 (0 0)
factorial number:
30825400000.00002053140A
converting number n0 from base b1 to b2:
n0/b2 = n1 r d1 ( this only works )
n1/b2 = n2 r d2 ( if you actually )
n2/b2 = n3 r d3 ( do all the work )
..until n<b2... ( in the 1st base )
n0 in b1 is n:...:d3:d2:d1 in b2, where
a colon represents separation of digits
if you can't do operations in other bases, first convert to base 10:
digit1 * b1^(#digits) + digit2 * b1^(#digits-1) + ... + digitn * b1^0 = number_in_base10
In words:
For the whole number part you take the floor of the number, and divide it by the largest factorial less than it, using the floor of that answer as the next digit and the remainder as the next argument.
For the fraction part, you multiply top and bottom until the denominator is a factorial n!, and convert the numerator to base n. Then remove the last digit and convert to the next lower base, using the full sequence of removed digits as the decimal.
You may notice that the three middle digits (...0.00...) are always 0. You may either include or exclude them, but state in your answer which you are going to do, and be consistent (ie, either your input and output both always use the abbreviated form like !1.1=DEC3/2 or they both always use the complete form like !10.001=DEC3/2).
Your code should take as input an input & output base, along with a real number represented in the input base, and then output that same real number in the output base. (depricated req) Note that at some point you will need to select a sub-base to represent the digits of numbers in bases larger than you can represent with one character. The higher you can get without falling back onto a sub-base the happier you will make me personally.
You may assume exactly one of either 'input' or 'output' must be in factoradic. Your output must take the same format as your input, ie your code should be able to back-convert anything it outputs. Numbers should be output in their simplest form (ie no leading/trailing 0's; no #/1's, 0/#'s, or #/0's; no -0; no #/-# or -#/-#; 6/4 -> 3/2; etc). (depricated req) In the spirit of flexible I/O you may use the default representation of higher-number bases for your language. Please state in your answer what format your numbers will use.
You may define the format for specifying 'input and output bases' in any way you like, as long as it can represent any integer base >= 2 and specifies whether the input will be going into or out of factoradic.
You may represent the non-factoradic number as either a/b (recommended) or as a real number n; if you use real number n as your input and output format you have to come up with a way to represent repeated digits like in DEC1/3, DEC1/7, or DEC1/28 (eg, digits after some delimiter repeat or something).
The factoradic part must be one number, you may not separately convert the numerator and denominator and return a fraction.
Examples:
radix: decimal-in
number: 14399/120
output: 43210.001234
radix: decimal-out
number: -43210.001234
output: -14399/120
radix: decimal-in
number: 123454321/11
output: 30825400000.00002053140A
radix: octal-in
number: -11656
output: -6543200
radix: hex-out
number: 42130100.001004
output: 4FD06/F
radix: 100-in
number(sub-base is hex): 1c|3|2f|62|35|5a|3/1|1e|4c|4a|24|50|0
output: 3110.0002223571381ccd
radix: binary-in
number: 0
output: 0
code-golf so shortest code in each language wins. You may assume input always follows your specified format, and it will always be a valid output as if your code had been given its own output and told to convert the other way. The logic of your code should work for any real number, converting between any positive integer base >=2 and factoradic in either direction. If your language has a built-in factoradic conversion function, you may include a secondary answer to show it off, but your first answer should not use it. Other integer base -> integer base conversion functions are fine.
⌊log(N)*10⌋-10
for highest base N but it seems like that would take it out of code-golf \$\endgroup\$