5
\$\begingroup\$

I wanted to ask this question: Convert to and from the factorial number system but I'm a couple of years too late!

So, instead you must convert to and from the lairotcaf backwards-factorial number base! The way it works is that the first digit is always 0, the maximum value of the next digit is 1, then 2 and so on. If a number has n digits, then each place value is given by n!/i! where i is the digit position starting at 1 on the left. The highest digit position is on the right. This means that each length uses different place values!

There is a unique shortest way to represent each number, which is what you must output for a decimal number input. If an input number starts with a 0, convert it to decimal. If it starts with any other digit, convert it to the backwards-factorial number base.

0 is both valid and the same number in both bases. In the test data no input value will use, or produce a number with a digit higher than 9. Note that the shortest representation of some numbers starts with multiple 0s.

Digit position:   1   2   3   4   5   6
Place value:    720 360 120  30   6   1
                  0   0   2   2   3   3
                  0   0 240+ 60+ 18+  3=321

This is the shortest way to represent 321 because removing a digit makes the highest number possible only 119 (5! - 1).

Test data:

Input:      Output:
0           0
1           01
002         2
3           010
011         4
5           012
0012        6
21          0121
0130        24
01000       60
01234       119
001000      120
321         002233
011235      563
0010330     987
4321        0120252
54321       000325536
654321      0010135621
0112351713  2838883
7654321     00102603574

This is so the fewest bytes wins!

\$\endgroup\$
1
\$\begingroup\$

ES6, 135 108 bytes

s=>s<"1"?[...s].reduce((t,d,i)=>+d+t*++i):eval("for(i=j=k=1;i<=s;i*=++j);for(r='';k<=j;k++)r+=s%i/(i/=k)|0")

Converting from backwards-factorial is nice and easy. Converting to it... not so nice. I found a 119-byte version that doesn't use eval:

s=>s<"1"?[...s].reduce((t,d,i)=>+d+t*++i):(i=j=k=1,g=_=>s<i||g(i*=++j),g(),[...Array(j)].map(_=>s%i/(i/=k++)|0).join``)
\$\endgroup\$
0
\$\begingroup\$

Perl 6, 71 bytes

{{/^0/??.comb.reduce(* *-+^++$+*)!![R~] .polymod(+.polymod(1..*)...2)}}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Jelly, 36 bytes

⁵R!>³¬TUŻ‘PƤµ³%Ḋ:ṖUŻṾ€
Jṙ1PÐƤḋV€µÇ¬?

Try it online!

How it works

⁵R!>³¬TUŻ‘PƤµ³%Ḋ:ṖUŻṾ€  Aux. link (monad). Integer -> string
⁵R!           [1..10]!
   >³¬T       All indices of above <= input
       UŻ‘    Reverse, prepend 0, increment
          PƤ  Product of each prefix
            µ           Re-focus on the above
             ³%Ḋ:Ṗ      Input % (next base value) // (own base value)
                  UŻṾ€  Reverse, prepend zero, map each digit to string

Jṙ1PÐƤḋV€µÇ¬?  Main link (monad). String -> integer || Integer -> string
         怪?  If input is string, apply the link on the left;
               otherwise, apply the aux. link
Jṙ1        List of indices rotated once to the left
   PÐƤ     Product of each suffix
      ḋV€  Convert each input char to digit, and dot product with above

Uses some tricks from my own Jelly answer for factorial base challenge.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.