繰り返した!階乗!


34

階乗の検索と混同しないでください

前書き

整数の階乗はnnで計算できます = N × N - 1 × N - 2 × × 2 × 1

n!=n×(n1)×(n2)×(...)×2×1

これは比較的簡単で、新しいことは何もありません。ただし、階乗は、n !のように二重階乗に 拡張できます= N × N - 2 × N - 4 × × 4 × 2 偶数のため、及び N = N × N - 2 × N - 4 ×

n!!=n×(n2)×(n4)×(...)×4×2
n!!=n×(n2)×(n4)×(...)×3×1
奇数の場合。しかし、二重階乗に限定されません。たとえば、
n!!!=n×(n3)×(n6)×(...)×6×3
または
n!!!=n×(n3)×(n6)×(...)×5×2
または
n!!!=n×(n3)×(n6)×(...)×4×1
開始値に応じ。

要約すると、

n!(k)={1if n=0nif 0<nkn((nk)!(k))if n>k
n!(k)=n!!k
平易な英語で、または:基数から階乗カウントを繰り返し減算し、結果の正の整数をすべて乗算します。

チャレンジ

負でない整数に対して、あらゆる種類の反復階乗を計算する関数を作成します。

入力

どちらか

  • 10以上の負でない整数を含む文字列と、それに続く1つ以上の感嘆符。例えば"6!"または"9!!"または"40!!!!!!!!!!!!!!!!!!!!"

または

  • 2つの整数で表される同じ値:1つの非負のベース値と、階乗カウントを表す1つの正の値。これは、デフォルトのI / Oルールの任意の形式に従って実行できます。

出力

上記の計算の結果。

チャレンジ発言

  • 0!1定義により等しい。あなたのコードはこれを説明する必要があります。
  • 階乗カウントによって限定される
    0<factorial countbase value
    この範囲外を、あなたはどのような出力に含みません。を除き0!、これはこのルールの唯一の例外です。

Input                              Output

3!!!                               3
0!                                 1
6!                                 720
9!!                                945
10!!!!!!!!                         20
40!!!!!!!!!!!!!!!!!!!!             800
420!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  41697106428257280000000000000000

未実装のPython実装で試してくださいオンラインで試してください!

総論


6
例はリストされて0!いますが、課題のコメントは、階乗カウントがベース値以下になると述べています。
ジョナサンアラン

1
3つじゃない!!! ゼロになる?N *(N-3)= 3×(3-3)= 0
ouflak

2
@ouflak 1!のように動作する場合、実際にはそうではありません。1のようなものです!= 1. 2 !! = 2. 3 !!! = 3.再帰性の終わりにいるので、計算はありません。製品の0またはすべての階乗は、最終的に0に低下しません。
V.クルトワ

4
3!!!!!!!未定義であってはなりません3。答えを返すだけです。1!!=1(未定義ではない)と同じです。また、入力仕様には、常に少なくとも1つあることが示されている!ため、最初の例3は仕様に適合しません。
グレッグマーティン

3
@FabianRöling:しかし、これはそうではありません。(3!)!代わりに、階乗から用語を削除しているわけではありません。紛らわしい名前です。Factorial関数をチェーンで繰り返し適用することになると想定して、実際にそれが何であるかを確認するために注意深く読む必要がありました。幸いなことに、質問はそれを明確に説明しています。 より良い名前は、ストライド階乗またはステップ階乗などです。
ピーター・コード

回答:



13

ArnoldC702 698 634バイト

LISTEN TO ME VERY CAREFULLY f
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE n
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE p
GIVE THESE PEOPLE AIR
HEY CHRISTMAS TREE r
YOU SET US UP 1
HEY CHRISTMAS TREE c
YOU SET US UP 0
STICK AROUND n
GET TO THE CHOPPER r
HERE IS MY INVITATION r
YOU'RE FIRED n
ENOUGH TALK
GET TO THE CHOPPER n
HERE IS MY INVITATION n
GET DOWN p
ENOUGH TALK
GET TO THE CHOPPER c
HERE IS MY INVITATION 0
LET OFF SOME STEAM BENNET n
ENOUGH TALK
BECAUSE I'M GOING TO SAY PLEASE c
GET TO THE CHOPPER n
HERE IS MY INVITATION 0
ENOUGH TALK
YOU HAVE NO RESPECT FOR LOGIC
CHILL
I'LL BE BACK r
HASTA LA VISTA, BABY

オンラインでお試しください!

擬似コードに変換:

f(n,p) {
  r=1;
  c=0;
  while (n) {
    r=r*n;
    n=n-p;
    c=n<0;
    if (c) n=0;
  }
  return r;
}

注:ArnoldCには、16ビットの符号付き整数という1種類のデータしかありません。したがって、420!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!ケースをテストすることはできません。


あなたの擬似コードに興味があります。変数「c」とは何ですか?
ouflak

@ouflak回答を数回編集して忘れました。c変数は、実際の比較値記憶nとを0
チャーリー

+1し、LUAの回答にそれを借りました(「c」を除く)。
ouflak

12

ゼリー、4 バイト

RṚmP

オンラインでお試しください!

nkn,,1RṚmkthn,nk,n2k,,nn/kkP


うまく機能し、最終的にはとても簡単です。ゼリーはまったく知りませんが、少なくとも見た目は良さそうです:)
V.クルトワ

1
nkn,,1RṚmk番目nnkn2knn/kkP

どうもありがとうございます。私はそれらのモナドを習得する必要がありますので、ある日、私はダイアドなど、この言語でゴルフをしたいかもしれません
V.クルトワ

:CJamのように見えることオルタナティブr1mP
アウトゴルファーのエリック

1
@KyeWShi Jellyには独自の コードページがあるため、それに含まれる256文字のそれぞれが1バイトとしてエンコードされます。
Xcoder氏


7

Haskell、21バイト

n%a=product[n,n-a..1]

オンラインでお試しください!

組み込みの製品関数と段階的な範囲の列挙を組み合わせると、再帰的にコード化できるものよりも優れています(flawrがバイトを保存する場合でも)。

22バイト

n%a|n<1=1|m<-n-a=n*m%a

オンラインでお試しください!

以下は、文字列形式で入力を取得するソリューションです 9!!です。

42バイト

(\[(n,a)]->product[n,n-length a..1]).reads

オンラインでお試しください!


2
再帰解を短くすることができると思いますn%a|n<1=1|m<-n-a=n*m%a
flawr



5

空白、91バイト

[S S S T    N
Push_1][S N
S _Duplicate_1][S N
S _Duplicate_1][T   N
T   T   _Read_STDIN_as_integer_(base)][T    T   T   _Retrieve_base][S S S N
_Push_0][T  N
T   T   _Read_STDIN_as_integer_(factorial)][N
S S N
_Create_Label_LOOP][S N
S _Duplicate_base][S S S T  N
_Push_1][T  S S T   _Subtract][N
T   T   S N
_If_negative_jump_to_Label_PRINT_RESULT][S N
S _Duplicate_base][S T  S S T   S N
_Copy_0-based_2nd_(result)][T   S S N
_Multiply][S N
T   _Swap_top_two][S S S N
_Push_0][T  T   T   _Retrieve_factorial][T  S S T   _Subtract][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_PRINT_RESULT][S N
N
_Discard_top][T N
S T _Print_result_as_integer]

強調表示としてのみ追加される文字S(スペース)、T(タブ)、およびN(改行)。
[..._some_action]説明としてのみ追加。

オンラインで試してください(未加工のスペース、タブ、改行のみ)。

擬似コードの説明:

Integer result = 1
Integer base = STDIN as integer
Integer factorial = STDIN as integer
Start LOOP:
  If(base <= 0):
    Call function PRINT_RESULT
  result = result * base
  base = base - factorial
  Go to next iteration of LOOP

function PRINT_RESULT:
  Print result as integer to STDOUT



4

05AB1E10 8 7 バイト

ݦRIιнP

2つの別々の入力として入力:最初の入力は base ; 第二の入力ビーイングfactorial

オンラインで試すか、、すべてのテストケースを検証します

@ Mr.Xcoderのおかげで-2バイト。@JonathanAllanの
おかげで-1バイト

説明:

Ý        # Create a list in the range [0, (implicit) base-input]
 ¦       # And remove the first item to make it the range [1, base]
         # (NOTE: this is for the edge case 0. For the other test cases simply `L` instead
         #  of `ݦ` is enough.)
  R      # Reverse this list so the range is [base, 1]
   Iι    # Uninterleave with the second input as step-size
         #  i.e. base=3, factorial=7: [[3],[2],[1],[],[],[],[]]
         #  i.e. base=10, factorial=8: [[10,2],[9,1],[8],[7],[6],[5],[4],[3]]
         #  i.e. base=420, factorial=30: [[420,390,360,...,90,60,30],[419,389,359,...],...]
     н   # Only leave the first inner list
      P  # And take the product of its values
         # (which is output implicitly as result)

元の10 バイトの回答:

L0KD¤-IÖÏP

2つの別々の入力として入力します。最初の入力はbase ; 第二の入力ビーイングfactorial

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

L           # Create a list in the range [1, (implicit) base-input]
 0K         # Remove all 0s (edge case for input 0, which will become the list [1,0])
   D        # Duplicate this list
    ¤       # Get the last value (without popping)
            # (could also be `Z` or `¹` for max_without_popping / first input respectively)
     -      # Subtract it from each item in the list
      IÖ    # Check for each if they're divisible by the second factorial-input
        Ï   # In the list we copied, only leave the values at the truthy indices
         P  # And take the product of those
            # (which is output implicitly as result)

1
この6 byter: LR²ιнPオンラインをお試しください!)すべてのテストケースのために働く、0を除いて
氏Xcoder

しかし、0の場合は最大2バイトで修正できると思います。あなたがそれを修正する方法を見つけたら、あなたはそれを取るかもしれません:) 編集:おそらくLR²ιн0KP8バイトですか?
Xcoder氏

@ Mr.Xcoderいい答えです!与えられたステップでインターリーブを使用しないでください。:)
ケビン・クルーッセン

0K0!(例に含まれていたとしても)仕様による無効な入力であるため、不要である必要があります- これについてコメントしました。
ジョナサンアラン

1
...また、入力ドメインにある場合 0!ݦRXιнPバイトを節約します。
ジョナサンアラン

4

x86-64マシンコード、12バイト

同じマシンコードは、32ビットモードでも、16ビットモードでは16ビット整数でも同じことを行います。

これは、args n=RCXで呼び出し可能な関数k=ESIです。32ビットの戻り値EAX

x86-64 System Vの呼び出し規約を使用してCから呼び出し可能。ダミーの引数を使用して、実際の引数を正しいレジスタに入れます。uint32_t factk(int, uint32_t k, int, uint64_t n); 1オペランドがmulRDXを使用するため、Windows x64を使用することはできませんでした。REXプレフィックスがR8 / R9にアクセスすることは望ましくありません。 nJRCXZが機能するように上位32ビットにガベージが含まれていてはなりませんが、それ以外はすべて32ビットです。

NASMリスト(相対アドレス、マシンコード、ソース)

 1                         factk:
 2 00000000 6A01             push 1
 3 00000002 58               pop rax             ; retval = 1
 4 00000003 E306             jrcxz  .n_zero      ; if (n==0) return
 5                         .loop:                ; do {
 6 00000005 F7E1              mul   ecx            ; retval *= n  (clobbering RDX)
 7 00000007 29F1              sub   ecx, esi       ; n -= k
 8 00000009 77FA              ja   .loop         ; }while(sub didn't wrap or give zero)
 9                         .n_zero:
10 0000000B C3               ret

0xc = 12バイト


または、n=0特殊なケースを処理する必要がなかった場合は10バイトで、jrcxz

標準の階乗ではloop、sub / jaの代わりに2バイトを節約しますが、それ以外はまったく同じコードです。


argcとして渡す呼び出し元をテストしknハードコーディングします。

align 16
global _start
_start:
  mov  esi, [rsp]
;main:
  mov  ecx, 9
  call factk

  mov  esi, eax
  mov  edx, eax
  lea  rdi, [rel print_format]
  xor  eax, eax
extern printf
  call printf
extern exit
  call exit

section .rodata
print_format: db `%#x\t%u\n`

```




3

Java 10、44バイト

f->b->{int r=1;for(;b>0;b-=f)r*=b;return r;}

階乗を最初の入力、ベースを2番目として入力します。

オンラインでお試しください。

これは、整数範囲(32ビット)が制限されているため、最大のテストケースでは機能しません。これを修正するために、我々は使用することができBigIntegersた、偶然を正確にサイズのダブル- 88 79バイト

f->b->{var r=f.ONE;for(;b.signum()>0;b=b.subtract(f))r=r.multiply(b);return r;}

@OlivierGrégoireのおかげで-9バイト

オンラインでお試しください。

説明:

f->b->{       // Method with two integer parameters and integer return-type
  int r=1;    //  Result-integer, starting at 1
  for(;b>0;   //  Loop as long as the base is still larger than 0
      b-=f)   //    After every iteration: decrease the base by the factorial
    r*=b;     //   Multiply the result by the base
  return r;}  //  Return the result


@OlivierGrégoireNp、ありがとう!:)
ケビン・クルーッセン



2

MathGolf7 6バイト

╙╒x%ε*

オンラインでお試しください!

0を処理する賢い方法を見つけました!他のテストケースを変更することなく。入力をk n(逆順)として受け取ります。これは、暗黙的なポップを支援します。

説明

╙        maximum of two elements (pops largest of k and n,
         which is n for every valid case except 0!, where 1 is pushed)
 ╒       range(1,n+1)
  x      reverse int/array/string
   %     slice every k:th element
    ε*   reduce list with multiplication

2

アタッシュ21 19バイト

${x<y∨x*$[x-y,y]}

オンラインでお試しください!かなり直接的な再帰的実装。(注:算術演算で使用できるため、true本質的1にです1です。)これは、ユニコード演算子を使用するとバイト(正確には1)を節約するこのサイト用に作成した数少ないプログラムの1つです。

代替案

20バイト: ${x<y or x*$[x-y,y]}

21バイト: Prod@${{_%y=x%y}\1:x}

27バイト: ${x*[`1,$][x>y][x-y,y]∨1}

27バイト: ${If[x>y,x*$[x-y,y],_or 1]}

27バイト: ${x*[`1,$][x>y][x-y,y]or 1}

29バイト: ${If[x>y,x*$[x-y,y],_+not _]}


2

Rust92 73 61バイト

fn f(n:i128,k:i128)->i128{if n<=0{return 1}return n*f(n-k,k)}

さびを習い始めたばかりなので、もっと短くできると確信しています。私が学ぶと更新されます。戻り値はi128、最後のテストを計算するためのものでなければなりません。

編集:再帰が短くなります。

オンラインでお試しください!

独自のテストを追加するか、既存のテストのいずれかを編集できます。


2

q59 57 55 53バイト

{prd 2+(&)1_i=last i:("J"$x(&)not[n])#(!)sum n:"!"=x}

説明:

q)x:"12!!" / let our input be 12!!, assign to x
q)sum n:"!"=x / count "!"s
2i
q)(!)sum n:"!"=x / (!)m -> [0,m)
0 1
q)("J"$x(&)not[n]) / isolate the number in input
12
q)("J"$x(&)not[n])#(!)sum n:"!"=x / x#y means take x items from list y, if x>y, circle around
0 1 0 1 0 1 0 1 0 1 0 1
q)i:("J"$x(&)not[n])#(!)sum n:"!"=x / assign to i
q)i
0 1 0 1 0 1 0 1 0 1 0 1
q)(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / take last elem of i and see which are equal in i
010101010101b
q)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / drop first elem
10101010101b
q)(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / indices of 1b (boolean TRUE)
0 2 4 6 8 10
q)2+(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / add 2 across array
2 4 6 8 10 12
q)prd 2+(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / product across array
46080

ここもk(同じロジック)、42 41バイトのバージョンです

{*/2+&1_i=last i:("J"$x@&~:n)#!+/n:"!"=x}

サイトへようこそ!投稿にコードの書式設定を追加しました。これは、行の前に4つのスペースを使用するか、3つのバッククォートで囲むことで実行できます。
ウィートウィザード

@ SriotchilismO'Zaicありがとう:-)
走り書き

1
説明と、おそらくTIOのようなオンライン通訳へのリンクを追加することをお勧めします。通常、コードのみの回答には、低品質として自動的にフラグが付けられます。
mbomb007

@ mbomb007面白い。ボットがフラグを立てる回答はありますか?低品質の提出物はどうなりますか?私はすぐに更新します!
15:09に走り書き

はい、ボットがあります。StackExchangeはボットを使用して、潜在的なスパムと低品質の回答を探します。評価が十分に高い人はレビューキューを表示できます。meta.stackexchange.com/a/161391/285610
mbomb007


1

網膜、66バイト

^0
1
\d+
*!,
+`(!+)(!+),\1$
$1$2,$2,$1
!+$
1
+`(!+),(\d+)
$.($2*$1

オンラインでお試しください!リンクには、より高速なテストケースが含まれています。感嘆符のないモール数。説明:

^0
1

修正し0!ます。

\d+
*!,

n単項に変換し、セパレータを追加します。

+`(!+)(!+),\1$
$1$2,$2,$1

繰り返し引くkからnwhilen>k、結果を収集します。

!+$
1

交換するk1(10進数)。

+`(!+),(\d+)
$.($2*$1

各中間値を順番に乗算し、10進数に変換します。




1

Forth(gforth)、50バイト

: f 1 1 2over / 1+ 0 do 2over i * - 1 max * loop ;

オンラインでお試しください!

コードの説明

: f                \ start a new word definition
  1 1              \ add placeholder and accumulator to stack
  2over / 1+       \ get the number of times to run the loop (num/factorial + 1)
  0 do             \ start loop from 0 to num/factorial
    2over          \ copy num and factorial to the top of the stack
    i * -          \ get the current number to multiply by (num - factorial * i)
    1 max          \ make sure it can't be 0 or negative [set to 1 if it is]
    *              \ multiply accumulator by result
  loop             \ end loop
;                  \ end the word definition           



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.