Преобразование в и из факториальной системы счисления

27

Системный номер Факториал , называемый также factoradic, смешанная система счисления с номером. Факториалы определяют стоимость места числа.

В этой системе крайняя правая цифра может быть 0 или 1, вторая правая цифра может быть 0, 1 или 2 и т. Д. Это означает, что nцифра факторадического числа может иметь максимальное значение (n + 1)!.

Например, чтобы преобразовать фактическое число 24201в десятичное, вы должны сделать это:

2 * 5! = 240
4 * 4! = 96
2 * 3! = 12
0 * 2! = 0
1 * 1! = 1
240 + 96 + 12 + 0 + 1 = 349

Следовательно, фактическое число 24201является 349базовым 10.

Чтобы преобразовать десятичное число ( 349в качестве примера) в факторическое число, вы должны сделать это:

Возьмите самый большой факториал меньше, чем число. В этом случае это 120или 5!.

349 / 5! = 2 r 109
109 / 4! = 4 r 13
13 / 3! = 2 r 1
1 / 2! = 0 r 1
1 / 1! = 1 r 0

Следовательно, 349база 10- фактическое число 24201.

Ваша задача - создать самую короткую программу или функцию, которая преобразует входной номер в другую базу.

Входными данными будет строковое представление неотрицательного целого числа. Фактическому числу будет предшествовать !(например, !24201), в то время как десятичному числу ничего не будет предшествовать. Вы можете предположить, что максимальный ввод будет 10! - 1- 3628799в десятичной и 987654321фактической. Это означает, что буквы не будут отображаться при фактическом вводе / выводе.

Программа не должна добавлять !перед факторическим выводом и может выводить строку или целое число. Ввод может быть в любом разумном формате.


Тестовые случаи:

Input: 1234
Output: 141120

Input: 746
Output: 101010

Input: !54321
Output: 719

Input: !30311
Output: 381
летучесть
источник

Ответы:

10

APL, 39 37 символов

{A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}

Примеры:

      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'1234'
141120
      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'!54321'
719
Говард
источник
1
Я думаю , что можно заменить ⍴⍵∩'!'с , '!'∊⍵чтобы сохранить характер.
Волатильность
@ Volatlity Да, вы можете. Я также нашел другой.
Говард
11
IMO, имеющий слово «pwn» в вашем скрипте, стоит дополнительного символа.
ejrb
1
Я согласен с ejrb. Не могли бы вы сломать это, пожалуйста?
Тит
1
Замените ~'!'на, ∩⎕Dчтобы сохранить символ.
Адам
9

Python 2,7 ( 163 157 152)

i=raw_input()
exec("b='';a=362880;j=int(i);x=9;"+'b+=`j//a`;j%=a;a/=x;x-=1;'*9,"a=x=1;b=0;"+'b+=a*int(i[-x]);x+=1;a*=x;'*~-len(i))['!'in i]
print int(b)

Более читаемая версия:

i=raw_input()
if'!'in i:a=x=1;b=0;c='b+=a*int(i[-x]);x+=1;a*=x;'*~-len(i)
else:b='';a=362880;j=int(i);x=9;c='b+=`j//a`;j%=a;a/=x;x-=1;'*9
exec c;print int(b)

Сломать:

Factoradic -> Decimal, when i is in the form !(number)
a=1   #Factorial value (multiplied every iteration)
x=1   #Index value
b=0   #Output
iterate ~-len(i) times:    #PSEUDOCODE! bitwisenot(a) = ~a = -a-1
    b+=a*int(i[-x])        #add the value of the xth last character in the factoradic #
    x+=1                   #Increment x
    a*=x                   #Set a to x!, (x-1)! * x = x!

Decimal -> Factoradic
b=''                       #Output
a=362880                   #Factorial value, set to 9! here
j=int(i)                   #Integer value of the input
x=9                        #Index value
iterate 9 times:           #PSEUDOCODE! This block is in an exec() loop
    b+=`j/a`               #Add floor(j/a) to b
    j%=a                   #Take out all multiples of a in j
    a/=x                   #Set a to (x-1)!, x! / x = (x-1)!
    x-=1                   #Decrement x
beary605
источник
1
Хорошее решение. Я думаю , вы можете заменить '!'==i[0]с '!'in i, и можете использовать a=x=1. Кроме того, вам не нужны скобки вокруг оператора exec.
GRC
1
Вы также можете заменить (len(i)-1)на ~-len(i).
Волатильность
@ Volatility, grc: Спасибо! Я должен изучить мои побитовые операторы :)
beary605
1
Хороший ответ, я позволил себе сменить выражение if (a,b)['!'in i]и сумел сбрить 6 символов. Это не так читабельно, как это было, хотя ... ссылка для
вставки
@erjb: Спасибо за предложение! Я использовал 2-кортеж с кодом в качестве строки в строке с функцией exec, которая сохраняет еще два символа :)
beary605
8

GolfScript ( 48 44 43 символов)

.~\{1{):?\.?%\?/@}9*{*+}+9*}:^{:N,{^N=}?}if

Это отдельная программа. Десятичное преобразование factoriadic => является довольно медленным, потому что оно выполняет поиск с использованием десятичного => факториального преобразования, а не прямого базового преобразования.

Входной формат допускает очень короткое переключение режимов: .~копирует входную строку и оценивает ее, поэтому, если ввод - это просто число, которое мы заканчиваем, например, "1234" 1234в стеке, и если оно начинается с !(не логично, с любым непустым значением) строка, являющаяся правдивой) мы в конечном итоге, например, 0 30311в стеке. Тогда значение в нижней части стека истинно для десятичного => факториального и ложно для факторного => десятичного.

Питер Тейлор
источник
4

PHP <7,1 178 171 170 168 164 155 147 144 138 126 123 байта

for($b=$j=1,$i=strlen($x=$argn);+$x?$b<=$x:--$i;$b*=++$j)$r+=$x[$i]*$b;if(+$x)for(;$j>1;$x%=$b)$r.=$x/($b/=$j--)|0;echo+$r;

Запустите как трубу с -rили проверьте это онлайн .

  • продление не требуется
  • нет суба функция необходимо: факториал база повторного использования (incresed / уменьшается в петлях)
  • чистая целочисленная и строковая арифметика, должна даже работать в php 3 (и все еще работает в php 7):
  • десятичное 0 возвращает пустую строку вместо 0. (оба других ответа PHP делают тоже.) Если это недопустимо, добавьте +5 для дополнительного случая.

ungolfed:

// two loops in one: compute the decimal number from a factorial
// or find the first factorial larger than a decimal $x
// the latter inits $r with '0': $i=strlen -> $x[$i]=='' -> (int)$x[$i]==$x[$i]*$b==0
// $b is the current digit´s base; $j is the bases´ latest factor
for($b=$j=1,$i=strlen($x=$argn);+$x?$b<=$x:--$i;$b*=++$j)
    $r+=$x[$i]*$b;
// and now for dec->fact ...
if(+$x)
    for(;$j>1;$x%=$b)
        // both $b and $j are one step too far in the first iteration;
        // -> decrement must precede the actual loop body
        // -> can be merged into the digit calculation -> all braces golfed
        $r.=$x/($b/=$j--)|0;
        // now: go on with the remainder (see loop head)
echo+$r; // final type cast removes leading zeros (from the first loop)
    // and fixes the '0' result (no operations at all on that input!)

заброшенные идеи игры в гольф:

  • $b<=$x-> $b<$x(-1)
    сломает чистые десятичные факториалы (то есть те, которые приводят к факториальному числу только с одной ненулевой цифрой). Решение JMPC страдает от этого; ХамЗа нет.
  • floor($x/$b)-> (int)($x/$b)
    может быть немного быстрее, но приведение типов предшествует делению, поэтому мне нужны скобки, а не байт.
    $x/$b|0делает трюк
  • Цикл по факту -> dec подобен факториалу в dec-> факте. Тот же прирост, тело не имеет значения, но, к сожалению, другие предустановки и другое состояние поста. Dang; мог бы сыграть в гольф -21 там.
    Я нашел решение. Взял совсем немного игры в гольф, но отрубил еще -4 (нет: -9) и закрыл все жучки / лазейки.

Есть еще потенциал ... или я сделал гольф?

Titus
источник
@ JörgHülsermann Спасибо за подсказку.
Тит
1
+$rвместо $r|0сохранения одного байта. То же самое дляif($x|0)
Йорг Хюльсерманн
3

JavaScript (ES 6) 139 137 122 113 111

попробовал другой подход с использованием некоторой магии массива; но в итоге я получил 174 172 байта:

f=x=>{if('!'==x[0]){a=x.split``.reverse();i=b=1;r=0;a.pop();a.map(d=>{r+=d*b;b*=++i})}else{t=[];for(i=b=1;b<=x;b*=++i){t.unshift(b)}r='';t.map(b=>{r+=x/b|0;x%=b})}return r}

Поэтому я просто взял свой PHP-код и перевел его. Может удалить все $s и несколько ;, но необходимость инициализации переменных израсходовала часть этой выгоды. Хотя оба умудрились сыграть в гольф, все же немного ниже.

golfed

f=x=>{for(r=0,b=j=1,i=x.length;x|0?b<=x:--i;b*=++j)r+=x[i]*b;if(x|0)for(r='';j>1;x%=b)r+=x/(b/=j--)|0;return r}
  • первая версия возвращает '' для десятичного 0; добавить +2, чтобы исправить
  • вторая версия требует ввода строки
  • оба протестированы в Firefox, Edge и Opera

ungolfed

f=x=>
{
    for(r=0,b=j=1,i=x.length;x|0?b<=x:--i;b*=++j)
        r+=x[i]*b;
    if(x|0)
        for(r='';j>1;x%=b)
            r+=x/(b/=j--)|0;
    return r
}

тестирование

<table id=out border=1><tr><th>dec</th><th>result<th>expected</th><th>ok?</th></tr></table>
<script>
    addR=(r,s)=>{var d=document.createElement('td');d.appendChild(document.createTextNode(s));r.appendChild(d)}
    test=(x,e)=>{var y=f(x),r=document.createElement('tr');addR(r,x);addR(r,y);addR(r,e);addR(r,e==y?'Y':'N');document.getElementById('out').appendChild(r)}
    samples={'349':'24201','1234':'141120','746':'101010','719':'54321','381':'30311','24':'1000','0':'0'};
    for(d in samples){test(d,samples[d]);test('!'+samples[d],d)}
</script>
Titus
источник
1
ES5 не имеет обозначения стрелки IIRC. И если вы собираетесь использовать ES6, то .split('')=>.split``
Zacharý
@ Zacharý Gna Я должен был отметить, в каком браузере я его тестировал ... возможно, Firefox или Opera. Так ES 6?
Тит
Да, обозначение стрелки - ES6.
Захари
1
О, это застало меня врасплох, я думал, что блок кода наверху был вашим решением! Несмотря на это, я не думаю, что вам нужно говорить f=. Кроме того, может r+=(x/(b/=j--)|0)быть r+=x/(b/=j--)|0?
Захари
1

GolfScript, 69 символов

10,1>{1$*}*](.0=33={1>01/-1%0\{~@(@*@+}/\}{~\-1%{1$<},{1$1$/@@%}/}if;

Принимает ввод из STDIN как обычно и печатает результат. Интернет тест .

Говард
источник
1

Haskell, 221 символ

Код Гольф

m v@(a:b)|a=='!'=(sum.zipWith(*)g.map(read.(:[])).reverse) b|True=(fst.until((<0).fst.snd)(\(s,(i,b))->(s*10+b`quot`f i,(i-1,b`rem`f i))).(\n->(0,((1+).last.takeWhile((n>=).f)$[1..], n))).read) v;g=scanl1(*)[1..];f=(g!!)

использование

$ ghci factorial.hs
ghci> m "1234"
 141120
ghci> m "!54321"
 719

Код без правил

parse v@(a:b) | a == '!' = to b
              | otherwise = from v

to = sum . zipWith (*) factorials . map (read . (:[])) . reverse

from = fst . until finished next . boostrap . read
    where finished = ((<0) . fst . snd)
          next (s,(i,r)) = (s * 10 + r `quot` factorial i, (i-1 ,r `rem` factorial i))
          bootstrap n = (0, (lastFact n, n))
          lastFact n = (1+) . last . takeWhile ((n>=) . factorial) $ [1..]

factorials = scanl1 (*) [1..]

factorial = (factorials!!)
StreakyCobra
источник
Безусловно самая читаемая запись. Haskell FTW!
Сохам Чоудхури
1

Mathematica 213 177 175

Факториальное число включается f[], независимо от того, является ли оно входным или выходным.

g@{n_,j_,r_}:=If[j==0,FromDigits@r,g@{q=QuotientRemainder[n,j!];q[[2]],j-1,Append[r,q[[1]]]}]
z@n_:=If[!IntegerQ@n, g[{n[[1]],9,{}}], f@Tr@(p=1;# (p++)!&/@Reverse@IntegerDigits@n)]

использование

z[24201]

F [349]

z[f[349]]

24201

Преобразование факториала в десятичное число . QuotientRemainder[n,j!]рекурсивно действует на цифры факторного числа слева направо, уменьшаясь jна каждом шаге. QuotientRemainder[349, 5!]например, возвращает {2, 109}и так далее.

Преобразование десятичного числа в факториальное число . Перемещение справа налево, чистая функция, # (p++)! &умножает каждую цифру #на соответствующий факториал.

DavidC
источник
1

Питон, 128 символов

Это займет около получаса, но это мало:

A=[`x`for x in xrange(10**9)if all(x/10**d%10<d+2 for d in range(9))]
i=raw_input()
print A.index(i[1:])if'!'in i else A[int(i)]

Он строит список всех фактических чисел <= 9 цифр в числовом порядке, а затем выполняет поиск или индекс для преобразования.

Если вы хотите проверить, просто заменить 10**9с 10**6и ограничивать себя 6-значные числа переменного числа.

Я мог бы технически сохранить персонажа, используя range(10**9)вместо xrange(10**9). Не пытайтесь делать это дома.

Кит Рэндалл
источник
Между d+2иfor
Zacharý
1

PHP 231 214 204

Самый новый ответ

function g($x){return $x?$x*g($x-1):1;}function f($x,$e){if($x[0]=="!"){for($t=1;$t<$c=strlen($x);$t++){$e+=$x[$t]*g($c-$t);}}else{while(g(++$p)<=$x);while(--$p){$e.=floor($x/g($p));$x%=g($p);}}return$e;}

Старый ответ

 function f($n){if($n[0]=="!"){$n=str_split($n);$c=count($n);$f=$y=1;while($c-->1){$e+=($f*$n[$c]);$f*=++$y;}return$e;}else{for($i=$c=1;$i<$n;$i*=$c){$r[$c++]=$i;}foreach(array_reverse($r)as$t){$e.=floor($n/$t);$n=$n%$t;}return$e;}}

пример

echo f('349')."\n"
    .f('!24201')."\n"
    .f('1234')."\n"
    .f('746')."\n"
    .f('!54321')."\n"
    .f('!30311');

Выход

24201
349
141120
101010
719
381
JPMC
источник
2
Для нового ответа я считаю 212, а не 214. $ e не нуждается в инициализации (-6) и foreach(range())может быть заменен простым forциклом (-9). Мне нравится идея, хотя.
Тит
2
неправильный результат для чистых факториалов. 24должен вернуться, 1000но возвращается 400. исправить: g(++$p)<$x-> g(++$p)<=$x(+1)
Тит
@Titus Спасибо за оба ваших ответа! Я обновил свой ответ. Я ценю, что вы помогаете мне улучшить мой ответ, когда ваш кажется намного лучше.
JPMC
1
1) Я считаю на 2 меньше, чем вы, опять же: 204, а не 206. Включаете ли вы разрыв строки Windows в число ваших байтов? 2) синтаксическая ошибка в forконструкции: ,должно быть ;3) у меня есть еще 7 изменений, сохраняющих 20 байтов в этом коде. Хотите их?
Тит
2
Ну, на самом деле это всего 5 изменений, но одна из них состоит из трех частей. a) устаревший второй аргумент для f () (-3) b) устаревший пробел в функции g (-1) c) устаревшие скобки в истинной ветви (-4) d) поменяйте местами истинную и ложную ветви, инвертируйте ifусловие, затем используйте мой сексуальный тип приведен к int (-6) Это не повлияет на результат десятичного 0! д) оставшаяся forконструкция может быть переписана с очень хорошим while(++$t<$c=strlen($x)): приращение перед телом -> $ t не нуждается в инициализации (-6)
Тит
1

Желе, 5 байт

Æ!ŒṘ€

объяснение

Æ!ŒṘ€
Æ!     -Convert to factoriadic (list form)
  ŒṘ€  -Construct string

* Желе моложе возраста вопроса, поэтому мой ответ неконкурентен.

DaggerOfMesogrecia
источник
1
Добро пожаловать в PPCG! Я думаю, что желе моложе, чем этот вызов, поэтому вы должны пометить свой ответ как не конкурирующий.
Лайкони
О, я не осознавал, что это было правилом. Сделаю.
DaggerOfMesogrecia
Разве ответы на этот вызов не должны работать в обоих направлениях? Кажется, это работает только в одном направлении; Вы можете исправить это. (С другой стороны, если вы конвертируете между целыми числами и строками в Jelly, обычно лучше использовать некоторую комбинацию Vи .)
1

Желе , 15 байт

ḊV€;0Æ¡µÆ!ṖḌƊ¬?

Попробуйте онлайн!

Как это работает

ḊV€;0Æ¡µÆ!ṖḌƊ¬?     Main link (monad). Input: integer or string
             ¬?  *) If the given input is a string, run 1); otherwise run 2)

ḊV€;0Æ¡  1) Factorial base -> integer
ḊV€         Remove "!" and map each char to number
   ;0       Append zero (this is needed to run the built-in correctly)
     Æ¡     Built-in conversion

Æ!ṖḌ  2) Integer -> factorial base
Æ!       Built-in conversion
  ṖḌ     Remove a zero at the end, and convert to decimal

Почему *)работает

¬поэлементно логично НЕ. Когда задано одно целое число, оно становится единичным нулем, что ложно. Однако, когда задана строка, каждый элемент (символ) превращается в ноль, и весь результат представляет собой массив нулей, который является истинным.

Ноль как целое число - это особый случай. Он проходит по маршруту "factorial -> integer", но все равно дает ноль, который является правильным.

Без встроенной факториальной базы, 25 байт

⁵R!µ³%Ḋ:ṖUḌ
⁵R!ḋḊUV€ƊµÇ¬?

Попробуйте онлайн!

Как это работает

⁵R!µ³%Ḋ:ṖUḌ  Aux. link (monad). Integer -> factorial base
⁵R!µ         Set (1..10)! as left argument
    ³%Ḋ:Ṗ    Compute each digit: (input % (2..10)!) // (1..9)!
         UḌ  Reverse and convert the digit array to decimal

⁵R!ḋḊUV€ƊµÇ¬?  Main link (monad).
         怪?  If the input is a string, apply the left chain;
               otherwise, apply the aux. link above
⁵R!            (1..10)!
   ḋ           Dot product with...
    ḊUV€Ɗ      Remove "!", reverse, map each character to digit
фонтанчик для питья
источник
0

К, 102

"I"$,/$*:'|:'{{(x-y*g),g:_(x:*x)%y:*/1+!y}\[x,0n;|1+!{$[(x>(*/1+!y))&x<*/1+!y+1;y;.z.s[x;1+y]]}[x;0]]}

Определенно может быть улучшено.

k)"I"$,/$*:'|:'{{,[;g]x-y*g:_(x:*x)%y:*/1+!y}\[(x;0n);|1+!{{$[(x>(*/1+!y))&x<*/1+!y+1;y;.z.s[x;1+y]]}[x;0]}x]} 349
24201
k)"I"$,/$*:'|:'{{,[;g]x-y*g:_(x:*x)%y:*/1+!y}\[(x;0n);|1+!{{$[(x>(*/1+!y))&x<*/1+!y+1;y;.z.s[x;1+y]]}[x;0]}x]} 746
101010
k)"I"$,/$*:'|:'{{,[;g]x-y*g:_(x:*x)%y:*/1+!y}\[(x;0n);|1+!{{$[(x>(*/1+!y))&x<*/1+!y+1;y;.z.s[x;1+y]]}[x;0]}x]} 1234
141120
tmartin
источник
0

D (159 символов)

int x(string n){import std.conv;int r,i=9,f=9*'鶀',d;if(n[0]<48){while(r.text.x<n[1..$].to!int)r++;}else{d=n.to!int;while(i){r=r*10+d/f;d%=f;f/=i--;}}return r;}

Неуправляемый и с точкой входа в программу

Все аргументы командной строки выводятся как <original> -> <converted>. Только десятичные к фактическим фактически осуществлены в x. И наоборот, просто вызывает xвсе десятичные числа (0 .. *), пока результат не станет равным входному значению. Это займет ~ 3 секунды для самого большого ввода (! 987654321).

Исполняемая онлайн-версия: http://dpaste.dzfl.pl/46e425f9

void main(string[] args) {
    import std.stdio;
    foreach (arg; args[1 .. $]) {
        writefln("%s -> %s", arg, x(arg));
    }
}

int x(string n) {
    import std.conv;
    int r, i=9, f=9*'鶀', d;  // 鶀's Unicode index equals 8*7*6*5*4*3*2*1

    // If the first character value is less than 48 ('0') it should be a '!'.
    if (n[0] < 48) {
        // Call x with different input (0..*) until it matches our n.
        // r.text.x is rewritten as x(text(r)).
        while (r.text.x < n[1..$].to!int) r++;
    } else {
        d = n.to!int;
        // Try d / 9!, d / 8!, etc. just as in the problem description.
        while (i) {
            r = r*10 + d/f;
            d %= f;
            f /= i--;
        }
    }
    return r;
}
mleise
источник
Я думаю, что можно было бы изменить, string nчтобы char[]nсохранить один байт (я знаю, что я опоздал здесь).
Захари
Также, я думаю, if(n[0]<48){while(r.text.x<n[1..$].to!int)r++;}можно if(n[0]<48)while(r.text.x<n[1..$].to!int)r++;сэкономить два байта.
Zacharý
0

VBA 225

Спасибо Титу за помощь! Все еще ищу в гольф еще.

Sub a(b)
Set w=WorksheetFunction
e=Len(b)
If IsNumeric(b) Then
i=0
For d=0To 8
h=w.Fact(9-d)
g=b Mod h
If g<b+i Then
i=1
f=f &Int(b/h)
b=g
End If
Next
Else
For d=2To e
f=f+w.Fact(e-d-1)*Mid(b,d,1)
Next
End If
MsgBox f
End Sub
Gaffi
источник
Я не знаю VBA, но есть ли способ проверить bчисловое значение вместо сравнения первого символа?
Тит
@Titus Есть числовая проверка, и эквивалент здесь будет:, If Not IsNumeric(b) Thenно это займет больше символов. Я не пошел и не пересмотрел весь код; может быть немного лучший способ сделать это в IsNumericцелом. - Исправление, здесь есть небольшое улучшение. Благодарность!
Гаффи
Я нашел еще четыре байта: For d=9To 1Step-1и Fact(d)-> For d=0To 8и Fact(9-d)еще два, если вы это сделаете For d=2To eиFact(e-d+1)*Mid(b,d,1)
Тит
Может ли тип, приведенный к Int, быть написан по-другому?
Тит
@ Titus Посмотри на себя, бегая кругами вокруг меня. :) Я сейчас поправляю ... Что касается Int (), я не думаю, что есть более простой (меньший) метод, нет.
Гаффи
0

PHP , 124 байта

for($f=1;("$">$a=$argn)&&~$c=strrev($a)[$n];)$r+=$c*$f*=++$n;for(;$a>=$f*=++$i;);for(;~-$i;$a%=$f)$r.=0|$a/$f/=$i--;echo+$r;

Попробуйте онлайн!

расширенный

for($f=1;("$">$a=$argn)&&~$c=strrev($a)[$n];) # runs in case of "!" at the beginning
  $r+=$c*$f*=++$n; #reverse string multiply with the next factorial "!"*$f=0
for(;$a>=$f*=++$i;); # runs not in case of "!" at the beginning string comparing. search the factorial that is higher as input value
for(;~-$i;$a%=$f) # runs only when the second loop had runs
  $r.=0|$a/$f/=$i--; # concat the value of the division with the highest factorial used
echo+$r; # Output result
Йорг Хюльсерманн
источник
0

Perl 6 , 150 байт

{/^\!/??([+] [Z*] .comb.skip.reverse,[\*] 1..*)!!(reduce
->\a,\b{a[0]~a[1] div b,a[1]%b},("",+$_),|(first
*[*-1]>$_,[\,] [\*] 1..*).reverse[1..*])[0]}
Шон
источник
0

APL (NARS), 36 символов, 72 байта

{⍵⊆⎕D:10⊥(9..2)⊤⍎⍵⋄t+.×⌽!⍳≢t←⍎¨,1↓⍵}

кажется, что 10⊥ (9..2) better лучше, чем рекурсивная функция, благодаря Говарду за другое решение APL, которое показывает, что ... (даже если я не понимаю 100%). Ввод для чисел без '!' <10 !. Тест:

  u←{⍵⊆⎕D:10⊥(9..2)⊤⍎⍵⋄t+.×⌽!⍳≢t←⍎¨,1↓⍵}    
  u¨'1234' '746' '!54321' '!30311' '!24201'    
141120 101010 719 381 349 
  u '0'
0
  u '!0'
0
  u '9'
111
  u '!111'
9
  u '!9'
9
RosLuP
источник