Chuyển đổi sang và từ hệ thống số giai thừa


27

Các hệ thống Số thừa , còn gọi là factoradic, là một hệ thống radix số hỗn hợp. Các giai thừa xác định giá trị vị trí của một số.

Trong hệ thống này, chữ số bên phải nhất có thể là 0 hoặc 1, chữ số ngoài cùng bên phải thứ hai có thể là 0, 1 hoặc 2, v.v. Điều này có nghĩa là một nsố nhân tố số có thể có giá trị tối đa là (n + 1)!.

Ví dụ: để chuyển đổi số nhân 24201thành số thập phân, bạn sẽ làm điều này:

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

Do đó số nhân tố 24201349cơ sở 10.

Để chuyển đổi một số thập phân (với 349ví dụ) thành một số nhân tố, bạn sẽ làm điều này:

Lấy giai thừa lớn nhất ít hơn số. Trong trường hợp này, nó là 120, hoặc 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

Do đó 349cơ sở 10là số nhân tố 24201.

Thách thức của bạn là tạo ra chương trình hoặc chức năng ngắn nhất để chuyển đổi một số đầu vào thành cơ sở khác.

Đầu vào sẽ là một chuỗi đại diện của một số nguyên không âm. Một số nhân tố sẽ được đi trước bởi một !(ví dụ !24201), trong khi một số thập phân sẽ không được đi trước bởi bất cứ điều gì. Bạn có thể giả định rằng đầu vào tối đa sẽ là 10! - 1- 3628799ở dạng thập phân và 987654321theo hệ số. Điều này có nghĩa là các chữ cái sẽ không xuất hiện trong một đầu vào / đầu ra nhân tố.

Chương trình không cần phải trả trước một !đầu ra nhân tố và có thể xuất ra một chuỗi hoặc một số nguyên. Các đầu vào có thể ở bất kỳ định dạng hợp lý.


Các trường hợp thử nghiệm:

Input: 1234
Output: 141120

Input: 746
Output: 101010

Input: !54321
Output: 719

Input: !30311
Output: 381

Câu trả lời:


10

APL, 39 37 ký tự

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

Ví dụ:

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

1
Tôi nghĩ rằng bạn có thể thay thế ⍴⍵∩'!'với '!'∊⍵để lưu một ký tự.
Biến động

@Volatility Có bạn có thể. Tôi cũng tìm thấy một cái khác.
Howard

11
IMO có từ "pwn" trong kịch bản của bạn rất xứng đáng với ký tự phụ.
ejrb

1
Tôi đồng ý với ejrb. Bạn có thể phá vỡ điều này xin vui lòng?
Tít

1
Thay thế ~'!'bằng ∩⎕Dđể lưu một nhân vật.
Adám

9

Con trăn 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)

Phiên bản dễ đọc hơn:

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)

Phá vỡ:

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
Giải pháp tốt đẹp. Tôi nghĩ bạn có thể thay thế '!'==i[0]bằng '!'in i, và có thể sử dụng a=x=1. Ngoài ra, bạn không cần dấu ngoặc quanh câu lệnh exec.
grc

1
Bạn cũng có thể thay thế (len(i)-1)bằng ~-len(i).
Biến động

@Volatility, grc: Cảm ơn! Tôi nên học các toán tử bitwise của mình :)
beary605

1
Câu trả lời hay, tôi đã tự do cố gắng thay thế câu lệnh if bằng (a,b)['!'in i]và quản lý để loại bỏ 6 ký tự. Nó không dễ đọc như mặc dù ... liên kết pastebin
ejrb

@erjb: Cảm ơn lời đề nghị! Tôi đã sử dụng 2 tuple với mã dưới dạng một chuỗi thẳng hàng với chức năng exec, giúp lưu thêm hai ký tự :)
beary605

8

GolfScript ( 48 44 43 ký tự)

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

Đây là một chương trình khép kín. Việc chuyển đổi factoriadic => chuyển đổi thập phân khá chậm, bởi vì nó thực hiện tìm kiếm bằng cách sử dụng chuyển đổi thập phân => factoriadic thay vì chuyển đổi cơ sở trực tiếp.

Định dạng đầu vào cho phép chuyển đổi chế độ rất ngắn: .~sao chép chuỗi đầu vào và đánh giá nó, vì vậy nếu đầu vào chỉ là một số chúng ta kết thúc bằng ví dụ "1234" 1234trên ngăn xếp và nếu nó bắt đầu bằng !(không logic, với bất kỳ không trống nào chuỗi là trung thực) chúng tôi kết thúc với ví dụ 0 30311trên ngăn xếp. Sau đó, giá trị ở dưới cùng của ngăn xếp là trung thực cho số thập phân => factoriadic và falsy cho factoriadic => thập phân.


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;

Chạy như ống với -rhoặc kiểm tra nó trực tuyến .

  • không cần gia hạn
  • không có chức năng phụ cần thiết: cơ sở giai thừa đang được sử dụng lại (bao gồm / giảm trong các vòng lặp)
  • số nguyên và chuỗi số nguyên, thậm chí sẽ hoạt động trong php 3 (và vẫn hoạt động trong php 7):
  • thập phân 0 trả về chuỗi rỗng thay vì 0. (cả hai câu trả lời PHP khác cũng vậy.) Nếu điều đó không được chấp nhận, hãy thêm +5 cho trường hợp thêm.

vô dụng:

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

ý tưởng chơi golf bị từ bỏ:

  • $b<=$x-> $b<$x(-1)
    sẽ phá vỡ các giai thừa thập phân thuần túy (tức là các yếu tố dẫn đến một số giai thừa chỉ có một chữ số khác không). Giải pháp JMPC hungs chịu đựng điều đó; HamZa hungs không.
  • floor($x/$b)-> (int)($x/$b)
    có thể nhanh hơn một chút, nhưng nhập phân chia trước phân chia, vì vậy tôi cần dấu ngoặc đơn và dont để đạt được một byte.
    $x/$b|0lừa
  • Vòng lặp trong thực tế-> dec tương tự như tìm hiểu giai thừa trong dec-> fact. Cùng một mức tăng, cơ thể không quan trọng, nhưng không may, cài đặt trước khác nhau và điều kiện bài khác nhau. Đăng; có thể đã chơi golf -21 ở đó.
    YAY tôi tìm thấy một giải pháp. Đã chơi khá nhiều môn đánh gôn, nhưng băm nhỏ -4 (không: -9) đóng tất cả các lỗi / sơ hở.

Còn tiềm năng nào nữa không ... hay tôi đã chơi golf chưa?


@ JörgHülsermann Cảm ơn bạn đã gợi ý.
Tít

1
+$rthay vì $r|0lưu một byte. Tương tự choif($x|0)
Jörg Hülsermann

3

JavaScript (ES 6) 139 137 122 113 111

đã thử một cách tiếp cận khác bằng cách sử dụng một số phép thuật mảng; nhưng tôi đã kết thúc ở mức 174 172 byte với điều đó:

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}

Vì vậy, tôi chỉ lấy mã PHP của tôi và dịch nó. Có thể loại bỏ tất cả $s và một vài ;, nhưng sự cần thiết phải khởi tạo các lọ đã ăn một số lợi ích đó. Quản lý để golf cả hai câu trả lời xuống một chút, mặc dù.

chơi gôn

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}
  • phiên bản đầu tiên trả về '' cho số thập phân 0; thêm +2 để sửa
  • phiên bản thứ hai yêu cầu đầu vào chuỗi
  • cả hai đã được thử nghiệm trong Firefox, Edge và Opera

vô dụng

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
}

bộ kiểm tra

<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 không có ký hiệu mũi tên IIRC. Và nếu bạn sẽ sử dụng ES6, thì .split('')=>.split``
Zacharý

@ Zacharý Gna Tôi nên lưu ý trình duyệt nào tôi đã thử nó trong ... có lẽ là Firefox hoặc Opera. Vậy ES 6?
Tít

Vâng, ký hiệu mũi tên là ES6.
Zacharý

1
Ồ, điều đó làm tôi mất cảnh giác, tôi nghĩ khối mã ở trên cùng là giải pháp của bạn! Bất kể, tôi không nghĩ bạn cần phải nói f=. Ngoài ra, có thể r+=(x/(b/=j--)|0)được r+=x/(b/=j--)|0?
Zacharý


1

GolfScript, 69 ký tự

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

Lấy đầu vào từ STDIN như bình thường và in kết quả. Kiểm tra trực tuyến .


1

Haskell, 221 ký tự

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

Sử dụng

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

Mã bị đánh cắp

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

Cho đến nay các mục dễ đọc nhất. Haskell FTW!
Soham Chowdhury

1

Toán học 213 177 175

Một số giai thừa được gói trong f[], cho dù đó là đầu vào hay đầu ra.

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

Sử dụng

z[24201]

f [349]

z[f[349]]

24201

Chuyển đổi giai thừa sang số thập phân . QuotientRemainder[n,j!]đệ quy hành động trên các chữ số của số giai thừa từ trái sang phải, giảm dần jở mỗi bước. QuotientRemainder[349, 5!], ví dụ, trả về {2, 109}và như vậy.

Chuyển đổi số thập phân sang số giai thừa . Di chuyển từ phải sang trái, hàm thuần túy # (p++)! &, nhân mỗi chữ số #, theo giai thừa thích hợp.


1

Python, 128 ký tự

Điều này mất khoảng nửa giờ để chạy, nhưng nó nhỏ:

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

Nó xây dựng một danh sách tất cả các số yếu tố <= 9 chữ số theo thứ tự số, sau đó thực hiện tra cứu hoặc lập chỉ mục để chuyển đổi.

Nếu bạn muốn kiểm tra, chỉ cần thay thế 10**9với 10**6và giới hạn mình vào số variadic 6 chữ số.

Về mặt kỹ thuật tôi có thể cứu một nhân vật bằng cách sử dụng range(10**9)thay vì xrange(10**9). Đừng thử điều này ở nhà.


Không có không gian là cần thiết giữa d+2for
Zacharý

1

PHP 231 214 204

Câu trả lời mới nhất

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

Câu trả lời cũ

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

Thí dụ

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

Đầu ra

24201
349
141120
101010
719
381

2
Tôi đếm 212 cho câu trả lời mới, không phải là 214. $ e không cần khởi tạo (-6) và foreach(range())có thể thay thế bằng một forvòng lặp đơn giản (-9). Tôi thích ý tưởng, mặc dù.
Tít

2
kết quả sai cho giai thừa. 24nên trả lại 1000nhưng trả lại 400. sửa chữa: g(++$p)<$x-> g(++$p)<=$x(+1)
Tít

@Titus Cảm ơn cả hai câu trả lời của bạn! Tôi cập nhật câu trả lời của tôi. Tôi đánh giá cao bạn giúp tôi cải thiện câu trả lời của tôi khi bạn có vẻ vượt trội hơn nhiều.
JPMC

1
1) Tôi đếm 2 ít hơn bạn, một lần nữa: 204, không phải 206. Bạn có bao gồm ngắt dòng Windows trong số byte của bạn không? 2) lỗi cú pháp trong forcấu trúc: ,nên là ;3) Tôi có 7 thay đổi khác lưu 20 byte trên mã đó. Muốn họ?
Tít

2
Chà, nó thực sự chỉ có 5 thay đổi, nhưng một trong số đó có ba phần. a) đối số thứ hai lỗi thời cho f () (-3) b) lỗi thời trong hàm g (-1) c) lỗi thời trong nhánh thực (-4) d) hoán đổi các nhánh đúng và sai, đảo ngược ifđiều kiện, sau đó sử dụng kiểu gợi cảm của tôi chuyển sang int (-6) Điều này sẽ không ảnh hưởng đến kết quả thập phân 0! e) forcấu trúc còn lại có thể được viết lại với một mức rất hay while(++$t<$c=strlen($x)): tăng trước thân -> $ t không cần khởi tạo (-6)
Tít

1

JELLY, 5 byte

Æ!ŒṘ€

Giải trình

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

* Jelly trẻ hơn so với tuổi của câu hỏi do đó câu trả lời của tôi là không thể hiểu được.


1
Chào mừng đến với PPCG! Tôi nghĩ Jelly trẻ hơn thử thách này, do đó bạn nên đánh dấu câu trả lời của mình là không cạnh tranh.
Laikoni

Oh tôi đã không nhận ra rằng đó là một quy tắc. Sẽ làm.
DaggerOfMesogrecia

Không có câu trả lời cho thách thức này có nghĩa là làm việc cả hai cách? Điều này dường như chỉ hoạt động một cách; bạn có thể muốn sửa nó. (Trên một lưu ý riêng, nếu bạn đang chuyển đổi giữa các số nguyên và chuỗi trong Jelly, thông thường sẽ khó nhất khi sử dụng một số kết hợp V.)

1

Thạch , 15 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Ḋ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

Tại sao *)làm việc

¬là yếu tố logic khôn ngoan KHÔNG. Khi được cung cấp một số nguyên duy nhất, nó trở thành một số không, là sai. Tuy nhiên, khi được cung cấp một chuỗi, mỗi phần tử (ký tự) được chuyển thành 0 và toàn bộ kết quả là một mảng các số 0 là đúng.

Số không là số nguyên là trường hợp đặc biệt. Nó đi qua tuyến đường "giai thừa -> số nguyên", nhưng nó vẫn cho số không đúng.

Không có cơ sở giai thừa tích hợp, 25 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Chắc chắn có thể được cải thiện.

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 ký tự)

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 và với điểm vào chương trình

Tất cả các đối số dòng lệnh được in dưới dạng <original> -> <converted>. Chỉ có thập phân đến yếu tố thực sự được thực hiện trong x. Cách khác, vòng chỉ gọi xvới tất cả các số thập phân (0 .. *) cho đến khi kết quả bằng với đầu vào. Quá trình này mất ~ 3 giây cho đầu vào lớn nhất (! 987654321).

Phiên bản trực tuyến có thể thực thi: 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;
}

Tôi nghĩ rằng nó có thể là có thể thay đổi string nđể char[]ntiết kiệm một byte (Tôi biết tôi đến trễ ở đây).
Zacharý

Ngoài ra, tôi nghĩ if(n[0]<48){while(r.text.x<n[1..$].to!int)r++;}có thể trở thành if(n[0]<48)while(r.text.x<n[1..$].to!int)r++;để lưu hai byte.
Zacharý

0

VBA 225

Cảm ơn Tít đã giúp đỡ! Vẫn đang tìm cách để chơi golf nhiều hơn.

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

Tôi không biết VBA, nhưng có cách nào để kiểm tra bgiá trị số thay vì so sánh ký tự đầu tiên không?
Tít

@Titus Có một kiểm tra số và tương đương ở đây sẽ là : If Not IsNumeric(b) Then, nhưng có nhiều ký tự hơn. Bây giờ, tôi đã không đi vào và kiểm tra lại tất cả các mã; có thể có một cách tốt hơn một chút để làm điều này với IsNumerictổng thể. - Sửa chữa, có một cải thiện nhỏ ở đây. Cảm ơn!
Gaffi

Tôi đã tìm thấy bốn byte khác: For d=9To 1Step-1Fact(d)-> For d=0To 8Fact(9-d)hai byte khác nếu bạn làm For d=2To eFact(e-d+1)*Mid(b,d,1)
Titus

Loại diễn viên để Int có thể được viết theo cách khác?
Tít

@Titus Nhìn bạn, chạy vòng quanh tôi. :) Bây giờ tôi đang điều chỉnh ... Đối với Int (), tôi không nghĩ có một phương pháp đơn giản hơn (nhỏ hơn), không.
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;

Hãy thử trực tuyến!

Mở rộng

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 ký tự, 72 byte

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

có vẻ như 10⊥ (9..2) tốt hơn hàm đệ quy, nhờ Howard cho giải pháp APL khác cho thấy rằng ... (ngay cả khi tôi không hiểu 100%). Nhập số mà không có '!' <10!. Kiểm tra:

  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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.