Konvertieren in und aus dem Fakultätszahlensystem

27

Das Factorial Number System , auch factoradic genannt, ist ein gemischtes Radix-Zahlensystem. Die Fakultäten bestimmen den Stellenwert einer Zahl.

In diesem System kann die Ziffer ganz rechts entweder 0 oder 1 sein, die zweite Ziffer ganz rechts kann 0, 1 oder 2 sein und so weiter. Dies bedeutet, dass eine nziffernfaktoradische Zahl einen Maximalwert von haben kann (n + 1)!.

Um beispielsweise die faktoradische Zahl 24201in eine Dezimalzahl umzuwandeln, gehen Sie folgendermaßen vor:

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

Daher ist die faktoradische Zahl 24201die 349Basis 10.

So konvertieren Sie eine Dezimalzahl (mit 349als Beispiel) in eine faktoradische Zahl:

Nehmen Sie die größte Fakultät kleiner als die Zahl. In diesem Fall ist es 120oder 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

Daher 349Basis 10ist die Zahl factoradic 24201.

Ihre Herausforderung besteht darin, das kürzeste Programm oder die kürzeste Funktion zu erstellen, die eine eingegebene Nummer in die andere Basis umwandelt.

Die Eingabe ist eine Zeichenfolgendarstellung einer nicht negativen Ganzzahl. Einer faktoradischen Zahl wird ein !(z. B. !24201) vorangestellt , während einer Dezimalzahl nichts vorangestellt wird. Sie können davon ausgehen, dass die maximale Eingabe 10! - 1- 3628799dezimal und 987654321faktoradisch - erfolgt. Dies bedeutet, dass in einer faktoradischen Eingabe / Ausgabe keine Buchstaben erscheinen.

Das Programm muss a keiner !faktoradischen Ausgabe voranstellen und kann eine Zeichenfolge oder eine Ganzzahl ausgeben. Die Eingabe kann in jedem vernünftigen Format erfolgen.


Testfälle:

Input: 1234
Output: 141120

Input: 746
Output: 101010

Input: !54321
Output: 719

Input: !30311
Output: 381
Flüchtigkeit
quelle

Antworten:

10

APL, 39 37 Zeichen

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

Beispiele:

      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'1234'
141120
      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'!54321'
719
Howard
quelle
1
Ich denke , Sie ersetzen können ⍴⍵∩'!'mit '!'∊⍵einem Zeichen zu speichern.
Volatilität
@Volatility Ja, das kannst du. Ich habe auch noch einen gefunden.
Howard
11
IMO mit dem Wort "pwn" in Ihrem Skript ist das zusätzliche Zeichen wert.
ejrb
1
Ich stimme ejrb zu. Würdest du das bitte aufschlüsseln?
Titus
1
Ersetzen Sie ~'!'durch ∩⎕D, um ein Zeichen zu speichern.
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)

Mehr lesbare Version:

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)

Nervenzusammenbruch:

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
quelle
1
Gute Lösung. Ich glaube , Sie ersetzen können '!'==i[0]mit '!'in iund verwenden können a=x=1. Außerdem benötigen Sie keine eckigen Klammern um die exec-Anweisung.
grc
1
Sie können auch ersetzen (len(i)-1)mit ~-len(i).
Volatilität
@Volatility, grc: Danke! Ich sollte meine bitweisen Operatoren lernen :)
beary605
1
Gute Antwort, ich habe mir die Freiheit genommen, die if-Anweisung durch zu ersetzen, (a,b)['!'in i]und habe es geschafft, 6 Zeichen zu entfernen. Es ist nicht so lesbar wie es war ... Pastebin-Link
ejrb
@erjb: Danke für den Vorschlag! Ich habe ein 2-Tupel mit dem Code als Zeichenfolge in Übereinstimmung mit der exec-Funktion verwendet, die zwei weitere Zeichen speichert :)
beary605
8

GolfScript ( 48 44 43 Zeichen)

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

Dies ist ein eigenständiges Programm. Die Konvertierung von Faktor => Dezimal ist recht langsam, da bei der Suche die Konvertierung von Dezimal => Faktor und nicht die direkte Basis verwendet wird.

Das Eingabeformat ermöglicht einen sehr kurzen Moduswechsel: .~Kopiert die Eingabezeichenfolge und wertet sie aus. Wenn die Eingabe also nur eine Zahl ist, die wir zB "1234" 1234auf dem Stapel haben, und wenn sie mit !(logisch nicht, mit einer nicht leeren) beginnt string being truthy) landen wir zB 0 30311auf dem Stack. Dann ist der Wert am unteren Ende des Stapels für dezimal => faktorisch und für faktorisch => dezimal falsch.

Peter Taylor
quelle
4

PHP <7.1 178 171 170 168 164 155 147 144 138 126 123 Bytes

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;

Laufen Sie als Pipe mit -roder testen Sie es online .

  • Keine Erweiterung erforderlich
  • Keine Unterfunktion erforderlich: Die Fakultätsbasis wird wiederverwendet (in den Schleifen erhöht / verringert)
  • Reine Integer- und String-Arithmetik sollte sogar in PHP 3 funktionieren (und funktioniert immer noch in PHP 7):
  • Dezimal 0 gibt anstelle von leere Zeichenfolge zurück 0. (Beide anderen PHP-Antworten tun dies auch.) Wenn dies nicht akzeptabel ist, fügen Sie +5 für den zusätzlichen Fall hinzu.

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

Verlassene Golfideen:

  • $b<=$x-> $b<$x(-1)
    würde reine Dezimalfaktoren auflösen (dh diejenigen, die eine Fakultätszahl mit nur einer Ziffer ungleich Null ergeben). Darunter leidet die Lösung von JMPC. HamZa´s nicht.
  • floor($x/$b)-> (int)($x/$b)
    könnte etwas schneller sein, aber Typ Casting geht der Division voraus, daher brauche ich die Klammern und gewinne kein Byte.
    $x/$b|0macht den Trick
  • Die Schleife in fact-> dec ähnelt der Fakultätsfindung in dec-> fact. Gleiches Inkrement, Körper spielt keine Rolle, aber leider unterschiedliche Voreinstellungen und unterschiedliche Nachbedingungen. Dang; hätte dort -21 golfen können.
    Ja, ich habe eine Lösung gefunden. Hat einiges Golf gespielt, aber ein weiteres -4 (no: -9) abgeschnitten und alle Bugs / Lücken geschlossen.

Noch mehr Potenzial ... oder bin ich fertig mit Golfen?

Titus
quelle
@ JörgHülsermann Danke für den Hinweis.
Titus
1
+$ranstatt $r|0ein Byte zu speichern. Gleiches gilt fürif($x|0)
Jörg Hülsermann
3

JavaScript (ES 6) 139 137 122 113 111

habe einen anderen Ansatz mit Array-Magie ausprobiert; aber ich endete mit 174 172 Bytes:

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}

Also habe ich einfach meinen PHP-Code genommen und übersetzt. Konnte alle $s und ein paar entfernen ;, aber die Notwendigkeit, vars zu initialisieren, hat einen Teil dieses Vorteils aufgezehrt. Schaffte es, beide Antworten etwas weiter nach unten zu spielen.

Golf gespielt

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}
  • erste Version gibt '' für dezimal 0 zurück; Addiere +2, um das Problem zu beheben
  • Die zweite Version erfordert die Eingabe eines Strings
  • beide in Firefox, Edge und Opera getestet

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
}

Testsuite

<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
quelle
1
ES5 hat keine Pfeilnotation IIRC. Und wenn Sie ES6 verwenden, dann .split('')=>.split``
Zacharý
@ Zacharý Gna Ich hätte notieren sollen, in welchem ​​Browser ich es getestet habe ... wahrscheinlich Firefox oder Opera. Also ES 6?
Titus
Ja, die Pfeilnotation ist ES6.
Zacharý
1
Oh, das hat mich überrascht, ich dachte, der Codeblock oben wäre Ihre Lösung! Egal, ich glaube nicht, dass Sie das sagen müssen f=. Kann auch r+=(x/(b/=j--)|0)sein r+=x/(b/=j--)|0?
Zacharý
2

Perl 6 , 66 65 60 Bytes

-1 Byte danke an Jo King

{/\!/??:1[.flip.chop.comb Z*[\*] 1..*]!![R~] .polymod(2..*)}

Probieren Sie es online!

nwellnhof
quelle
1

GolfScript, 69 Zeichen

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

Nimmt die Eingabe von STDIN wie gewohnt und druckt das Ergebnis. Online-Test .

Howard
quelle
1

Haskell, 221 Zeichen

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

Verwendung

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

Ungolfed Code

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
quelle
Mit Abstand der am besten lesbare Eintrag. Haskell FTW!
Soham Chowdhury
1

Mathematica 213 177 175

Eine Fakultätszahl wird eingepackt f[], egal ob es sich um eine Eingabe oder eine Ausgabe handelt.

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

Verwendung

z[24201]

f [349]

z[f[349]]

24201

Umwandlung von Fakultät in Dezimalzahl . QuotientRemainder[n,j!]Wirkt rekursiv auf die Ziffern der Fakultätszahl von links nach rechts und dekrementiert sie jbei jedem Schritt. QuotientRemainder[349, 5!]kehrt zum Beispiel zurück {2, 109}und so weiter.

Umwandlung von Dezimalzahlen in Fakultätszahlen . Bei Bewegung von rechts nach links # (p++)! &multipliziert die reine Funktion jede Ziffer #mit der entsprechenden Fakultät.

DavidC
quelle
1

Python, 128 Zeichen

Das dauert ungefähr eine halbe Stunde, ist aber klein:

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

Es wird eine Liste aller faktoradischen Zahlen mit <= 9 Stellen in numerischer Reihenfolge erstellt und anschließend eine Suche oder ein Index zur Konvertierung durchgeführt.

Wenn Sie testen möchten, ersetzen Sie einfach 10**9mit 10**6und beschränken Sie sich auf 6-stellige variadische Zahlen.

Ich könnte einen Charakter technisch speichern, indem ich ihn range(10**9)anstelle von benutze xrange(10**9). Versuchen Sie das nicht zu Hause.

Keith Randall
quelle
Zwischen d+2und wird kein Leerzeichen benötigt.for
Zacharý
1

PHP 231 214 204

Neueste Antwort

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

Alte Antwort

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

Beispiel

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

Ausgabe

24201
349
141120
101010
719
381
JPMC
quelle
2
Ich zähle 212 für die neue Antwort, nicht 214. $ e benötigt keine Initialisierung (-6) und foreach(range())kann durch eine einfache forSchleife (-9) ersetzt werden. Die Idee gefällt mir allerdings.
Titus
2
falsches Ergebnis für reine Fakultäten. 24sollte zurückkehren 1000, kehrt aber zurück 400. Fix: g(++$p)<$x-> g(++$p)<=$x(+1)
Titus
@Titus Danke für beide Antworten! Ich habe meine Antwort aktualisiert. Ich weiß es zu schätzen, dass Sie mir helfen, meine Antwort zu verbessern, wenn Ihre weit überlegen erscheint.
JPMC
1
1) Ich zähle 2 weniger als Sie, also 204, nicht 206. Beziehen Sie einen Windows-Zeilenumbruch in Ihre Byteanzahl ein? 2) Syntaxfehler im forKonstrukt: ,sollte ;3) Ich habe weitere 7 Änderungen, die 20 Bytes in diesem Code einsparen. Will diese?
Titus
2
Nun, es sind eigentlich nur 5 Änderungen, aber eine von ihnen besteht aus drei Teilen. a) veraltetes zweites Argument für f () (-3) b) veraltetes Leerzeichen in Funktion g (-1) c) veraltete geschweifte Klammern im wahren Zweig (-4) d) wahre und falsche Zweige vertauschen, die ifBedingung invertieren , dann verwenden Mein sexy Typ wird auf int (-6) geworfen. Dies hat keinen Einfluss auf das Ergebnis von Dezimal 0! e) Das verbleibende forKonstrukt kann mit einem sehr netten while(++$t<$c=strlen($x)): Inkrement vor Körper umgeschrieben werden -> $ t braucht keine Initialisierung (-6)
Titus
1

JELLY, 5 Bytes

Æ!ŒṘ€

Erläuterung

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

* Jelly ist jünger als das Alter der Frage, daher ist meine Antwort nicht konkurrierend.

Dolch von Mesogrecia
quelle
1
Willkommen bei PPCG! Ich denke, Jelly ist jünger als diese Herausforderung, daher sollten Sie Ihre Antwort als nicht konkurrierend markieren.
Laikoni
Oh, ich wusste nicht, dass das eine Regel ist. Wird besorgt.
DaggerOfMesogrecia
Sollen Antworten auf diese Herausforderung nicht in beide Richtungen funktionieren? Dies scheint nur in eine Richtung zu funktionieren; Vielleicht möchten Sie das beheben. (Wenn Sie in Jelly zwischen Ganzzahlen und Zeichenfolgen konvertieren, empfiehlt es sich normalerweise, eine Kombination aus Vund zu verwenden .)
1

Gelee , 15 Bytes

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

Probieren Sie es online!

Wie es funktioniert

Ḋ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

Warum *)funktioniert

¬ist elementweise logisch NICHT. Wenn eine einzelne Ganzzahl angegeben wird, wird sie zu einer einzelnen Null, was falsch ist. Wenn jedoch eine Zeichenfolge angegeben wird, wird jedes Element (Zeichen) auf Null gesetzt, und das gesamte Ergebnis ist ein Array von Nullen, das wahr ist.

Null als Ganzzahl ist ein Sonderfall. Es geht durch die "Fakultät -> Ganzzahl" Route, aber es gibt immer noch Null, was korrekt ist.

Ohne eingebaute Fakultätsbasis 25 Bytes

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

Probieren Sie es online!

Wie es funktioniert

⁵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
Bubbler
quelle
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]]}

Könnte definitiv verbessert werden.

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

D (159 Zeichen)

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 und mit Programmeinstieg

Alle Befehlszeilenargumente werden als gedruckt <original> -> <converted>. In wird nur dezimal nach faktoradisch implementiert x. Umgekehrt wird nur xmit allen Dezimalzahlen (0 .. *) gerufen, bis das Ergebnis der Eingabe entspricht. Dies dauert ca. 3 Sekunden für die größte Eingabe (! 987654321).

Ausführbare Online-Version: 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
quelle
Ich denke, es könnte möglich sein, zu wechseln string n, char[]num ein Byte zu sparen (ich weiß, dass ich zu spät bin).
Zacharý
Auch denke ich if(n[0]<48){while(r.text.x<n[1..$].to!int)r++;}kann werden if(n[0]<48)while(r.text.x<n[1..$].to!int)r++;, um zwei Bytes zu sparen.
Zacharý
0

VBA 225

Vielen Dank an Titus für die Hilfe! Ich freue mich immer noch auf 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
Gaffi
quelle
Ich kenne VBA nicht, aber gibt es eine Möglichkeit, bnach einem numerischen Wert zu suchen, anstatt das erste Zeichen zu vergleichen?
Titus
@Titus Es gibt eine numerische Prüfung, und die Entsprechung hier wäre:, If Not IsNumeric(b) Thenaber das braucht mehr Zeichen. Jetzt habe ich nicht mehr den gesamten Code überprüft. Es kann einen etwas besseren Weg geben, dies mit IsNumericinsgesamt zu tun . - Korrektur, hier gibt es eine leichte Verbesserung. Vielen Dank!
Gaffi
Ich habe weitere vier Bytes gefunden: For d=9To 1Step-1und Fact(d)-> For d=0To 8und Fact(9-d)und noch zwei, wenn Sie dies tun For d=2To eundFact(e-d+1)*Mid(b,d,1)
Titus
Kann der Typ, der in Int umgewandelt wurde, auf andere Weise geschrieben werden?
Titus
@Titus Schau dich an und renne Kreise um mich herum. :) Ich optimiere jetzt ... Was Int () betrifft, glaube ich nicht, dass es eine einfachere (kleinere) Methode gibt, nein.
Gaffi
0

PHP , 124 Bytes

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;

Probieren Sie es online!

Verlängert

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
Jörg Hülsermann
quelle
0

Perl 6 , 150 Bytes

{/^\!/??([+] [Z*] .comb.skip.reverse,[\*] 1..*)!!(reduce
->\a,\b{a[0]~a[1] div b,a[1]%b},("",+$_),|(first
*[*-1]>$_,[\,] [\*] 1..*).reverse[1..*])[0]}
Sean
quelle
0

APL (NARS), 36 Zeichen, 72 Byte

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

es scheint, dass 10.2 (9..2) ⊤ besser ist als die rekursive Funktion, dank Howard für die andere APL-Lösung, die das zeigt ... (auch wenn ich nicht 100% verstehe). Eingabe für Zahlen ohne '!' <10 !. Prüfung:

  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
quelle