この数は素数ですか?


195

信じられないかもしれませんが、単純な素数性テストのためのコードゴルフチャレンジはまだありません。特に「通常の」言語の場合、これは最も興味深い課題ではないかもしれませんが、多くの言語では自明ではありません。

Rosettaコードは、素性テストに対する慣用的なアプローチの言語ごとのリストを特徴としており、1つはMiller-Rabinテストを具体的に使用し、もう1つは試験部門を使用しています。ただし、「最も慣用的」は「最短」と一致しないことがよくあります。プログラミングパズルとコードゴルフをコードゴルフの人気サイトにするために、この課題では、「Hello、World!」と同様に、すべての言語での最短アプローチのカタログを作成しようとしていますそして、あなたのために素晴らしい馬をゴルフしましょう!

さらに、素数性テストを実装する機能はプログラミング言語の定義の一部であるため、この課題は実証済みのプログラミング言語のディレクトリとしても機能します。

仕事

入力として厳密に正の整数nが与えられると、nが素数であるかどうかを判断し、それに応じて真実または偽の値を出力する完全なプログラムを作成します

この課題のために、厳密に正の約数が2つだけある整数は素数です。これは、唯一の厳密に正の除数である1を除外することに注意してください。

アルゴリズムは決定論的である必要があり(つまり、確率1で正しい出力を生成する)、理論上、任意の大きな整数に対して機能する必要があります。実際には、プログラムが1〜255の整数で機能する限り、入力をデータ型に格納できると想定できます。

入力

  • 言語がSTDINからの読み取り、コマンドライン引数またはユーザー入力の他の代替形式の受け入れが可能な場合、整数をその10進表現、単項表現(選択した文字を使用)、バイト配列(大きなまたはリトルエンディアン)またはシングルバイト(これがあなたの言語の最大のデータ型である場合)。

  • あなたの言語がどんな種類のユーザー入力も受け入れられない場合(そしてその場合のみ)、プログラムで入力をハードコードすることができます。

    この場合、ハードコードされた整数は簡単に交換可能でなければなりません。特に、プログラム全体の1か所にしか表示されない場合があります。

    スコアリングの目的で、入力1に対応するプログラムを送信します。

出力

出力はSTDOUTまたは最も近い代替に書き込まれる必要があります。

可能であれば、出力は真偽値または偽の値(またはその文字列表現)のみで構成され、必要に応じて単一の改行が続きます。

この規則の唯一の例外は、挨拶、ANSIカラーコード、インデントなど、抑制できない言語のインタープリターの一定の出力です。

追加のルール

  • これは、プライムテストの最短アプローチで言語を見つけることではなく、すべての言語で最短アプローチを見つけることです。したがって、回答は承認済みとしてマークされません。

  • ほとんどの言語での提出物は、適切な既存のエンコーディングでバイト単位でスコアリングされます。通常は(必ずしもそうではありませんが)UTF-8です。

    たとえば、言語Pietはコーデルでスコアリングされますが、これはこの言語の自然な選択です。

    Foldersのような一部の言語は、スコア付けが少し難しいです。疑問がある場合は、Metaで質問してください。

  • 通常のルールとは異なり、このチャレンジよりも新しい言語(または言語バージョン)を自由に使用できます。空のプログラムが素数性テストを実行する言語を作成することでこれを悪用したい場合は、非常に退屈な答えへの道を開くことを祝福します。

    提出物をテストできるように、通訳が必要であることに注意してください。以前に実装されていない言語用にこのインタープリターを自分で作成することは許可されています(さらには推奨されています)。

  • 選択した言語が、すでに回答を持っている別の(潜在的により人気のある)言語の些細なバリアントである場合(BASICまたはSQL方言、Unixシェル、またはHeadsecksやUnaryのような些細なBrainfuck派生語を考えてください)、既存の回答にメモを追加することを検討してください同じまたは非常に類似したソリューションは、他の言語でも最短です。

  • 素数性をテストするための組み込み関数許可されています。この課題は、各言語で可能な限り最短のソリューションをカタログ化することを目的としているため、言語の組み込みを使用する方が短い場合は、それを選択してください。

  • それらが以前に無効にされていない限り、http://meta.codegolf.stackexchange.com/q/1061を含む、すべての標準規則が適用されます。

補足として、ゴルフにそれほど価値のない言語では、退屈な(しかし有効な)答えに投票しないでください。これらは、カタログを可能な限り完全にコンパイルしようとするので、この質問には依然として有用です。ただし、主に作成者がコードのゴルフに力を入れなければならない言語では、主に回答を支持してください。

カタログ

この投稿の下部にあるスタックスニペットは、a)言語ごとの最短ソリューションのリストとして、b)全体的なリーダーボードとして、回答からカタログを生成します。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

## Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

## Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

## Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、スニペットに表示することもできます。

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


入力を負の数として受け取ることはできますか?abs(input)がテストする数になりますか?
スタンストラム

いいえ、入力は厳密に正の整数です。
デニス

1
@LyndonWhiteこれは、素数性テストのカタログ(「Hello、World!」など)を意図していたため、統一された提出形式が望ましいと思われました。後悔するのは、この課題に関する2つの決定のうちの1つであり、もう1つは決定論的な素数性テストのみを許可することです。
デニス

1
@Shaggyはメタに対する質問のようです。
デニス

1
ええ、それは私が考えていたことです。それがあなたの挑戦であるように、私はあなたに名誉をやらせます。
シャギー

回答:


226

こんにちは世界!、13

hello, world!

83
あなたは、のような、なかっただけで、この言語を作成するだけで、この提出のために?;)
ETHproductions

41
@ETHproductions最新のコミットは10日前だったようです。
ジオビット

39
どこかにリンクする前に言語を少し良い形にしたいと思っていましたが、この課題が投稿され、抵抗できませんでした。
-histocrat

31
1の入力にハングアップするのは正しい機能だとほぼ言えるでしょう。
iamnotmaynard

22
これに関する最良の部分は、プログラムが単なる組み込みではなく、各キャラクターが正しい結果を得るために独自の役割を果たすということです。
ETHproductions

157

六角形、29バイト

.?'.).@@/'/.!.>+=(<.!)}($>(<%

このコードの読み取り可能なバージョンは次のとおりです。

   . ? ' .
  ) . @ @ /
 ' / . ! . >
+ = ( < . ! )
 } ( $ > ( <
  % . . . .
   . . . .

説明:nを分割する2からn-1までの数があるかどうかをテストします。

初期化:

一方のメモリセルにnを書き込み、もう一方のメモリセルにn-1を書き込みます。

   . ? ' .
  . . . . .
 . . . . . .
+ = ( . . . .
 . . . . . .
  . . . . .
   . . . .

特別なケースn = 1:

0を出力して終了します

   . . . .
  . . . @ .
 . . . ! . .
. . . < . . .
 . . . . . .
  . . . . .
   . . . .

ループ

n%aを計算し、aを減らします。a = 1またはn%a = 0の場合は終了します。

   . . . .
  ) . . . /
 ' / . . . >
. . . . . . .
 } ( $ > ( <
  % . . . .
   . . . .

ケースa = 1:

0を1に増やして印刷し、終了します。(命令ポインターはNE方向に実行され、東の隅から南西の隅にループします。$は次のコマンドを無視することを確認します)

   . . . .
  . . . @ .
 . . . ! . .
. . . < . . )
 . . $ . . <
  . . . . .
   . . . .

ケースa%n = 0:

0を出力して終了します(命令ポインタはSWを実行しており、@の先頭にループします

   . . . .
  . . @ . .
 . . . . . >
. . . . . ! .
 . . . . . .
  . . . . .
   . . . .

61
なんてこった、それは印象的な最初の投稿の1つです。:)すぐに賞金を差し上げます(回答にさらに注意を払うために、7日以内に授与します)。PPCGへようこそ!
マーティンエンダー

35
素晴らしい答えです!「このコードの読み取り可能なバージョンは次のとおりです:<...> " :
agtoever

68

六角形218 92 58 55バイト

注意:この答えは、Etoplayによるサイドレングス4ソリューションで確実に打ち負かされました。

)}?}.=(..]=}='.}.}~./%*..&.=&{.<......=|>(<..}!=...&@\[

史上初の非自明(つまり、非線形)ヘキサゴニープログラム!Sp3000のLabyrinth answerと同じ2乗要因アプローチに基づいています。サイズ10の六角を始めた後、私はしかし、大きさ5にそれを圧縮するために管理し、私はいくつかの重複したコードを再利用することができましたし、今でもコードでノーオペレーションの非常にたくさんありますので、サイズ4は、かもしれないだけ可能です。

説明

コードを理解するために、最初にコードを展開する必要があります。Hexagonyは、すべてのソースコードを次の中央に配置された六角形の番号に無操作(.)でパディングします61。次に、コードを対応するサイズの通常の六角形に再配置します。

     ) } ? } .
    = ( . . ] =
   } = ' . } . }
  ~ . / % * . . &
 . = & { . < . . .
  . . . = | > ( <
   . . } ! = . .
    . & @ \ [ .
     . . . . .

これは、実行パスと複数の命令ポインター(IP)が交差して重なり合っているため、非常に重くなります。それがどのように機能するかを説明するために、最初に制御フローがエッジを通過せず、1つのIPのみが使用され、実行パスが可能な限り単純な、非ゴルフバージョンを見てみましょう。

             . . . . . . . . . . . . .
            . . . . . . . . . . . . . .
           . . . . . . . . . . . . . . .
          . . . . . . . . . . @ . . . . .
         . . . . . . . . . . ! . . . . . .
        . . . . . . . . . . % . . . . . . .
       . . . . . . . . . . ' . . . . . . . .
      . . . . . . . . . . & . . . . . . . . .
     . . . . . . . . . . { . . . . . . . . . .
    . . . . . . . . . . * . . . . . . . . . . .
   . . . . . . . . . . = . . . . . . . . . . . .
  . . . . . . . . . . } . . . . . . . . . . . . .
 ) } ? } = & { < . . & . . . . . . . . . . . . . .
  . . . . . . . > ( < . . . . . . . . . . . . . .
   . . . . . . = . . } . . . . . . . . . . . . .
    . . . . . } . . . = . . . . . . . . . . . .
     . . . . | . . . . | . . . . . . . . . . .
      . . . . * . . . ) . . . . . . . . . . .
       . . . . = . . & . . . . . . . . . . .
        . . . . > } < . . . . . . . . . . .
         . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . .
           . . . . . . . . . . . . . . .
            . . . . . . . . . . . . . .
             . . . . . . . . . . . . .

サイドノート:上記のコードは、no-opsでいっぱいの最初の行を実行することから始まります。次に、IPが北東の端に到達すると)、実際のコードが始まる左端の角()に折り返されます。

始める前に、Hexagonyのメモリレイアウトについて一言。ステロイドに関するBrainfuckのテープに少し似ています。実際には、テープではなく、六角形のグリッド自体(無限グリッド)であり、各エッジには最初は0の整数値があります(標準のBrainfuckとは対照的に、値は任意精度の符号付き整数です)。このプログラムでは、4つのエッジを使用します。

ここに画像の説明を入力してください

エッジAで階乗を計算し、エッジCで入力をカウントダウンし、エッジDで(モジュロの)入力の別のコピーを保存します。Bは、計算の一時的なエッジとして使用されます。

メモリポインター(MP)はエッジAから始まり、北を指します(これはMPを移動するために重要です)。次に、コードの最初のビットを示します。

)}?}=&{

)階乗の基礎としてエッジAを増分します1}MPを右折させます。つまり、エッジC(北東を指す)に移動します。ここでは、入力を整数として読み取ります?。その後、我々はエッジに別の右折を取るD}Cと=共有する頂点を指すようにMPを反転します。値をC(入力)からDにコピーします-現在の値が正でない(ゼロ)ため、値は左からコピーされます。最後に、MPを使用してCに左折します。&{

次に、<技術的にはブランチですが、現在の値が正であることがわかっているため、IPは常に右に曲がり>ます。サイドからヒットしたブランチはミラーとして機能し、IPがに向かって再び水平に移動し、C(の値が減少します。

次の分岐は、<ある実際に今の枝。これは、からどのように我々のループであるn-1まで1Cの現在の値が正である間、IPは右折します(ループを実行するため)。ゼロに達すると、代わりに左に曲がります。

ループの「body」を見てみましょう。ザ・は|、単純なミラーである、><も再びミラーとして使用されています。つまり、実際のループ本体は

}=)&}=*}=

}MPは、エッジに移動B=頂点面にその方向逆転ABCを)値をインクリメントします。これは、Bの値がまだゼロである最初の反復にのみ関係します。次の命令&隣、つまりA、つまり階乗の現在の値をコピーするように、それが正であることを確認したいBへの計算。

}その後にMPを移動A=共通の頂点に直面し、再びそれを反転させます。*両方の近傍、つまりエッジBCを乗算し、結果をAに保存します。最後に、頂点ABCを向いたままC}=に戻る別の要素があります。

これn-1Aの階乗をどのように計算するかをご覧いただければ幸いです。

これで、Cのループカウンターはゼロになりました。階乗を二乗してから、入力でモジュロを取ります。それがこのコードが行うことです:

&}=*{&'%!@

Cはゼロなので&、左隣、つまりAの階乗をコピーします。}=*移動Bに格納する要因の2つのコピーの生成物(即ち、四角)BC{戻りますが、MPを元に戻しません。現在の値が正であることがわかっているため、入力をDからCにコピーします。MP を右に後方に、つまりAに向かって。階乗の二乗はBにあり、入力はCにあることに注意してください。ですから、探しているものを正確に計算します。&'%(n-1)!^2 % n!結果を整数(0または1)として出力し@、プログラムを終了します。


わかりましたが、それは無料版です。ゴルフバージョンはどうですか?Hexagonyについてさらに2つのことを知る必要があります。

  1. エッジはラップアラウンドします。IPが六角形の端に当たると、反対側の端にジャンプします。IPがまっすぐに角に当たるとこれはあいまいになるため、角に当たると分岐としても機能します。現在の値が正の場合、IPは右側のグリッドエッジにジャンプし、そうでない場合は左側にジャンプします。
  2. 実際には6つの IP があります。それらはそれぞれ異なるコーナーで始まり、エッジに沿って時計回りに動きます。一度にアクティブになるのは1つだけです。つまり、他の5つのIPが必要ない場合は、それらを無視できます。で次のIPに(時計回りに)切り替え]、前のIPにで切り替えることができ[ます。(で特定のものを選択することもできます#が、それはまた別の機会です。)

また、いくつかの新しいコマンドがあります:\との/ようなミラーで、現在の値に|~掛けます-1

それでは、ゴルフのないバージョンはゴルフのバージョンにどのように変換されますか?線形セットアップコード)}?}=&{と基本的なループ構造は、次の場所にあります。

        ) } ? } .  ->
       . . . . . .
      . . . . . . .
     . . . . . . . .
->  . = & { . < . . .
     . . . . . > ( <
      . . . . . . .
       . . . . . .
        . . . . .

ループボディはエッジを数回横切りますが、最も重要なことは、実際の計算は前のIP(左隅から始まり、北東に移動する)に渡されることです。

        ) . . . .
       = . . . ] .
      } = . . } . .
     ~ . / . * . . .
    . . . . . . . . .
     . . . = . > ( <
      . . } . = . .
       . & . \ [ .
        . . . . .

ブランチを南東に向けて跳ね返った後、IP =は左上隅の2つにエッジの周りを回り(一緒に、何もしない)、その後、跳ね返ります/~その後の反復のために重要であり、現在の値の符号を反転します。IPは再び同じエッジをラップし、最終的[に制御が他のIPに渡されます。

これ~}=)&}=*}は、否定を取り消すように実行され、次に、ループされていないループ本体を実行します(マイナス=)。最後に、]どちらの手が元のIPに制御を戻すかがヒットします。(次回、このIPを実行すると、中断したところから開始するため、最初にコーナーにヒットします。IPが北西端に戻るには、現在の値が負である必要があります。南東の代わりに。)

元のIPが制御を再開すると、で跳ね返り\、残りのIPを実行して=からヒット>して、次のループ反復に送り込みます。

さて、本当にクレイジーな部分:ループが終了するとどうなりますか?

        ) . . . .
       . ( . . ] =
      . . ' . } . }
     . . . % * . . &
    . . . . . . . . .
     . . . = | . . <
      . . } ! . . .
       . & @ . . .
        . . . . .

IPはから北東に移動<し、北東の対角線に回り込みます。そのため、ループ本体と同じ実行パスになります(&}=*}])。少なくとも別のコードを追加する場合は、これがまさにこの時点で実行したいコードである=}ため}=}です(実際はに等しいため{)。しかし、これが実際に以前のループに再び入らないのはどうしてですか?]これは、右上隅から始まり、南西に移動する(今のところ未使用の)IPである次のIPに変更されるためです。そこから、IPはエッジに沿って続き、左上隅に折り返され、対角線を下に移動し、跳ね返り、線形コードの最後のビットを実行|@ながら終了します。

=}&)('%!@

(これ)(はもちろんノーオペレーションです- が既に存在していた(ので追加しなければなりませんでした)。)

ふう...なんて混乱...


いいね!これはどれくらい新しいですか?また、あなたは安定版リリースを取得するたびesolangsページを作成することを望むかもしれない
mbomb007

18
@ mbomb007私は2日前に言語を実装しました(その前に2、3日かけて設計しました)。そして、はい、間違いなくesolangsページを追加しますが、仕様はまだ100%安定していないと思います(たとえば、まだ3つの未割り当てコマンドがあります)。より安定していると感じたら、エソランとメタ投稿の両方に追加します。
マーティンエンダー

拡張されたヘックスの下では、左端の角(1)に折り返されます。そこで何1について話しているのですか?
mbomb007

@ mbomb007が修正されました。)するために使用1
マーティンエンダー

5
それがどのように機能するかの説明の詳細レベルのためだけに+1。より多くの人々がより多くの人々がそれらを使用できる詳細な例が付属している場合:D
jdarling

66

Pyth、4バイト

}QPQ

印刷TrueまたはFalse


12
私はこれが古いことを知っていますが、今では次のようにすることもできます:P_Qと1バイトを保存します。
drobilc

14
可能になりましたP_
ブルー

3
@drobilc関数は、引数を期待しているときは、EOFとして、Qをカットすることができ、それは入力を使用しています
スタン・ストラム

55

網膜、16バイト

^(?!(..+)\1+$)..

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

古典から始めましょう:regexで素数を検出します。入力は、繰り返し印刷可能な文字を使用して、単項で指定する必要があります。テストスイートには、便宜上10進数から単項への変換が含まれています。

1行で構成されるRetinaプログラムは、その行を正規表現として扱い、入力で見つかった一致数を出力します。これは0、合成数と1素数になります。

先読みは、入力が合成されないことを保証します:バックトラッキングは、のすべての可能な部分文字列(少なくとも2文字)を(..+)試行し、その後、先読みは、ここでキャプチャされたものを繰り返すことで入力の残りを一致させようとします。これが可能であれば、入力の除数が1より大きいが、それ自体よりも小さいことを意味します。その場合、負の先読みにより一致が失敗します。プライムの場合、そのような可能性はなく、試合は続きます。

唯一の問題は、この先読みも受け入れることです1。そのため、少なくとも2つの文字をに一致させることで除外し..ます。


プライムは通常の言語を形成しないため、実際には不規則な表現です。
PyRulez

@PyRulez実際のほとんどの正規表現フレーバーは、正規表現の理論的概念よりもはるかに強力です。私は言い回しを改善しました。
マーティンエンダー

1
現在公開されている最も強力な「正規表現」エンジンは、線形有界オートマトンと同等の認識力を備えています。標準の問題の正規表現、パターンの再帰、無制限のルックヘッド、無制限のルックビハインドは、コンテキスト依存の解析に必要なものすべてです(ただし、後方参照などは効率的な解析を複雑にするのに一般的に役立ちます)。コードを正規表現に埋め込むことができるエンジンを開始してはいけません。
eaglgenes101

52

CJam、4バイト

qimp

CJamには、素数性テスト用の組み込み演算子があります。


18
また:limp
SP3000

43
pimp私のチャム。
flawr

12
pimp客観的にもっとポン引き
MickLH

1
できることl~mp
牛は

12
@Cyoceは、q入力行を読み取りi、整数として解析しmp、組み込みです。CJamには2文字の組み込みの2つのグループがあります。「拡張された」ものが始まりe、「数学的な」ものが始まりますm
ピーターテイラー

48

HTML + CSS、最大 254 + n * 28バイト

正規表現を使用して素数をチェックできます。Mozillaには@document、次のように定義されています。

@document [ <url> | url-prefix(<string>) | domain(<string>) | regexp(<string>) ]# {
  <group-rule-body>
}

現在のURLに基​​づいてCSSを介して要素をフィルタリングします。これは単一のパスなので、2つのステップを実行する必要があります。

  1. ユーザーからの入力を取得します。この入力は何らかの形で現在のURLに反映される必要があります。
  2. できるだけ少ないコードでユーザーに返信します。

1.入力を取得する

入力を取得してそれをURLに転送するために考えられる最も短い方法は、GETチェックボックスのあるフォームです。正規表現の場合、出現回数をカウントするための一意の文字列が必要です。

したがって、これから始めます(61バイト):

<div id=q><p id=r>1<p id=s>0</div><form method=GET action=#q>

<p>入力した数値が素数(1)かそうでない(0)かを示す2つの一意のs を取得しました。フォームとそのアクションも定義します。

同じ名前のn個の最大チェックボックス(n 最大 * 28バイト):

<input type=checkbox name=i>

送信要素が続きます(34バイト):

<input name=d value=d type=submit>

2.回答を表示する

<p>表示する(1または0)を選択するにはCSS(159バイト)が必要です。

#q,#s,#q:target{display:none}#q:target{display:block}@-moz-document regexp(".*\\?((i=on&)?|(((i=on&)(i=on&)+?)\\4+))d=d#q$"){#s{display:block}#r{display:none}}

»codepen.ioでお試しください(firefoxのみ)


12
+1:これは私のお気に入りのHTMLの不正使用であり、Codegolfを愛するようなものです。

これは確かに興味深いことですが、このチャレンジのルールを満たしているかどうかはわかりません。特に、あなたのアルゴリズムに準拠するとは思わない[...]理論的には、任意の大きな整数で動作するはずです。入力フィールドの値にも正規表現を使用できませんでしたか?
デニス

@デニス多分。おそらく均一。しかし、それはあなたが言及した問題を解決しません。これは、競合しないエントリとしてここに残します。これは、そのための最も話題の課題だからです。
mınxomaτ

何故なの?入力フィールドに単項の数値がある場合、コードは最大数に依存しなくなります。
デニス

5
うーん、私はこれについてもう少し考えました、そして、xチェックボックスだけを持つこととyビット数だけを持つインタプリタを持つことの間で本当に違いはありません。以前のコメントは無視してください。
デニス


40

六角形、28バイト

Etoplayこの質問で絶対に私を打ち倒したので、私は彼の他の唯一の答えをゴルフアウトしなければならないと感じました。

?\.">"!*+{&'=<\%(><.*.'(@>'/

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

マーティンは彼にやったように私は、ウィルソンの定理を使用して答えを考える:n、I出力(n-1!)² mod n

ここでプログラムが展開されました:

   ? \ . "
  > " ! * +
 { & ' = < \
% ( > < . * .
 ' ( @ > ' /
  . . . . .
   . . . .

そして、これが読みやすいバージョンです:

とても読みやすい

説明:

このプログラムには、3つの主要なステップがあります:初期化要因および出力

六角形のメモリモデルは、無限の六角形のグリッドです。この図に示すように、5つのメモリロケーションを使用しています。

記憶

これらの場所(およびそこに格納されている整数)を、その図のラベルで参照します。

初期化:

初期化

命令ポインター(IP)は、左上隅から始まり、東に進みます。メモリポインタ(MP)はINから始まります。

まず、?入力から数値を読み取り、INに格納します。IPはで反射された青色路上にとどまります\。シーケンス"&(は、MPを左から(Aに)移動し、値をINからAにコピーしてデクリメントします。

IPは、次いで六角形の一辺を出て(緑色パスに)反対側に再び入ります。これは、実行'+移動するMPをするBとしていたものをコピーします。IPをWestにリダイレクトします<

階乗:

階乗を特定の方法で計算するので、それを二乗するのは簡単です。私は次のようにBCのn-1!両方に保管します。

階乗

指示ポインターは、東に向かう青いパスから始まります。

='MPの方向を反転し、Cに逆方向に移動します。これは同等です{=が、持つ=、それは後で役に立ったされた場合を。

&{AからCに値をコピーしてから、MPAに戻します。IPは、その後、赤のパスを到達押す前に、何もしない、緑の経路をたどる\と、オレンジ色のパス上に行きます。

(>Aをデクリメントし、IP East をリダイレクトします。ここでブランチにヒットします<。正のAの場合、オレンジのパスに沿って続行します。それ以外の場合、IPは北東に向けられます。

'*MPBに移動し、A * CBに格納します。これは(n-1)*(n-2)、最初の入力があった場所nです。IPは、再度最初のループに入り、デクリメントとなるまで乗算継続達します。(コンピューティング)0n-1!

NB:次のループで&は、Bの値をCに格納します。Cには現在、正の値が格納されています。これは階乗の計算に重要です。

出力:

出力

ときに達します。ブランチは、代わりに青いパスに沿ってIPを誘導します0

=*逆転MPをの値記憶Bの *のCAを。次に、IPは六角形を出て、緑のパスに再び入ります。実行し"%ます。これはMPOUTに移動し、A mod INまたはを計算し(n-1!)² mod nます。

以下{"は、お互いをキャンセルするため、ノーオペレーションとして機能します。!最終出力を出力し、*+'(終了前に実行されます:@

実行後、(の入力で5)メモリは次のようになります。

メモリー2

制御フローの美しい画像は、Timwiの Hexagony Colororを使用して作成されました

すべての画像を生成してくれたMartin Enderに感謝します。私のPCではできませんでした。


これらのメモリダイアグラムには何を使用していますか?Esoteric IDEを見ましたが、実行することができませんでした
...-NieDzejkob

@NieDzejkobは、とにかく私のために作ったので、チャットでMartinに尋ねた方が良いでしょう。
H.PWiz

@NieDzejkobええ、メモリダイアグラムはEsoIDEからエクスポートできます。chat.stackexchange.com/rooms/27364 / ...これについてもう少しチャットしたい場合。
マーティンエンダー

34

モーニングトンクレセント、2448バイト

ロンドンに戻ってきました!

Take Northern Line to Bank
Take Circle Line to Bank
Take District Line to Parsons Green
Take District Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upney
Take District Line to Hammersmith
Take Circle Line to Victoria
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Circle Line to Victoria
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take Circle Line to Hammersmith
Take Circle Line to Notting Hill Gate
Take District Line to Upminster
Take District Line to Bank
Take Circle Line to Victoria
Take Circle Line to Temple
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Pinner
Take Metropolitan Line to Aldgate
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Victoria
Take Circle Line to Aldgate
Take Circle Line to Victoria
Take Circle Line to Victoria
Take District Line to Upminster
Take District Line to Embankment
Take Circle Line to Embankment
Take Northern Line to Angel
Take Northern Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Aldgate
Take Circle Line to Aldgate
Take Circle Line to Cannon Street
Take District Line to Upney
Take District Line to Cannon Street
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Hammersmith
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Ruislip
Take Piccadilly Line to Ruislip
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Aldgate
Take Circle Line to Aldgate
Take Circle Line to Cannon Street
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Moorgate
Take Circle Line to Moorgate
Take Northern Line to Mornington Crescent

Timwiは、制御フロー局を実装するためにとても親切だったTempleAngelにおける密教IDEだけでなく、言語仕様に入力し、整数の解析を追加します。

これはおそらく「Hello、World!」よりもゴルフが上手いでしょう。なぜなら、今回はCJamスクリプトを書いて、2つのステーション間の最短経路を見つけるのに役立つからです。あなたがそれを使用したい場合(私は誰が望むのか分かりませんが...)、あなたはオンライン通訳を使用することができます。このコードを貼り付けます:

"Mornington Crescent"
"Cannon Street"
]qN/{'[/0=,}$:Q;{Q{1$#!}=\;_oNo'[/1>{']/0="[]"\*}%}%:R;NoQ{R\f{f{\#)}:+}:*},N*

ここで、最初の2行は確認するステーションです。また、このペーストビンの内容を入力ウィンドウに貼り付けます。

出力には、2つのステーションで利用可能な回線が表示され、2つのステーションを接続するすべてのステーションのリストがステーション名の長さでソートされて表示されます。短い行が許可されているか、駅を避けるために駅(銀行や寺院など)が特別であるため、長い名前を使用した方が良い場合があるため、すべて表示されます。2つのステーションが他の1つのステーションによって接続されていない(特に、メトロポリタン線とディストリクト線が交差することはない)エッジケースがあります。その場合、他の何かを把握する必要があります。;)

実際のMCコードに関しては、MCには乗算、除算、およびモジュロがあるため、他の多くの答えと同様に2乗要因アプローチに基づいています。また、単一のループが便利だと考えました。

1つの問題は、ループがdo-whileループであり、デクリメントとインクリメントが高価であるため、(n-1)!(for n > 0)を簡単に計算できないことです。代わりに、コンピューティングn!n行ってから、最後に除算します。これにはもっと良い解決策があると確信しています。

これを書き始めたとき-1、Hammersmithに保存するのは良いアイデアだと思ったので、もっと安く減らすことができましたが、結局はこれが節約した以上の費用がかかるかもしれません。これをやり直す忍耐があれば、-1代わりにUpminsterを使い続けて、Hammersmithを使ってもっと便利なものを試すことができます。


10
ロンドンのチューリングは完了していますか?
ローハンジュンジュンワラ

1
@RohanJhunjhunwala おそらく
マーティンエンダー

うわー!よく考えられた質問を見るのが大好きです。特に、プログラムを書くためにプログラムを書かなければならない質問を見るのが大好きです。
ローハンジュンジュンワラ

27

Brachylog(V2)、1バイト

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

Brachylog(V1)、2バイト

#p

これは、#p - Prime入力を素数に制限する組み込み述語を使用します。

Brachylogは、PrologのCode Golfバージョンを作成しようとする私の試みです。Prologは、バックトラッキングと統合を使用する宣言的なコードゴルフ言語です。

組み込みなしの代替ソリューション:14バイト

ybbrb'(e:?r%0)

上記のコードの内訳は次のとおりです。

y            The list [0, …, Input]
bbrb         The list [2, …, Input - 1]
'(           True if what's in the parentheses cannot be proven; else false
     e           Take an element from the list [2, …, Input - 1]
     :?r%0       The remainder of the division of the Input but that element is 0
)

1
構文が1バイト短くなったので、この記事のBrachylog 2バージョンも編集してください。

1
@ ais523はい、できました。
致命的

Brachylog 2の回答は、チャレンジ後の日付ですか?
スコットミルナー

1
@ScottMilnerはい、これは明示的にこの課題に許可されている:「私たちの通常の規則とは異なり、それはこの挑戦より新しいだ場合でも、言語(または言語バージョン)を使用して自由に感じる」
Fatalize

26

Haskell、49バイト

使用ウィルソンの定理にXNORの推論を

main=do n<-readLn;print$mod(product[1..n-1]^2)n>0

短くするのではないmain=interact$\n-> ...でしょうか?
ジョンドヴォルザーク

2
直感に反して、いいえ!interact...readそこにどこかで必要になると考えてくださいreadLn。多くの場合do、特に代替がラムダである場合、表記は予想よりも簡潔になる可能性があります。
リン

24

ラビリンス、29バイト

1
?
:
}  +{%!@
(:'(
 } {
 :**

STDINから整数を読み取り、出力します((n-1)!)^2 mod nウィルソンの定理は、この課題に非常に役立ちます。

プログラム1は、スタックの最上部を10で乗算し、1を加算する左上隅から開始します。これは、ラビリンスの多数の構築方法ですが、ラビリンスのスタックはゼロで埋められているため、最終的な効果は1をプッシュしました。

?次にn、STDINから読み取り、:複製します。モジュロの最後に使用される補助スタックに}シフトnします。(その後、減少しn、二乗階乗の計算を開始する準備ができました。

2番目:(重複)はジャンクションにあり、ラビリンスの制御フロー機能が作用します。命令が実行された後のジャンクションで、スタックの最上部が正の場合は右に曲がり、負の場合は左に曲がり、ゼロの場合はまっすぐ進みます。曲がろうとして壁にぶつかると、ラビリンスは代わりに他の方向に曲がります。

の場合n = 1、スタックの最上部がnデクリメントされるか0、またはなので、直進します。次に、no-opを押し'てから、別のデクリメント(を実行し-1ます。これは負であるので、我々は左折し、実行+(プラス-1 + 0 = -1{シフトするnメインとした補助スタックから戻って%(モジュロ-1 % 1 = 0)。次に、で出力し!、で終了し@ます。

以下のためにn > 1第二に、:我々は右折。次に}、コピーしたループカウンターを補助スタックにシフトし、複製:と乗算を2回行います。**その後、カウンターをシフト{ダウンしてデクリメントします(。まだ前向きであれば、右に曲がろうとしてもできないので、ラビリンスは左に曲がり、ループを続けます。それ以外の場合、スタックの最上部はループカウンターであり、0に減らさ+れ、計算されたに追加されます((n-1)!)^2。最後に、modulo 、output 、terminateでn戻ります。{%!@

これ'はノーオペレーションですが、デバッグにも使用できます。が渡さ-dれるたびに、フラグの状態で実行してスタックの状態を確認してください'


2
階乗を二乗することは本当にクールなトリックです:)
リン

@Maurisありがとう!私はそれが当然である
xnor

5
イェー、私が書いていない最初のラビリンスの答え!:)
マーティンエンダー

24

Bash + GNUユーティリティ、16

  • @Dennisのおかげで4バイト節約

  • @Lekensteynのおかげで2バイト節約

factor|awk NF==2

入力は、STDINから取得した1行です。出力は、偽の場合は空の文字列で、真実の場合は空でない文字列です。例えば:

$ ./pr.sh <<< 1
$ ./pr.sh <<< 2
2: 2
$ ./pr.sh <<< 3
3: 3
$ ./pr.sh <<< 4
$

2
クール、別のcoreutilについて学びました。フィールドの数を数えることで2文字を削除できますfactor|awk NF==2
。– Lekensteyn

@Lekensteyn-ありがとう-なんらかの理由で私は以前あなたのコメントを逃しました:)
デジタルトラウマ

AWKを使用せずに、少しだけ似たようなものを投稿する予定でした。よくできました。
デビッドコンラッド

21

Java、126 121バイト

スコアボードにはJavaの答えが必要だと思うので、簡単な除算ループを以下に示します。

class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}}

Javaの場合と同様に、「完全なプログラム」の要件により、主にmain署名が原因で、関数の場合よりもはるかに大きくなります。

展開された形式:

class P{
    public static void main(String[]a){
        int i=2,n=Short.valueOf(a[0]);
        for(;i<n;)
            n=n%i++<1?0:n;
        System.out.print(n>1);
    }
}

編集:ピーターによってコメントで修正および再登録されました。ありがとう!


バギー:それは素晴らしかったと報告しています1。それ以外の場合は、削除pして言うことで4文字節約になりますfor(;i<n;)n=n%i++<1?0:n;System.out.print(n>0);
Peter Taylor

2
OTOH class P{public static void main(String[]a){int i=2,n=Short.valueOf(a[0]);for(;i<n;)n=n%i++<1?0:n;System.out.print(n>1);}}作品
ピーターテイラー

6
行3を 'long i = 2、n = Long.valueOf(a [0]); `に変更すると、長さは変更されませんが、有効な入力の範囲が広くなります。
ジェームズKポーク

4
の代わりに、やのように.valueOfを使用できます。これは少し短いです。newnew Short(a[0])new Long(a[0])
ECS

3
インターフェイスを使用してpublic修飾子をドロップすると、4バイトを節約できます。
ラーメンシェフ

18

Brain-Flak112 108バイト

({}[()]){((({})())<>){{}<>(({}<(({}[()])()<>)>)<>)<>{({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}}}<>{{}}([]{})

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

使い方

最初は、最初のスタックには正の整数nが含まれ、2番目のスタックは空になります。

次のようにnをデクリメントすることから始めます。

(
  {}      Pop n.
  [()]    Yield -1.
)       Push n - 1.

n = 1

場合N = 1は、whileループゼロであります

{
  ((({})())<>)
  {
    {}<>(({}<(({}[()])()<>)>)<>)<>{({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}
  }
}

完全にスキップされます。最後に、残りのコードが実行されます。

<>    Switch to the second stack (empty).
{}    Pop one of the infinite zeroes at the bottom.
{<>}  Switch stacks while the top on the active stack is non-zero. Does nothing.
(
  []    Get the length of the active stack (0).
  {}    Pop another zero.
)     Push 0 + 0 = 0.

n> 1

場合のn - 1が非ゼロであり、我々はループ入るn = 1のスキップを。これは「実際の」ループではありません。コードは1回だけ実行されます。以下を達成します。

{                   While the top of the active stack is non-zero:
  (
    (
      ({})                Pop and push n - 1.
      ()                  Yield 1.
    )                   Push n - 1 + 1 = n.
    <>                  Switch to the second stack. Yields 0.
  )                   Push n + 0 = n.
                      We now have n and k = n - 1 on the first stack, and n on
                      the second one. The setup stage is complete and we start
                      employing trial division to determine n's primality.
  {                   While the top of the second stack is non-zero:
    {}                  Pop n (first run) or the last modulus (subsequent runs),
                        leaving the second stack empty.
    <>                  Switch to the first stack.
    (
      (
        {}                  Pop n from the first stack.
        <
          (
            (
              {}              Pop k (initially n - 1) from the first stack.
              [()]            Yield -1.
            )               Push k - 1 to the first stack.
            ()              Yield 1.
            <>              Switch to the second stack.
          )               Push k - 1 + 1 = k on the second stack.
        >               Yield 0.
      )               Push n + 0 = n on the second stack.
      <>              Switch to the first stack.
    )               Push n on the first stack.
    <>              Switch to the second stack, which contains n and k.
                    The first stack contains n and k - 1, so it is ready for
                    the next iteration.
    {({}[()]<({}[()]<({}())>)>{(<()>)}{})}{}{}  Compute and push n % k.
  }               Stop if n % k = 0.
}               Ditto.

n%kは、私の分割可能性テストの回答から42バイトのモジュラスアルゴリズムを使用して計算されます

最後に、結果を解釈してnの素数性を決定します。

<>    Switch to the first stack, which contains n and k - 1, where k is the
      largest integer that is smaller than n and divides n evenly.
      If (and only if) n > 1 is prime, k = 1 and (thus) k - 1 = 0.
{     While the top of the first stack is non-zero:
  {}    Pop it.
}     This pops n if n is prime, n and k - 1 if n is composite.
(
  []    Yield the height h of the stack. h = 1 iff n is prime).
  {}    Pop 0.
)     Push h + 0 = h.

2
スタックの最後の0をポップする必要はありません。一番上の真実の1で十分です。最後のを削除することで、そのように2バイトを節約できます{}
スティーブンH.

1
うーん、私は破れています。一方では、質問は、出力が真の値または偽の値のみで構成される必要1 0があり、2つの値であると言います。一方、言語がそれらを真実または偽とみなし、複数のスタック項目がBrain-Flakが配列に最も近いものである限り、配列を受け入れます。これをメタにする価値があるかもしれません。
デニス

Brain-Flakの作成者に1 0真実を確認しました。chat.stackexchange.com/transcript/message/32746241#32746241
スティーブンH.


17

R、37 29バイト

n=scan();cat(sum(!n%%1:n)==2)

トライアル部門を使用します。scan()STDINから整数を読み取り、cat()STDOUTに書き込みます。

n整数1からnmoduloで構成される長さのベクトルを生成しnます。それぞれが0であるかどうかをテスト!します。()は、数値が0の場合はtrue、0より大きい場合はfalseの論理値を返します。論理ベクトルの合計は、真の要素の数であり、期待される素数唯一の非ゼロ係数は1およびnであるため、合計は2になると予想されます。

flodelのおかげで8バイト節約されました!


ではf=function(x)sum(!x%%1:x)==2、あなたは28バイトでそれを行うことができます。
ムタドール

2
@AndréMutaこの課題のために、すべての提出物は単なる機能ではなく完全なプログラムでなければなりません。提案をありがとう。
アレックスA.

17

TI-BASIC、12バイト

2=sum(not(fPart(Ans/randIntNoRep(1,Ans

とても簡単です。randIntNoRep(1からのすべての整数のランダムな順列を与えAnsます。

これはルールを少し曲げます。TI-BASICのリストは、私が解釈した999個の要素に制限されているため

入力をデータ型に保存できると仮定します

すべてのデータ型が入力に対応すると想定できることを意味します。OPはこの解釈に同意します。

実際に最大10 ^ 12程度で動作する17バイトのソリューション

2=Σ(not(fPart(Ans/A)),A,1,Ans

@toothbrush TI-BASICはトークン化された言語であるため、ここにあるすべてのトークンrandIntNoRep(は2 バイトを除いて1バイトです。
リルトシアスト

+1ああ、TL-BASICを見たことがありません。教えてくれてありがとう
歯ブラシ

1
しかし、それ少し不公平ですよね...?1〜4バイト(質問ID)のみを必要とするゴルフ言語を作成し、次にパラメーターを作成する必要があります。理解できる言語でトップアンサーを選択し、実行して(パラメーターを渡します)、結果を返します...それがルールに違反しているのでしょうか?:
歯ブラシ

@toothbrush TI-BASICの防御では、インタープリターにとって、PythとCJamの1文字のコマンドほど不公平ではなく、TI-BASICはより読みやすくなっています。
リスト管理者

1
本当です。他のほとんどすべての言語でのソリューションの方が長いため、この種の言語は嫌いです。最近、VB6でCJamを破りました:-]
歯ブラシ

15

PARI / GP、21バイト

print(isprime(input))

この種のことはPARI / GPの目的であるため、途方もなく大きな入力に対して機能します。


6
isprimeAPR-CLの素数性証明を行うので、入力が非常に大きくなるとかなり遅くなります。 ispseudoprime(input)AES BPSW推定プライムテストを実行します。これは、100桁を超えるとはるかに高速になります。35年後の反例はまだ知られていない。2002年より前のバージョン2.1以前のPariは、誤った結果を簡単に与えることができる別の方法を使用しますが、誰も使用するべきではありません。
DanaJ

15

TI-BASIC、24バイト

TI-Basicプログラムはトークンシステムを使用するため、文字をカウントしてもプログラムの実際のバイト値は返されないことに注意してください。

トーマス・クワの回答に賛成票を投じ、それは優れています。

:Prompt N
:2
:While N≠1 and fPart(N/Ans
:Ans+1
:End
:N=Ans

サンプル:

N=?1009
                         1
N=?17
                         1
N=?1008
                         0
N=?16
                         0

0素数でない1場合、または素数である場合に戻ります。


3
平方根は、プログラムを正しくするために実際に必要としない最適化ではありませんか?
マーティンエンダー

なぜ2で割る必要があるのですか?
ジオビット

TI-BASICの回答はいつも大好きです。
グラントミラー

15

スタック猫、62 + 4 = 66バイト

*(>:^]*(*>{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}*<)]*(:)*=<*)>]

-lnコマンドラインフラグ(+4バイト)を使用して実行する必要があります。0合成数および1素数の印刷。

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

これは最初の重要なStack Catsプログラムです。

説明

Stack Catsの簡単な紹介:

  • Stack Catsは、現在のスタックを指すテープヘッドで、スタックの無限のテープで動作します。すべてのスタックは、最初は無限のゼロで満たされています。私は一般にこれらのゼロを言葉遣いで無視しますので、「スタックの一番下」と言うときは最低のゼロ以外の値を意味し、「スタックは空です」と言うときはゼロしかありません。
  • プログラムが開始する前に、a -1が初期スタックにプッシュされ、次に入力全体がその先頭にプッシュされます。この場合、-nフラグにより​​、入力は10進整数として読み取られます。
  • プログラムの最後に、現在のスタックが出力に使用されます。ある場合-1一番下に、それは無視されます。繰り返し-nますが、フラグのために、スタックからの値は単に改行で区切られた10進整数として印刷されます。
  • Stack Catsは可逆的なプログラム言語です。すべてのコードを元に戻すことができます(Stack Catsが明示的な履歴を追跡する必要はありません)。より具体的には、コードの一部を反転するには、単にミラーリングします。たとえばに<<(\-_)なり(_-/)>>ます。この設計目標は、言語に存在する演算子と制御フローの構成要素の種類、およびグローバルメモリ状態で計算できる関数の種類にかなり厳しい制限を課します。
  • さらに、すべてのStack Catsプログラムは自己対称である必要があります。上記のソースコードには当てはまらないことに気付くかもしれません。これが-lフラグの目的です。中央の最初の文字を使用して、コードを暗黙的に左にミラーリングします。したがって、実際のプログラムは次のとおりです。

    [<(*>=*(:)*[(>*{[[>[:<[>>_(_-<<(-!>)>(>-)):]<^:>!->}<*)*[^:<)*(>:^]*(*>{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}*<)]*(:)*=<*)>]
    

コード全体で効果的にプログラミングすることは、非常に簡単で直感的ではなく、人間がどのようにそれを行うことができるかはまだ実際にはわかっていません。このようなプログラムを単純なタスクのために強引に強制しましたが、手作業でその近くに到達することはできませんでした。幸いなことに、プログラムの半分を無視できる基本的なパターンが見つかりました。これは確かに最適ではありませんが、現在のところStack Catsで効果的にプログラムする唯一の既知の方法です。

したがって、この答えでは、上記のパターンのテンプレートは次のとおりです(実行方法には多少のばらつきがあります)。

[<(...)*(...)>]

プログラムが起動すると、スタックテープは次のようになります(入力用4など)。

     4    
... -1 ...
     0
     ^

[移動左に、スタックの最上位(と一緒にテープヘッドは) -私たちは、この「プッシュ」と呼びます。そして、<テープヘッドだけを動かします。したがって、最初の2つのコマンドの後、次のような状況になります。

...   4 -1 ...
    0 0  0
    ^

これは(...)、条件として非常に簡単に使用できるループです。ループは、現在のスタックのトップが正の場合にのみ開始および終了します。現在はゼロなので、プログラムの前半全体をスキップします。現在、中央のコマンドは*です。これは単純であるXOR 1、それは、スタックの最上位の最下位ビットをトグルし、この場合に回転する。すなわち、01

... 1 4 -1 ...
    0 0  0
    ^

今、私たちはの鏡像に遭遇し(...)ます。この時間は、スタックの最上位は正であり、我々はやるのコードを入力してください。括弧内で何が起こるかを調べる前に、最後にどのようにまとめるかを説明しましょう。このブロックの最後で、テープヘッドが再び正の値になるようにしますループは1回の反復後に終了し、単に線形条件として使用されます)、右側のスタックが出力を保持し、その右側のスタックが保持することを示します-1。その場合は、ループを終了>し、出力値に移動して]プッシュ-1します。これにより、出力用のクリーンスタックができます。

それだけです。括弧内で、最後の前の段落で説明したように設定することを確認する限り、素数性をチェックすることは何でもできます(プッシュとテープヘッドの移動で簡単に実行できます)。私は最初にウィルソンの定理で問題を解決しようとしましたが、2乗の階乗計算は実際にStack Catsで非常に高価です(少なくとも私は短い道を見つけていません)ので、100バイトをはるかに超えてしまいました。そのため、代わりにトライアル部門を使用しましたが、実際はもっと簡単になりました。最初の線形ビットを見てみましょう:

>:^]

これらのコマンドのうち2つをすでに見ました。さらに:、現在のスタックの上位2つの値をスワップし^、2番目の値を上位の値にXORします。これにより:^、空のスタックに値を複製する一般的なパターンが作成されます(値の上にゼロを引いてから、ゼロをに変えます0 XOR x = x)。したがって、この後、テープのセクションは次のようになります。

         4    
... 1 4 -1 ...
    0 0  0
         ^

私が実装したトライアル除算アルゴリズムはinput 1では機能しないため、その場合はコードをスキップする必要があります。を使用1して0、他のすべてを正の値に簡単にマッピングでき*ます。その方法を次に示します。

*(*...)

それは我々がオンである10、私たちが実際に取得する場合、コードの大部分をスキップし0、私たちはすぐに元に戻すの内側に*、我々は戻って私たちの入力値を取得するようにします。かっこがループを開始しないように、かっこの最後で正の値で終了することを再度確認する必要があります。条件内で、1つのスタックを右に移動して>から、メインの試行分割ループを開始します。

{<-!<:^>[:((-<)<(<!-)>>-_)_<<]>:]<]]}

中括弧(括弧ではなく)は、異なる種類のループを定義します。これは、do-whileループです。つまり、常に少なくとも1回は実行されます。もう1つの違いは終了条件です。ループに入ると、スタック猫は現在のスタックの最高値を記憶します(0この場合)。ループは、反復の最後にこの同じ値が再び現れるまで実行されます。これは便利です。各反復で、次の潜在的な除数の残りを計算し、それをこのスタックに移動して、ループを開始します。除数が見つかると、残りはで0あり、ループは停止します。で除数を試してから、n-1それらを1に減らします1。つまり、a)到達するとこれが終了することがわかっている1遅くても、b)次に、最後に試した除数を調べて、数値が素数であるかどうかを判断できます(それがの場合1、それは素数、そうでない場合は素数です)。

それに行きましょう。最初に短い線形セクションがあります。

<-!<:^>[:

あなたはそれらのほとんどが今では何をしているのか知っています。新しいコマンドがある-!。Stack Catsには、インクリメント演算子またはデクリメント演算子はありません。ただし、-(否定、つまり乗算-1)と!(ビットごとのNOT、つまり乗算-1と減分)があります。これらは、increment !-、、またはdecrementのいずれかに結合できます-!。そのnため-1、の上にあるのコピーをデクリメントしてnから、スタックの左側に別のコピーを作成し、新しいトライアル除数を取得しての下に置きますn。したがって、最初の反復で、これを取得します。

      4       
      3       
... 1 4 -1 ...
    0 0  0
      ^

さらに反復する場合、3次のテスト除数などに置き換えられます(一方、この2つのコピーnは常に同じ値になります)。

((-<)<(<!-)>>-_)

これはモジュロ計算です。ループは正の値で終了するため、正の値が得られるまでループを開始し-n、試行除数dを繰り返し追加します。実行したら、結果を減算しd、残りを取得します。ここで注意が必要なのは、スタックの先頭に-n追加して追加するループを開始することはできないということです。スタックdの先頭が負の場合、ループは開始されません。これは、リバーシブルプログラミング言語の制限です。

したがって、この問題を回避するためnに、スタックの先頭から始めますが、最初の反復でのみ無効にします。繰り返しますが、それはそれが判明するよりも簡単に聞こえます...

(-<)

スタックの一番上が正の場合(つまり、最初の反復でのみ)、で否定し-ます。しかし、私たちは行うことはできません(-)し、我々はされないので、残してまで、ループを-2回適用されました。その<ため、正の値(1)があることがわかっているため、1つのセルを左に移動します。さて、これでn最初の反復で確実に否定されました。しかし、新しい問題があります。テープヘッドは、最初の反復では他のすべての反復と異なる位置になりました。先に進む前にこれを統合する必要があります。次に<、テープヘッドを左に移動します。最初の反復の状況:

        -4       
         3       
...   1  4 -1 ...
    0 0  0  0
    ^

そして、2回目の繰り返しで(今d一度追加したことを思い出してください-n):

      -1       
       3       
... 1  4 -1 ...
    0  0  0
    ^

次の条件は、これらのパスを再びマージします。

(<!-)

最初の反復では、テープヘッドはゼロを指すため、これは完全にスキップされます。さらに繰り返して、テープヘッドは1を指すので、これを実行し、左に移動し、そこでセルをインクリメントします。セルはゼロから開始することがわかっているため、セルは常に正になり、ループを抜けることができます。これにより、メインスタックの左側に常に2つのスタックがあり、で戻ることができるようになります>>。次に、モジュロループの最後に行います-_。あなたはすでに知ってい-ます。XORである_ものを減算すること^です:スタックの一番上がaその下の値である場合、bそれはに置き換えaられb-aます。まず否定するのでa、しかし-_代わるものab+a、これにより追加します、d ランニング合計に。

ループが終了した(正の値に達した)値は、テープは次のようになります。

        2       
        3       
... 1 1 4 -1 ...
    0 0 0  0
        ^

左端の値は任意の正の数にすることができます。実際には、反復回数から1を引いたものです。もう1つの短い線形ビットがあります。

_<<]>:]<]]

前に述べたようにd、実際の剰余(3-2 = 1 = 4 % 3)を取得するには結果を減算する必要があるため、_もう一度行います。次に、左側でインクリメントしているスタックをクリーンアップする必要があります。次の除数を試すとき、最初の反復が機能するためには、再びゼロにする必要があります。そこでそこに移動し、その正の値を他のヘルパースタックにプッシュし<<]、次に別のヘルパースタックに操作スタックに戻ります>。私たちは、プルアップd:し、上に戻ってそれをプッシュする-1]、その後、私たちは私たちとの条件付きスタックに残りを動かします<]]。これが試行除算ループの終わりです。これは、残りがゼロになるまで続きます。この場合、左側のスタックにはnの最大の除数(以外n)。

ループの終了後、*<パスを1再び入力に結合する直前があります。*単純にゼロになります1私たちは少しで必要があります、その後、我々はと除数に移動<(私たちは入力と同じスタックにしているように1)。

この時点で、3種類の入力を比較するのに役立ちます。まず、n = 1私たちがその試用部門のことを何もしていない特別な場合:

         0    
... 1 1 -1 ...
    0 0  0
         ^

次に、前の例n = 4、合成数:

    2           
    1    2 1    
... 1 4 -1 1 ...
    0 0  0 0
         ^

そして最後にn = 3、素数:

    3           
    1    1 1    
... 1 3 -1 1 ...
    0 0  0 0
         ^

したがって、素数の場合、1このスタック上にa があり、複合数の場合、0またはより大きい正の数があり2ます。私たちは、にこのような状況を回す0か、1私たちは、次のコード最後の部分で必要があります。

]*(:)*=<*

]この値を右に押すだけです。その後*、条件付き状況を大幅に簡素化するために使用されます。最下位ビットを切り替えること1により00(プライム)を、(コンポジット)を正の値1に変換しますが、他のすべての正の値は正のままです。ここで0、ポジティブとポジティブを区別する必要があります。そこで別のものを使用します(:)。スタックの最上位が0(かつ入力が素数である)場合、これは単にスキップされます。しかし、スタックの最上位は、(と、入力がコンポジット数はあった)、これはでそれを交換正の場合は1、我々が今持っているように、0複合のためにと1プライムの場合-2つの異なる値のみ。もちろん、それらは出力したいものの反対ですが、それは別のもので簡単に修正され*ます。

今残っているすべては、私たちの周囲のフレームワークによって期待されるスタックのパターン復元することです:右にスタックの一番上に、正の値にテープヘッドをもたらし、単一-1のスタック右のこと。これが=<*目的です。=隣接する2つのスタックの上部を入れ替えて-1、結果の右側に移動します。たとえば、入力のため4に:

    2     0       
    1     3       
... 1 4   1 -1 ...
    0 0 0 0  0
          ^

次に、左に移動して<、そのゼロを1に変えます*。そしてそれはそれです。

プログラムの動作をさらに詳しく調べたい場合は、デバッグオプションを利用できます。追加のいずれか-dのフラグをして挿入"あなたは現在のメモリの状態を見てみたいところはどこでも、このように、たとえば、または使用-Dフラグをプログラム全体の完全なトレースを取得します。別の方法としては、使用することができますTimwiのEsotericIDEステップバイステップデバッガでスタック猫のインタプリタを含んでいます。


3
>:^]Stack Catsの公式ロゴ
Alex A.

14

Haskell、54バイト

import Data.Numbers.Primes
main=readLn>>=print.isPrime

説明することはあまりありません。


1
ウィルソンの定理を使用して、外部ライブラリなしで同じスコアを(非常に非効率的ではあるが)達成できますmain=do n<-readLn;print$n>1&&mod(product[1..n-1]+1)n<1
Lynn

9
さらに短くすることもできmain=do n<-readLn;print$mod(product[1..n-1]^2)n>0ます。49バイトです。
リン

4
@モーリス:いいですね。別の回答として投稿してください。
nimi

14

ルビー、15 + 8 = 23バイト

p$_.to_i.prime?

サンプル実行:

bash-4.3$ ruby -rprime -ne 'p$_.to_i.prime?' <<< 2015
false

Heheh、Rubyにはどこかにビルトインが存在することはわかっていましたが、それを探すのが面倒だったので、C。+1で答えました。
レベルリバーセント

@steveverrill、それはProject Eulerにとって大きな助けだったので知っていました。
マナトワーク

14

JavaScript、39 36バイト

ETHproductionsのおかげで3バイト節約されました:

for(i=n=prompt();n%--i;);alert(1==i)

プライムの場合はtrue、そうでない場合はfalseを表示します。

以下のためのループは、すべての番号テストのIからN-1まで、iは除数です。最初に見つかった除数が1の場合、それは素数です。


以前のソリューション(39バイト):

for(i=n=prompt();n%--i&&i;);alert(1==i)

不要なテストが残された方法:

for(i=2,n=prompt();n%i>0&&i*i<n;i++);alert(n%i>0) //49: Simple implementation: loop from 2 to sqrt(n) to test the modulo.
for(i=2,n=prompt();n%i>0&&i<n;i++);alert(n==i)    //46: Replace i*i<n by i<n (loop from 2 to n) and replace n%i>0 by n==i
for(i=2,n=prompt();n%i&&i<n;i++);alert(n==i)      //44: Replace n%i>0 by n%i
for(i=2,n=prompt();n%i&&i++<n;);alert(n==i)       //43: Shorten loop increment
for(i=n=prompt();n%--i&&i>0;);alert(1==i)         //41: Loop from n to 1. Better variable initialization.
for(i=n=prompt();n%--i&&i;);alert(1==i)           //39: \o/ Replace i>0 by i

JavaScriptの最良の答えはすでに40バイトであったため、39バイトのソリューションのみを投稿しました。


2
プログラミングパズルとコードゴルフへようこそ!
デニス

2
素晴らしい答えです!&&i実際に、このプログラムでは何もしませんので、あなたはそれを削除することができます。
ETHproductions

n>1ただし、1素数になりたくない場合は、最終条件に追加する必要があります。
タイタス

1
@Titus入力が1forループの場合、n%--i一度実行するとループが1%0返されNaNて停止します。ときにalert呼ばれているがi、すでにに等しい0ので1==iリターンfalse
エディ

2
i <2(および一部のテキスト)
シャイントッド

13

カタツムリ、122

入力は単項で与える必要があります。数字は、改行を除く任意の文字の組み合わせです。

^
..~|!(.2+~).!~!{{t.l=.r=.}+!{t.!.!~!{{r!~u~`+(d!~!.r~)+d~,.r.=.(l!~u~)+(d!~l~)+d~,.l.},l=(.!.)(r!~u~)+(d!~!.r~)+d~,.r.!.

この2Dパターンマッチング言語では、プログラムの状態は、現在のグリッドの位置、一致したセルのセット、およびパターンコード内の位置のみで構成されます。マッチした広場に移動することも違法です。トリッキーですが、情報を保存および取得することは可能です。一致したセルへの移動に対する制限は、完了後にグリッドを変更しないままにするバックトラッキング、テレポート(t)、およびアサーション(=!)によって克服できます。

25の因数分解

奇数の合成数の因数分解は、相互に隣接していないセルのセット(図の青色)をマークすることから始まります。次に、プログラムは、黄色の各セルから、隣接する青色のセルの両側に同じ数の非青色のセルがあることを確認します。この図は、チェックする必要がある4つの黄色のセルの1つに対するこのパターンを示しています。

注釈付きコード:

^                         Match only at the first character
..~ |                     Special case to return true for n=2
!(.2 + ~)                 Fail for even numbers
. !~                      Match 1st character and fail for n=1
!{                        If the bracketed pattern matches, it's composite.
  (t. l=. r=. =(.,~) )+   Teleport to 1 or more chars and match them (blue in graphic)
                          Only teleport to ones that have an unmatched char on each side.
                          The =(.,~) is removed in the golfed code. It forces the
                          teleports to proceed from left to right, reducing the
                          time from factorial to exponential.
  !{                      If bracketed pattern matches, factorization has failed.
    t . !. !~             Teleport to a square to the left of a blue square (yellow in diagram)
    !{                    Bracketed pattern verifies equal number of spaces to
                          the left or right of a blue square.
      {              
        (r!~ u~)+         Up...
        (d!~!. r~)+       Right...
        d~,               Down...
        . r . =.          Move 1 to the right, and check that we are not on the edge;
                          otherwise d~, can fall off next iteration and create and infinite loop
        (l!~ u~)+         Up...
        (d!~ l~)+         Left...
        d ~,              Down...
        . l .             Left 1
      } ,                 Repeat 0 or more times
      l  =(. !.)          Check for exactly 1 unused char to the left
      (r!~ u~)+           Up...
      (d!~!. r~)+         Right...
      d ~,                Down...
      . r . !.
    }
  }
}

13

C、67バイト

i,n;main(p){for(scanf("%d",&i),n=i;--i;p=p*i*i%n);putchar(48+p%n);}

プリント!1(でfalsey値、ピーター・テイラーの定義 0であれば(n-1)!^2 == 0 (mod n)、そして1それ以外の場合は。

編集:チャットでいくつかの議論の後puts("!1"+p%n)、少しチートとみなされるようだので、私はそれを置き換えました。結果は1バイト長くなります。

編集:大きな入力の修正。

より短いソリューション

56バイト:pawel.boczarskiのコメントで推奨されているように、コマンドライン引数の数を読み取ることで単項で入力を取得できます。

p=1,n;main(i){for(n=--i;--i;p=p*i*i%n);putchar(48+p%n);}

のようなプログラムを呼び出す

$ ./a.out 1 1 1 1 1
1                        <-- as 5 is prime

51バイト:リターンコードを使用して「出力」を許可する場合:

p=1,n;main(i){for(n=--i;--i;p=p*i*i%n);return p%n;}

投稿したソリューションのように、単項表現(コマンドライン引数の数)を使用してソリューションを短くすることができます。scanf呼び出しでいくつかのバイトを削ることができます。
pawel.boczarski

puts("!1"+p%n)あなたa+bchar*価値のためにどうすることができますか?
エリックアウトゴルファー16

文字列"!1"がaddress aで始まる場合、文字列がa+1見つかります"1"
リン

@リンああ、私はそれが連結のためだと思った(そう、それを残し方がいいstrcat(const char*,const char*)。)
エリック・ザ・アウトゴルファー

に変更p=p*i*i%nしてもらえますかp*=i*i%n
アルバートレンショー

12

Python 3、59バイト

input()コマンドライン引数の代わりに使用するようになりました。@Beta Decayに感謝

n=int(input())
print([i for i in range(1,n)if n%i==0]==[1])

入力を使用input()すると、はるかに短くなります
ベータディケイ

おかげで、すでにinput()を使用して書いていますが、答えを更新するのを忘れていました。再度、感謝します!
uno20001

4
52バイト:n=m=int(input())print(all(n%m for m in range(2,n)))
ジョンリヨン

1
真剣ですか。足りない二次の高速化のために25個の余分な文字を使いますか?ここでは、バイトが嫌いです。私たちの人生の1時間、1分、2秒ごとに19バイト目を取り除きます。(冗談です。しかし、プログラムの長さを増やす時間の最適化は行いません。)
CalculatorFeline

2
n%i<1代わりに使用してください。
エリックアウトゴルファー

12

APL、40 13バイト

2=+/0=x|⍨⍳x←⎕

私のR回答と同じアルゴリズムを使用した除算。xSTDIN()からの入力に割り当てx、1からの各整数で割った余りを取得しxます。各剰余は0と比較されます。これにより、どの整数が除算されるかを示す1と0のベクトルが得られますx。これは+/除数の数を取得するために使用して合計されます。この数が正確に2の場合、これは除数が1とのみxであり、したがってx素であることを意味します。


12

Python 2、44

P=n=1
exec"P*=n*n;n+=1;"*~-input()
print P%n

Sp3000のPython answerていますが、変数を入力値nまでカウントアップすることで入力を保存しません1


12

C ++テンプレートのメタプログラミング。 166 131 119バイト。

定数が素数の場合はコードがコンパイルされ、複合または1の場合はコンパイルされません。

template<int a,int b=a>struct t{enum{x=t<a,~-b>::x+!(a%b)};};
template<int b>struct t<b,0>{enum{x};};
int _[t<1>::x==2];

(最後の改行を除くすべての改行は、「実際の」バージョンでは削除されます)。

「コンパイルの失敗」は、メタプログラミング言語の偽の戻り値だと思います。完全なC ++プログラムとしてリンクされないことに注意してください(したがって、プライムを入力すると、リンクエラーが発生します)。

テストする値は、最後の「行」の整数です。

ライブ例

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