せっかちな可分性テスト


14

あなたの仕事は、ある数値が別の数値で割り切れるかどうかを判断するプログラムまたは関数を書くことです。キャッチは、数字のすべての数字が与えられていなくても、できるだけ早く答えを出すべきだということです。

あなたのプログラムは、整数とるべきD ≥2と、入力として一連の数字を。これらは、整数、別の数字を表すN個の最下位桁から始まる、1≥。最初の時点でいることをNのどちらかがしなければならないか、してはならないことでdivisbleもD、あなたのプログラムの出力すべき適切な解答して終了します。入力の終わりに到達した場合、完全なNDで割り切れるかどうかを出力する必要があります。

Nの受け入れ可能な入力形式のリストを次に示します (含まれないものを許可する必要があると思われる場合はコメントを残します)。

  • 標準入力:数字は別々の行に表示されます。 入力の終わりはEOFまたは特別な値です。 exitは、関数が戻るか、プログラムが終了することを意味します。

  • アナログ入力:キーストロークや各桁を表す10個のボタンなど。 入力の終わりは特別な値です。 exitは、関数が戻るか、プログラムが終了することを意味します。

  • グローバル状態の関数:連続した数字で繰り返し呼び出されます。 入力の終わりは特別な値です。 exitは、関数がnull以外の値を返すことを意味します。グローバル状態を使用する場合は、値が返された後、または関数が複数回機能するようにリセットした後にクリアする必要があることに注意してください。

  • Curried function:次の数字または値で呼び出される別の関数を返します。 入力の終わりは特別な値であるか、引数なしで関数を呼び出します。 exitは、関数が別の関数ではなく答えを返すことを意味します。

  • GUIプロンプトなど:繰り返し表示されます。 入力の終わりは「キャンセル」または同等の値、または特別な値です。 exitは、プロンプトが表示されなくなることを意味します。

  • イテレータ関数:入力は、呼び出されたときに次の数字を返すステートフルオブジェクトまたは関数 です。入力の終わりは例外または特別な値です。 exitは、反復子の呼び出しが停止することを意味します。

Dの入力と出力は、任意の受け入れ可能な標準方法を使用できます。

テストケース:

2;   6               => true
5;   6               => false
20;  0 3             => false
20;  0 4             => true
100; 1               => false
100; 0 0             => true
100; 0 2             => false
4;   2 4             => false
4;   2 5             => true
4;   2 [eof]         => false
4;   4 [eof]         => true
625; 5 5             => false
625; 5 7 2           => false
625; 5 7 3 6         => false
625; 5 7 3 4         => true
7;   9 3 4 [eof]     => false
7;   9 3 4 5 [eof]   => true
140; 0 3             => false
140; 0 4 5 [eof]     => false
140; 0 4 5 1 [eof]   => true
14;  4 5 1 4 [eof]   => false
14;  4 5 1 4 1 [eof] => true

ソリューションが入力を要求するたびに1桁が与えられると想定すべきだと思いますか?そして、これは入力が数字ごとに与えられることを保証する客観的な方法なので、完全なプログラムである必要がありますか?(課題は「プログラムまたは機能」と言います、うーん...)
エリックアウトゴルファー

1
@EriktheOutgolfer入力形式は、質問の箇条書きリストで詳細に説明されています。
ドアノブ

1
これらのフォーマットがどれほど客観的であるかを考えていました...私はちょうどピッキングをやめて、実際にこれを解決し始めると思います。:-)
エリック・ザ・アウトゴルファー

1
digitsEOFの特別な値を持つ入力としてリストを取得するだけで問題はありませんか?
ジョナサンアラン

1
@EriktheOutgolferは、EOF値がある場合でも、何か誤解しない限り、そうではありません。たとえばのは、全体の値は132で、潜在的な除数が4、その後で言わせて[][2]リターン以外falseたりtrueしながら、(...関数自体などを含む)[2,3][2,3,1]および[2,3,1,EOF]リターンtrue。グローバル状態オプションに近いと思います。
ジョナサンアラン

回答:


9

JavaScript(ES6)、70バイト

入力形式:カリー関数

除数を取り、各桁またはEOFに対してを取る関数を返す関数。2番目の関数は、0(false)、1(true)、またはそれ自体(応答なし)を返します。101

p=>(q='',g=(d,t=k=z=!~d||(q=d+q,p))=>k--?g(d,t-=(k+q)%p<1):t?t-z&&g:1)

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

どうやって?

除数が与えられおよび配当Qからなるnは小数点以下の桁、我々はすべてのために、次の式を計算0 K < pはpqn0k<p

(1)k×10n+qモッドp

バツpm10k<pバツ=mp+k

バツ×10n+qモッドp=mp+k×10n+qモッドp=mp×10nモッドp+k×10n+qモッドpモッドp=0+k×10n+qモッドpモッドp=k×10n+qモッドp

100k<p0kp

100k<p

1q

コメント済み

p => (                       // p = divisor
  q = '',                    // q = dividend stored as a string, initially empty
  g = (                      // g() = curried function taking:
    d,                       //   d = next digit
    t =                      //   t = number of iterations yielding a non-zero value
    k =                      //   k = total number of iterations to process
    z =                      //   z = copy of k
      !~d ||                 //   if d == -1 (meaning EOF), use only 1 iteration
                             //   so that we simply test the current value of q
      (q = d + q, p)         //   otherwise, prepend d to q and use p iterations
  ) =>                       //
    k-- ?                    //   decrement k; if it was not equal to zero:
      g(                     //     do a recursive call to g():
        d,                   //       pass the current value of d (will be ignored anyway)
        t -= (k + q) % p < 1 //       test (k + q) % p and update t accordingly
      )                      //     end of recursive call
    :                        //   else:
      t ?                    //     if t is greater than 0:
        t - z && g           //       return 0 if t == z, or g otherwise
      :                      //     else:
        1                    //       return 1
)                            //

2

バッチ、177 169バイト

@set n=
@set g=1
:l
@set/ps=
@if %s%==- goto g
@set n=%s%%n%
@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g
@if %g% neq %1 if %r%==0 goto l
:g
@cmd/cset/a!(n%%%1)

かかるdコマンドラインパラメータとしての数字読み出しnと別の行には-EOFマーカーとして。1割り切れ0ない場合の出力。説明:

@set n=

n空の文字列に初期化します。

@set g=1

ggcd(d, 10**len(n))

:l

数字の読み取りループを開始します。

@set/ps=

次の数字を読みます。

@if %s%==- goto g

EOFで処理を停止します。

@set n=%s%%n%

次の桁をに追加しnます。

@set/ae=%1/g,g*=2-e%%2,g*=1+4*!(e%%5),r=n%%g

更新glen(n)て計算しn%gます。

@if %g% neq %1 if %r%==0 goto l

場合はrゼロで、その後d確実に分割されませんnので、gの要因はd、しません。場合はrゼロ、我々は唯一のかを知っているされてd分裂するnならばgイコールdそれがない場合は、そう、ループを継続します。

:g

EOFで、ここで数字読み取りループから抜け出します。

@cmd/cset/a!(n%%%1)

結果を計算して暗黙的に出力します。

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