Konversi ke dan dari sistem angka faktorial

27

The faktorial Number System , juga disebut factoradic, adalah sistem radix angka campuran. Faktorial menentukan nilai tempat suatu angka.

Dalam sistem ini, digit paling kanan bisa 0 atau 1, digit paling kanan kedua bisa 0, 1 atau 2, dan seterusnya. Ini berarti bahwa nangka faktoradik digit dapat memiliki nilai maksimum (n + 1)!.

Misalnya, untuk mengonversi angka faktoradik 24201menjadi desimal, Anda akan melakukan ini:

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

Oleh karena itu angka faktoradik 24201adalah 349basa 10.

Untuk mengonversi angka desimal (dengan 349sebagai contoh) menjadi angka faktoradik, Anda akan melakukan ini:

Ambil faktorial terbesar kurang dari jumlah. Dalam hal ini 120, atau 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

Karenanya 349basis 10adalah angka faktoradik 24201.

Tantangan Anda adalah membuat program atau fungsi terpendek yang mengubah nomor input ke basis lain.

Input akan berupa representasi string dari integer non-negatif. Angka faktoradik akan didahului oleh !(mis. !24201), Sedangkan angka desimal tidak akan didahului oleh apa pun. Anda dapat berasumsi bahwa input maksimum adalah 10! - 1- 3628799dalam desimal dan 987654321faktoradik. Ini berarti bahwa huruf tidak akan muncul dalam input / output faktoradik.

Program tidak perlu menambahkan sebuah !ke keluaran faktoradik, dan dapat menampilkan string atau integer. Masukan mungkin dalam format yang masuk akal.


Kasus uji:

Input: 1234
Output: 141120

Input: 746
Output: 101010

Input: !54321
Output: 719

Input: !30311
Output: 381
Keriangan
sumber

Jawaban:

10

APL, 39 37 karakter

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

Contoh:

      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'1234'
141120
      {A B←(9⍴10)(⌽1+⍳9)⌽⍨'!'∊⍵⋄A⊥B⊤⍎⍵~'!'}'!54321'
719
Howard
sumber
1
Saya pikir Anda dapat mengganti ⍴⍵∩'!'dengan '!'∊⍵untuk menyimpan karakter.
Volatilitas
@ Kelemahan Ya Anda bisa. Saya juga menemukan yang lain.
Howard
11
IMO memiliki kata "pwn" dalam skrip Anda layak karakter tambahan.
ejrb
1
Saya setuju dengan ejrb. Apakah Anda akan memecah ini tolong?
Titus
1
Ganti ~'!'dengan ∩⎕Duntuk menyimpan karakter.
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)

Versi yang lebih mudah dibaca:

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)

Kerusakan:

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
sumber
1
Solusi yang bagus. Saya pikir Anda bisa menggantinya '!'==i[0]dengan '!'in i, dan bisa menggunakan a=x=1. Juga, Anda tidak perlu tanda kurung di sekitar pernyataan eksekutif.
grc
1
Anda juga bisa mengganti (len(i)-1)dengan ~-len(i).
Volatilitas
@Vatilitas, grc: Terima kasih! Saya harus mempelajari operator bitwise saya :)
beary605
1
Jawaban yang bagus, saya mengambil kebebasan untuk mencoba mengganti pernyataan if dengan (a,b)['!'in i]dan berhasil mencukur 6 karakter. Ini tidak dapat dibaca seperti dulu ... tautan pastebin
ejrb
@erjb: Terima kasih atas sarannya! Saya menggunakan 2-tuple dengan kode sebagai string in-line dengan fungsi exec, yang menyimpan dua karakter lagi :)
beary605
8

GolfScript ( 48 44 43 karakter)

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

Ini adalah program mandiri. Factoriadic => konversi desimal cukup lambat, karena ia melakukan pencarian menggunakan konversi desimal => factoriadic daripada konversi basis langsung.

Format input memungkinkan untuk mode switch yang sangat singkat: .~menyalin string input dan mengevaluasinya, jadi jika inputnya hanya berupa angka, kita berakhir dengan mis. "1234" 1234Pada stack, dan jika dimulai dengan !(tidak logis, dengan sembarang kosong) string menjadi benar) kita berakhir dengan misalnya 0 30311pada stack. Kemudian nilai di bagian bawah tumpukan benar untuk desimal => factoriadic dan falsy untuk factoriadic => decimal.

Peter Taylor
sumber
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;

Jalankan sebagai pipa dengan -ratau uji secara online .

  • tidak diperlukan ekstensi
  • tidak diperlukan sub fungsi: basis faktorial sedang digunakan kembali (bertambah / berkurang di loop)
  • integer murni dan string arithmetics, bahkan harus bekerja di php 3 (dan masih berfungsi di php 7):
  • desimal 0 mengembalikan string kosong sebagai ganti 0. (kedua jawaban PHP lainnya juga.) Jika itu tidak dapat diterima, tambahkan +5 untuk case tambahan.

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

ide golf ditinggalkan:

  • $b<=$x-> $b<$x(-1)
    akan memecah faktorial desimal murni (yaitu yang menghasilkan bilangan faktorial dengan hanya satu digit bukan nol). Solusi JMPC menderita karenanya; HamZa tidak.
  • floor($x/$b)-> (int)($x/$b)
    bisa sedikit lebih cepat, tetapi tipe casting mendahului divisi, jadi saya perlu tanda kurung dan jangan mendapatkan byte.
    $x/$b|0lakukan triknya
  • Loop pada fact-> dec mirip dengan factorial-find dalam dec-> fact. Selisih yang sama, body tidak masalah, tetapi sayangnya kondisi preset dan postingan berbeda. Dang; bisa bermain golf -21 di sana.
    YA saya menemukan solusinya. Mengambil sedikit golf, tetapi memotong -4 (no: -9) dan menutup semua bug / celah.

Adakah yang lebih potensial ... atau apakah saya sudah bermain golf?

Titus
sumber
@ JörgHülsermann Terima kasih atas petunjuknya.
Titus
1
+$ralih-alih $r|0menyimpan satu byte. Sama untukif($x|0)
Jörg Hülsermann
3

JavaScript (ES 6) 139 137 122 113 111

mencoba pendekatan yang berbeda menggunakan beberapa array magic; tapi saya berakhir di 174 172 byte dengan itu:

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}

Jadi saya hanya mengambil kode PHP saya dan menerjemahkannya. Bisa menghapus semua $dan beberapa ;, tetapi keharusan untuk menginisialisasi vars memakan beberapa manfaat itu. Berhasil untuk golf kedua jawaban turun sedikit lebih jauh.

bermain golf

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}
  • versi pertama mengembalikan '' untuk 0 desimal; tambahkan +2 untuk memperbaikinya
  • versi kedua membutuhkan input string
  • keduanya diuji di Firefox, Edge dan 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
}

test suite

<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
sumber
1
ES5 tidak memiliki notasi panah IIRC. Dan jika Anda akan menggunakan ES6, maka .split('')=>.split``
Zacharý
@ Zacharý Gna Seharusnya saya mencatat di browser mana saya mengujinya ... mungkin Firefox atau Opera. Jadi ES 6?
Titus
Ya, notasi panah adalah ES6.
Zacharý
1
Oh, itu membuat saya lengah, saya pikir blok kode di atas adalah solusi Anda! Bagaimanapun, saya pikir Anda tidak perlu mengatakannya f=. Juga, bisa r+=(x/(b/=j--)|0)menjadi r+=x/(b/=j--)|0?
Zacharý
2

Perl 6 , 66 65 60 byte

-1 byte terima kasih kepada Jo King

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

Cobalah online!

nwellnhof
sumber
1

GolfScript, 69 karakter

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

Mengambil input dari STDIN seperti biasa dan mencetak hasilnya. Tes online .

Howard
sumber
1

Haskell, 221 karakter

Golf kode

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

Pemakaian

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

Kode tidak dikunci

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
sumber
Sejauh ini entri yang paling mudah dibaca. Haskell FTW!
Soham Chowdhury
1

Mathematica 213 177 175

Sejumlah faktorial dibungkus f[], apakah itu input atau 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)]

Pemakaian

z[24201]

f [349]

z[f[349]]

24201

Konversi faktorial ke angka desimal . QuotientRemainder[n,j!]secara rekursif bertindak pada digit nomor faktorial dari kiri ke kanan, menurun jpada setiap langkah. QuotientRemainder[349, 5!], misalnya, pengembalian {2, 109}dan sebagainya.

Konversi angka desimal ke faktorial . Bergerak ke kanan ke kiri, fungsi murni # (p++)! &,, mengalikan setiap digit,# , dengan faktorial yang sesuai.

DavidC
sumber
1

Python, 128 karakter

Ini membutuhkan waktu sekitar setengah jam untuk berjalan, tetapi kecil:

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

Itu membangun daftar semua nomor faktoradik <= 9 digit dalam urutan numerik, kemudian melakukan pencarian atau indeks untuk dikonversi.

Jika Anda ingin menguji, ganti saja 10**9dengan 10**6dan batasi diri Anda dengan angka variadic 6 digit.

Secara teknis saya bisa menyimpan karakter dengan menggunakan range(10**9)alih-alih xrange(10**9). Jangan coba ini di rumah.

Keith Randall
sumber
Tidak ada ruang yang dibutuhkan antara d+2danfor
Zacharý
1

PHP 231 214 204

Jawaban Terbaru

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

Jawaban Lama

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

Contoh

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

Keluaran

24201
349
141120
101010
719
381
JPMC
sumber
2
Saya menghitung 212 untuk jawaban baru, bukan 214. $ e tidak perlu inisialisasi (-6) dan foreach(range())dapat diganti dengan forloop sederhana (-9). Saya suka ide itu.
Titus
2
hasil yang salah untuk faktorial murni. 24harus kembali 1000tetapi kembali 400. fix: g(++$p)<$x-> g(++$p)<=$x(+1)
Titus
@Titus Terima kasih untuk kedua balasan Anda! Saya memperbarui jawaban saya. Saya menghargai Anda membantu saya meningkatkan jawaban saya ketika jawaban Anda tampaknya jauh lebih unggul.
JPMC
1
1) Saya menghitung 2 lebih sedikit dari Anda, lagi: 204, bukan 206. Apakah Anda menyertakan jeda baris Windows dalam jumlah byte Anda? 2) kesalahan sintaks dalam formembangun: ,seharusnya ;3) Saya punya 7 perubahan lain menghemat 20 byte pada kode itu. Ingin mereka?
Titus
2
Sebenarnya hanya 5 perubahan, tetapi salah satunya memiliki tiga bagian. a) Argumen kedua usang untuk f () (-3) b) usang kosong pada fungsi g (-1) c) kawat gigi usang di cabang benar (-4) d) menukar cabang benar dan salah, membalikkan ifkondisi, kemudian menggunakan kondisi tersebut, kemudian menggunakan my sexy type cast to int (-6) Ini tidak akan memengaruhi hasil 0 desimal! e) forkonstruk yang tersisa dapat ditulis ulang dengan sangat bagus while(++$t<$c=strlen($x)): kenaikan sebelum tubuh -> $ t tidak perlu inisialisasi (-6)
Titus
1

JELLY, 5 byte

Æ!ŒṘ€

Penjelasan

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

* Jelly lebih muda dari usia pertanyaan karena itu jawaban saya tidak bersaing.

DaggerOfMesogrecia
sumber
1
Selamat datang di PPCG! Saya pikir Jelly lebih muda dari tantangan ini, maka Anda harus menandai jawaban Anda sebagai tidak bersaing.
Laikoni
Oh saya tidak menyadari bahwa itu adalah aturan. Akan melakukan.
DaggerOfMesogrecia
Bukankah jawaban untuk tantangan ini dimaksudkan untuk bekerja dua arah? Ini sepertinya hanya bekerja satu arah; Anda mungkin ingin memperbaikinya. (Pada catatan terpisah, jika Anda mengonversi bilangan bulat dan string di Jelly, biasanya paling sederhana untuk menggunakan beberapa kombinasi dari Vdan .)
1

Jelly , 15 byte

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

Cobalah online!

Bagaimana itu bekerja

Ḋ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

Mengapa *)bekerja

¬unsur-bijaksana TIDAK logis. Ketika diberi bilangan bulat tunggal, itu menjadi nol tunggal, yang salah. Namun, ketika diberi string, setiap elemen (karakter) berubah menjadi nol, dan keseluruhan hasilnya adalah array nol yang benar.

Nol sebagai bilangan bulat adalah kasus khusus. Ia melewati rute "faktorial -> integer", tetapi masih memberikan nol yang benar.

Tanpa basis faktorial bawaan, 25 byte

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

Cobalah online!

Bagaimana itu bekerja

⁵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
sumber
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]]}

Pasti bisa ditingkatkan.

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

D (159 karakter)

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

Tidak disatukan dan dengan titik masuk program

Semua argumen baris perintah dicetak sebagai <original> -> <converted>. Hanya desimal ke faktoradik yang benar-benar diterapkan di x. Sebaliknya hanya panggilanx dengan semua angka desimal (0 .. *) hingga hasilnya sama dengan input. Ini membutuhkan ~ 3 detik untuk input terbesar (! 987654321).

Versi online yang dapat dieksekusi: 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
sumber
Saya pikir itu mungkin untuk mengubah string nke char[]nmenyimpan satu byte (saya tahu aku terlambat sini).
Zacharý
Juga, saya pikir if(n[0]<48){while(r.text.x<n[1..$].to!int)r++;}bisa menjadi if(n[0]<48)while(r.text.x<n[1..$].to!int)r++;menghemat dua byte.
Zacharý
0

VBA 225

Terima kasih kepada Titus atas bantuannya! Masih ingin bermain golf lagi.

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
sumber
Saya tidak tahu VBA, tetapi apakah ada cara untuk memeriksa bnilai numerik daripada membandingkan karakter pertama?
Titus
@Titus Ada pemeriksaan numerik, dan yang setara di sini adalah:, If Not IsNumeric(b) Thentetapi itu membutuhkan lebih banyak karakter. Sekarang, saya tidak masuk dan memeriksa ulang semua kode; mungkin ada cara yang sedikit lebih baik untuk melakukan ini dengan IsNumerickeseluruhan. - Koreksi, ada sedikit peningkatan di sini. Terima kasih!
Gaffi
Saya menemukan empat byte lagi: For d=9To 1Step-1dan Fact(d)-> For d=0To 8dan Fact(9-d)dan dua lagi jika Anda lakukan For d=2To edanFact(e-d+1)*Mid(b,d,1)
Titus
Bisakah tipe yang dilemparkan ke Int ditulis dengan cara lain?
Titus
@Itus Lihatlah dirimu, berlari melingkari aku. :) Saya mengutak-atik sekarang ... Adapun Int (), saya tidak berpikir ada metode yang lebih sederhana (lebih kecil), tidak.
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;

Cobalah online!

Diperpanjang

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
sumber
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]}
Sean
sumber
0

APL (NARS), 36 karakter, 72 byte

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

tampaknya 10⊥ (9..2) ⊤ lebih baik daripada fungsi rekursif, terima kasih kepada Howard untuk solusi APL lainnya yang menunjukkan bahwa ... (bahkan jika saya tidak mengerti 100%). Masukkan nomor tanpa '!' <10 !. Uji:

  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
sumber