Converti da e verso il sistema numerico fattoriale


27

Il sistema numerico fattoriale , chiamato anche factoradic, è un sistema numerico radix misto. I fattoriali determinano il valore del luogo di un numero.

In questo sistema, la cifra più a destra può essere 0 o 1, la seconda cifra più a destra può essere 0, 1 o 2 e così via. Ciò significa che un nnumero fattorico numerico può avere un valore massimo di (n + 1)!.

Ad esempio, per convertire il numero fattorico 24201in decimale devi fare questo:

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

Quindi il numero fattorico 24201è 349base 10.

Per convertire un numero decimale (con 349come esempio) in un numero fattorico, devi fare questo:

Prendi il fattoriale più grande in meno del numero. In questo caso lo è 120, o 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

Quindi la 349base 10è il numero fattorico 24201.

La tua sfida è creare il programma o la funzione più breve che converta un numero di input nell'altra base.

L'input sarà una rappresentazione in formato stringa di un numero intero non negativo. Un numero fattorico sarà preceduto da un !(es. !24201), Mentre un numero decimale non sarà preceduto da nulla. Si può presumere che l'input massimo sarà 10! - 1- 3628799in decimale e 987654321in fattorico. Ciò significa che le lettere non appariranno in un input / output fattorico.

Il programma non ha bisogno di !anteporre a un output fattadico e può generare una stringa o un numero intero. L'input può essere in qualsiasi formato ragionevole.


Casi test:

Input: 1234
Output: 141120

Input: 746
Output: 101010

Input: !54321
Output: 719

Input: !30311
Output: 381

Risposte:


10

APL, 39 37 caratteri

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

Esempi:

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

1
Penso che puoi sostituirlo ⍴⍵∩'!'con '!'∊⍵per salvare un personaggio.
Volatilità,

@Volatilità Sì, puoi. Ne ho trovato anche un altro.
Howard,

11
L'IMO che ha la parola "pwn" nella tua sceneggiatura merita il carattere extra.
ejrb,

1
Sono d'accordo con ejrb. Ti dispiacerebbe per favore?
Titus

1
Sostituisci ~'!'con ∩⎕Dper salvare un personaggio.
Adám,

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)

Versione più leggibile:

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)

Abbattersi:

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

1
Bella soluzione. Penso che tu possa sostituire '!'==i[0]con '!'in i, e puoi usare a=x=1. Inoltre, non sono necessarie parentesi attorno all'istruzione exec.
GRC

1
Puoi anche sostituirlo (len(i)-1)con ~-len(i).
Volatilità,

@Volatilità, grazie: grazie! Dovrei imparare i miei operatori bit a bit :)
beary605

1
Bella risposta, mi sono preso la libertà di provare a sostituire la dichiarazione if (a,b)['!'in i]e sono riuscito a radere via 6 caratteri. Non è leggibile come era però ... link pastebin
ejrb

@erjb: grazie per il suggerimento! Ho usato una 2-tupla con il codice come stringa in linea con la funzione exec, che salva altri due caratteri :)
beary605

8

GolfScript ( 48 44 43 caratteri)

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

Questo è un programma autonomo. La conversione decimale => decimale è piuttosto lenta, poiché effettua una ricerca utilizzando la conversione decimale => decimale piuttosto che una conversione base diretta.

Il formato di input consente un cambio di modalità molto breve: .~copia la stringa di input e la valuta, quindi se l'input è solo un numero con cui finiamo ad esempio "1234" 1234nello stack, e se inizia con !(logicamente no, con qualsiasi non vuoto essendo la stringa veritiera) finiamo per es. 0 30311con lo stack. Quindi il valore nella parte inferiore della pila è vero per decimale => factoriadico e falso per factoriadico => decimale.


4

PHP <7,1 178 171 170 168 164 155 147 144 138 126 123 byte

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;

Esegui come pipe -ro testalo online .

  • nessuna estensione richiesta
  • nessuna sottofunzione necessaria: la base fattoriale viene riutilizzata (aumentata / ridotta nei loop)
  • aritmetica di interi e stringhe pure, dovrebbe funzionare anche in php 3 (e funziona ancora in php 7):
  • il decimale 0 restituisce una stringa vuota anziché 0. (lo fanno anche le altre due risposte PHP.) Se questo è inaccettabile, aggiungi +5 per il caso aggiuntivo.

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!)

idee golf abbandonate:

  • $b<=$x-> $b<$x(-1)
    spezzerebbe i fattoriali decimali puri (cioè quelli che danno come risultato un numero fattoriale con una sola cifra diversa da zero). La soluzione di JMPC ne soffre; HamZa non lo fa.
  • floor($x/$b)-> (int)($x/$b)
    potrebbe essere un po 'più veloce, ma digitare casting precede la divisione, quindi ho bisogno delle parentesi e non guadagno un byte.
    $x/$b|0fa il trucco
  • Il loop infatti-> dec è simile al factorial-find in dec-> fact. Stesso incremento, il corpo non ha importanza, ma sfortunatamente preimpostazioni diverse e condizioni post diverse. Dang; avrebbe potuto giocare a golf -21 lì.
    YAY ho trovato una soluzione. Ha preso un bel po 'di golf, ma ha eliminato un altro -4 (no: -9) e chiuso tutti i bug / scappatoie.

Altre potenzialità ... o ho finito il golf?


@ JörgHülsermann Grazie per il suggerimento.
Tito

1
+$rinvece di $r|0salvare un byte. Lo stesso perif($x|0)
Jörg Hülsermann,

3

JavaScript (ES 6) 139 137 122 113 111

ha provato un approccio diverso usando un po 'di magia dell'array; ma ho finito con 174 172 byte con quello:

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}

Quindi ho appena preso il mio codice PHP e l'ho tradotto. Potrebbe rimuovere tutti $i pochi e pochi ;, ma la necessità di inizializzare vari consumò parte di quel vantaggio. Gestito a golf entrambe le risposte un po 'più in basso, però.

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}
  • la prima versione restituisce '' per 0 decimale; aggiungi +2 per correggere
  • la seconda versione richiede l'immissione di stringhe
  • entrambi testati in Firefox, Edge e 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
}

suite di test

<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>

1
ES5 non ha la notazione con freccia IIRC. E se hai intenzione di usare ES6, allora .split('')=>.split``
Zacharý

@ Zacharý Gna Avrei dovuto notare in quale browser l'ho provato ... probabilmente Firefox o Opera. Quindi ES 6?
Tito,

Sì, la notazione a freccia è ES6.
Zacharý,

1
Oh, questo mi ha preso alla sprovvista, ho pensato che il blocco di codice in alto fosse la tua soluzione! Indipendentemente da ciò, non penso che tu debba dire f=. Inoltre, può r+=(x/(b/=j--)|0)essere r+=x/(b/=j--)|0?
Zacharý,


1

GolfScript, 69 caratteri

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

Prende l'input da STDIN come al solito e stampa il risultato. Test online .


1

Haskell, 221 caratteri

Codice Golf

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!!)

uso

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

Codice Ungolfed

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!!)

Di gran lunga la voce più leggibile. Haskell FTW!
Soham Chowdhury,

1

Mathematica 213 177 175

Viene inserito un numero fattoriale f[], sia esso input o output.

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)]

uso

z[24201]

f [349]

z[f[349]]

24201

Conversione del numero fattoriale in numero decimale . QuotientRemainder[n,j!]agisce in modo ricorsivo sulle cifre del numero fattoriale da sinistra a destra, diminuendo jad ogni passo. QuotientRemainder[349, 5!], ad esempio, restituisce {2, 109}e così via.

Conversione del numero decimale in numero fattoriale . Spostando da destra a sinistra, la funzione pura # (p++)! &, moltiplica ogni cifra #per il fattoriale appropriato.


1

Python, 128 caratteri

Questa operazione richiede circa mezz'ora per l'esecuzione, ma è piccola:

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)]

Costruisce un elenco di tutti i numeri fattorici <= 9 cifre in ordine numerico, quindi effettua una ricerca o un indice da convertire.

Se vuoi testare, sostituiscilo 10**9con 10**6e limitati ai numeri variadici a 6 cifre.

Potrei tecnicamente salvare un personaggio usando range(10**9)invece di xrange(10**9). Non provarlo a casa.


Non è necessario spazio tra d+2efor
Zacharý

1

PHP 231 214 204

Risposta più recente

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;}

Vecchia risposta

 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;}}

Esempio

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

Produzione

24201
349
141120
101010
719
381

2
Conto 212 per la nuova risposta, non 214. $ e non ha bisogno di inizializzazioni (-6) e foreach(range())può essere sostituito con un semplice forciclo (-9). Mi piace l'idea, però.
Tito

2
risultato errato per fattoriali puri. 24dovrebbe tornare 1000ma ritorna 400. correzione: g(++$p)<$x-> g(++$p)<=$x(+1)
Tito

@Titus Grazie per entrambe le tue risposte! Ho aggiornato la mia risposta. Apprezzo che mi aiuti a migliorare la mia risposta quando la tua sembra di gran lunga superiore.
JPMC,

1
1) Conto 2 in meno di te, ancora: 204, non 206. Includete un'interruzione di linea di Windows nel conteggio dei byte? 2) errore di sintassi nel forcostrutto: ,dovrebbe essere ;3) Ho altre 7 modifiche salvando 20 byte su quel codice. Li voglio?
Tito

2
Bene, in realtà sono solo 5 modifiche, ma una di queste ha tre parti. a) secondo argomento obsoleto per f () (-3) b) spazio vuoto obsoleto nella funzione g (-1) c) parentesi graffe obsolete nel ramo vero (-4) d) scambia i rami vero e falso, inverti la ifcondizione, quindi usa my sexy type cast to int (-6) Questo non influirà sul risultato decimale 0! e) il forcostrutto rimanente può essere riscritto con un ottimo while(++$t<$c=strlen($x)): incremento prima del corpo -> $ t non ha bisogno di inizializzazione (-6)
Tito

1

JELLY, 5 byte

Æ!ŒṘ€

Spiegazione

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

* La gelatina è più giovane dell'età della domanda, quindi la mia risposta non è competitiva.


1
Benvenuti in PPCG! Penso che Jelly sia più giovane di questa sfida, quindi dovresti contrassegnare la tua risposta come non competitiva.
Laikoni,

Oh, non avevo capito che quella era una regola. Andrà bene.
DaggerOfMesogrecia,

Le risposte a questa sfida non sono pensate per funzionare in entrambi i modi? Questo sembra funzionare solo in un modo; potresti voler risolvere questo. (In una nota separata, se stai convertendo tra numeri interi e stringhe in Jelly, di solito è meglio usare una combinazione di Ve .)

1

Gelatina , 15 byte

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

Provalo online!

Come funziona

Ḋ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

Perché *) funziona

¬è NOT logico dal punto di vista degli elementi. Quando viene dato un singolo intero, diventa un singolo zero, che è falso. Tuttavia, quando viene data una stringa, ogni elemento (carattere) viene trasformato in zero e l'intero risultato è una matrice di zero che è vera.

Lo zero come numero intero è un caso speciale. Attraversa il percorso "fattoriale -> intero", ma fornisce comunque zero che è corretto.

Senza base fattoriale integrata, 25 byte

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

Provalo online!

Come funziona

⁵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

K, 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]]}

Potrebbe sicuramente essere migliorato.

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

0

D (159 caratteri)

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;}

Ungolfed e con punto di accesso al programma

Tutti gli argomenti della riga di comando vengono stampati come <original> -> <converted>. In realtà è implementato solo il decimale in fattorico x. Al contrario, chiama solo xcon tutti i numeri decimali (0 .. *) fino a quando il risultato è uguale all'input. Questo richiede ~ 3 secondi per l'ingresso più grande (! 987654321).

Versione eseguibile online: 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;
}

Penso che potrebbe essere possibile passare string na char[]nper salvare un byte (so che sono in ritardo qui).
Zacharý,

Inoltre, penso che if(n[0]<48){while(r.text.x<n[1..$].to!int)r++;}possa diventare if(n[0]<48)while(r.text.x<n[1..$].to!int)r++;per salvare due byte.
Zacharý,

0

VBA 225

Grazie a Titus per l'aiuto! Sto ancora cercando di giocare a golf.

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

Non conosco VBA, ma c'è un modo per verificare bun valore numerico invece di confrontare il primo carattere?
Tito

@Titus Esiste un controllo numerico e l'equivalente qui sarebbe:, If Not IsNumeric(b) Thenma richiede più caratteri. Ora, non sono entrato e ho riesaminato tutto il codice; potrebbe esserci un modo leggermente migliore per farlo nel IsNumericcomplesso. - Correzione, c'è un leggero miglioramento qui. Grazie!
Gaffi,

Ho trovato altri quattro byte: For d=9To 1Step-1e Fact(d)-> For d=0To 8e Fact(9-d)altri due se lo fai For d=2To eeFact(e-d+1)*Mid(b,d,1)
Tito

Il tipo cast su Int può essere scritto in un altro modo?
Tito

@Titus Guardati, correndo intorno a me. :) Ora sto modificando ... Per quanto riguarda Int (), non penso che ci sia un metodo più semplice (più piccolo), no.
Gaffi,

0

PHP , 124 byte

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;

Provalo online!

estesa

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 byte

{/^\!/??([+] [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 caratteri, 72 byte

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

sembra che 10⊥ (9..2) ⊤ sia migliore della funzione ricorsiva, grazie a Howard per l'altra soluzione APL che mostra che ... (anche se non capisco al 100%). Inserire i numeri senza "!" <10 !. Test:

  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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.