数字の安全性


22

正の整数の周期的シーケンスがn、シーケンス内で発生するすべての整数について、n2つの連続するオカレンスの間に他の整数を超えないという特性があるかどうかを判別するプログラムを作成しnます。

たとえば、2, 3, 5, 2, 3, 6, 2, 3, 5, 2, 3, 6, ...このプロパティを持っている:の連続発生のすべてのペア2のようなそれらの間にほとんど二つの整数(に持っている2, 3, 5, 22, 3, 6, 2、の連続発生のすべてのペア3それらの間の最も3つの整数で持っている;そして同じのため56

ただし、2, 3, 5, 2, 3, 4, 2, 3, 5, 2, 3, 4, ...このプロパティはありません:の2つの連続したオカレンス4、つまり4, 2, 3, 5, 2, 3, 4、間に4つ以上の整数があります。

入力:正の整数の周期的シーケンスの合理的な表現。たとえば、などの有限リスト{2, 3, 5, 2, 3, 6}は、2, 3, 5, 2, 3, 6, 2, 3, 5, 2, 3, 6, ...上記の最初の無限シーケンスを表すことができます。(そのことについては、無限の周期的なリストの代わりにラップアラウンドする有限のリストに対して問題を述べることができます。)

出力:真実/偽の値。

真実の例:

{1}
{8, 9}
{2, 3, 4}
{5, 5, 3, 3, 6}
{2, 3, 5, 2, 3, 6}
{6, 7, 3, 5, 3, 7}
{9, 4, 6, 7, 4, 5}
{1, 1, 1, 1, 1, 100, 1}
{1, 9, 1, 8, 1, 7, 1, 11}

偽の例:

{1, 2, 3}
{2, 3, 9, 5}
{3, 5, 4, 4, 6}
{2, 3, 5, 2, 3, 4}
{3, 5, 7, 5, 9, 3, 7}
{5, 6, 7, 8, 9, 10, 11}
{1, 9, 1, 8, 1, 6, 1, 11}

これはなので、最短のコードがます。すべての言語での回答が推奨されます。


入力リストには常に少なくとも1つの要素が含まれていますか?
-nimi

2
それ以外の場合、@ nimiは無限の周期的なシーケンスを表しません。
マーティンエンダー

1
thue-morseシーケンスを使用して、各項に1より大きい正の固定整数を追加すると、このプロパティを持つ非周期的な無限シーケンスになります。
-SuperJedi224

回答:


7

ハスケル、 60 57 56 55バイト

f(a:b)=b==[]||length(fst$span(/=a)b)<=a&&f b
g x=f$x++x

入力リストに少なくとも1つの要素が含まれていると仮定します。

使用例:g [1]-> Trueオンラインでお試しください!

ましょうaリストの頭とb尾になります。結果はTrue、if bが空であるか、先頭の要素の数がb等しくない場合aaおよび再帰呼び出しのf bTrueelseですFalse。入力リストの2倍から始めます。

編集:@Leoは3バイトを保存しました。ありがとう!

編集2:@Laikoniは1バイトを節約しました。ありがとう!


スパンの代わりにtakeWhileを使用すると、パターンマッチングを回避し、3バイトのニースソリューションを節約できます。:)
レオ

@レオ:いいキャッチ!通常、using spanはusing よりも短いtakeWhileため、まったく見ませんでした。
-nimi

takeWhileほとんどの場合、常にfst$spanまたはfst.spanに短縮でき、別のバイトが節約されます。
ライコニ

@ライコニ:もちろん!ありがとう!
-nimi

ハスケル愛;)
theonlygusti

6

パイソン57 56バイト

デニスに-1バイトのおかげ(交換するi+1:i+v+2i:i-~vしてiから、1のオフセットenumerate

lambda a:all(v in(a+a)[i:i-~v]for i,v in enumerate(a,1))

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

無名関数、リストを取ってa、各値は、という条件テストv、表示inの連結でその右側に関連するスライスa、それ自体と(a+a)[i:i-~v]、1から始まるインデックスvではaiによって提供されますenumerate(a,1)


1
それが8バイトのゼリーの答えに影響を与えました。:) このようなバイトを保存できます。
デニス

6

JavaScript(ES6)、67 65 55 54 51 49バイト

@ETHproductionsのおかげで3B、@ Arnauldのおかげで2B節約

a=>!a.some((b,c)=>a.concat(a).indexOf(b,++c)>b+c)

説明

これは、配列aを入力として受け取る関数を定義します。次に、.someメソッドはその配列を反復処理し、すべての要素に対して別の関数を実行します。

この内部関数は2つの引数を取り、bそしてc、現在の値とそのインデックス。関数は、インデックスから開始して、現在の値のインデックスを見つけますc + 1。次に、このインデックスが現在の値に現在のインデックスを加えた値よりも大きいかどうかをチェックします(同じ値の2つのオカレンスの差はより大きいb)。これは、私たちが望むものの正反対を返すことに注意してください。

これらの戻り値のいずれかがの場合true.some関数trueも同様に戻ります。どのチェックも返らない場合true.some関数はfalse。ここでも、返したい値の反対なので、この結果は否定されてから返されます。

試して

ここですべてのテストケースを試してください。

let f=
a=>!a.some((b,c)=>a.concat(a).indexOf(b,++c)>b+c)

let truthy = [[1], [8, 9], [2, 3, 4], [5, 5, 3, 3, 6], [2, 3, 5, 2, 3, 6], [6, 7, 3, 5, 3, 7], [9, 4, 6, 7, 4, 5], [1, 1, 1, 1, 1, 100, 1], [1, 9, 1, 8, 1, 7, 1, 11]];
let falsy  = [[1, 2, 3], [2, 3, 9, 5], [3, 5, 4, 4, 6], [2, 3, 5, 2, 3, 4], [3, 5, 7, 5, 9, 3, 7], [5, 6, 7, 8, 9, 10, 11], [1, 9, 1, 8, 1, 6, 1, 11]];

console.log("Truthy test cases:");
for (let test of truthy) {
    console.log(`${test}: ${f(test)}`);
}

console.log("Falsy test cases:");
for (let test of falsy) {
    console.log(`${test}: ${f(test)}`);
}


非常に素晴らしい、それはまさに私が思いついたものです:-)開始時に一度二重配列を作成.shift()し、スライスに保存するために使用できます:a=>!a.some(b=>z.indexOf(z.shift())>b,z=a.concat(a))
ETHproductions

へへ、偉大なゴルファーは同じように考える;-)。私もシフトを使用することを考えましたが、それがより長いことが判明したので、私はそれを使用しませんでした。ダブル配列を一度作成して、毎回シフトするのは本当に賢いです。ありがとう!
ルーク

だろうa=>!a.some((n,i)=>a.concat(a).indexOf(n,++i)>n+i)動作しますか?
アーナウルド

はい、そうです。ありがとう!
ルーク

4

ゼリー、11バイト

ṣZL
;çЀ<‘P

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

使い方

;çЀ<‘P  Main link. Argument: A (array)

;        Concatenate A with itself.
 çD€     For each n in A, call the helper with left arg. A + A and right arg. n.
     ‘   Increment all integers in A.
    <    Perform element-wise comparison of the results to both sides.
      P  Take the product of the resulting Booleans.


ṣZL      Helper link. Left argument: A. Right argument: n

ṣ        Split A at all occurrences of n.
 Z       Zip to transpose rows and columns.
  L      Length; yield the number of rows, which is equal to the number of columns
         of the input to Z.

3

ゼリー、8バイト

ṙJḣ"‘Œpċ

に指示された のPython answerます

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

使い方

ṙJḣ"‘Œpċ  Main link. Argument: A (array)

 J        Yield the indicies of A, i.e., [1, ..., len(A)].
ṙ         Rotate; yield A, rotated 1, ..., and len(A) units rotated to the left.
    ‘     Increment; add 1 to all elements of A.
  ḣ"      Head zipwith; truncate the n-th rotation to length A[n]+1.
     Œp   Take the Cartesian product of all resulting truncated rotations.
       ċ  Count the number of times A appears in the result.

2

SWI-Prolog、83バイト

a(L,[H|R]):-nth0(X,R,H),H>=X,a(L,R);length(R,N),nth0(X,L,H),H>=N+X,a(L,R).
a(_,[]).


リストは2回入力する必要があります。

a([1,2,3],[1,2,3]).

これが受け入れられると見なされない場合は、述語を追加できます

a(L):-a(L,L).

余分な14バイトが追加されます。

オンラインで試す


nb:クエリを「;」で区切ることにより、さまざまな誤ったケースを一度にテストできます。(または)「、」で区切ることにより、異なる真のケースをテストします(および)

すなわち、OPの例を使用します。

a([1],[1]),
a([8, 9],[8, 9]),
a([2, 3, 4],[2, 3, 4]),
a([5, 5, 3, 3, 6],[5, 5, 3, 3, 6]),
a([2, 3, 5, 2, 3, 6],[2, 3, 5, 2, 3, 6]),
a([6, 7, 3, 5, 3, 7],[6, 7, 3, 5, 3, 7]),
a([9, 4, 6, 7, 4, 5],[9, 4, 6, 7, 4, 5]),
a([1, 1, 1, 1, 1, 100, 1],[1, 1, 1, 1, 1, 100, 1]),
a([1, 9, 1, 8, 1, 7, 1, 11],[1, 9, 1, 8, 1, 7, 1, 11]).

そして

a([1, 2, 3],[1, 2, 3]);
a([2, 3, 9, 5],[2, 3, 9, 5]);
a([3, 5, 4, 4, 6],[3, 5, 4, 4, 6]);
a([2, 3, 5, 2, 3, 4],[2, 3, 5, 2, 3, 4]);
a([3, 5, 7, 5, 9, 3, 7],[3, 5, 7, 5, 9, 3, 7]);
a([5, 6, 7, 8, 9, 10, 11],[5, 6, 7, 8, 9, 10, 11]);
a([1, 9, 1, 8, 1, 6, 1, 11],[1, 9, 1, 8, 1, 6, 1, 11]).

2

PHP、52バイト

for(;$n=$argv[++$i];$$n=$i)!$$n|$i-$$n<$n+2?:die(1);

コマンドライン引数からシーケンスを取ります。1虚偽、真実のコードで終了します0
で実行し-nrます。

  • $n引数をループする:
    • 以前に発生
      していないか、十分に新しい場合は何もせず、コードで終了します1
    • $$nvariable variables)での以前の発生を記憶します
  • コードで終了する0(暗黙的)

クレイジーな変数名は無効ですが、気に入っています。
ヨルクヒュルサーマン

2

網膜、50バイト

$
,$`
M!&`\b(1+),.*?\b\1\b
+%`(^1*)1,1+
$1
M`1,
^0

コンマ区切りの単項数のリストとして入力します。

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

説明

$
,$`

入力を複製して、最後にくるステップを確認できるようにします。

M!&`\b(1+),.*?\b\1\b

2つの同一の値の間の各(最短)セクションに一致して返します11,111,1,11

+%`(^1*)1,1+
$1

最初の数字から数字を繰り返し、その後に続く数字全体を削除します。ギャップが十分に小さい場合、これは最初の数値を完全に削除します。それ以外の場合、少なくとも1桁が残ります。

M`1,

1,すべての行に表示される頻度をカウントします。どこかに表示される場合、ステップの1つが広すぎました。

^0

0(つまり、0それ自体のみ)で始まる番号と一致させてください。これは、事実上、出力の論理否定です。


2

JavaScript(ES6)、47バイト

a=>![...a,...a].some((n,i)=>a[-n]-(a[-n]=i)<~n)

使い方

入力配列を再利用してa、最後に検出された各整数の位置を格納しaます。キーを使用して-nこの位置を保存し、元のインデックスと干渉しないようにしますaます。

ときにa[-n]存在する、実際のテストが起こります。ときはa[-n]存在しない、式がa[-n] - (a[-n] = i)等しいundefined - i == NaNととの比較は~n、予想される結果である、常にfalsyです。

テストケース


2

網膜 41 39バイト

2つのバイトが途中で彼とグループのバランスを紹介してくれたマーティン・エンダー、おかげgolfed SOに素晴らしいガイド

$
,$`,
((1)+,)(?=(?<-2>1+,)*(\1|$))

^$

入力は単項数のコンマ区切りリストです。出力は0falseおよび1trueです。

オンラインでお試しください!(10進数から自動的に変換するテストスイート)

私は最近、グループのバランスを取ることを学びましたので、試してみたいと思いました。これらは使用するのに最も簡単なツールではありませんが、強力であることを確認してください。

説明

$
,$`,

他の多くのサブミッションと同様に、リストを複製してラッピングを処理します。また、最後にコンマを追加するため、すべての数字の後にコンマが続きます(これにより、後から少し簡単になります)

((1)+,)(?=(?<-2>1+,)*(\1|$))

ここからがおもしろいところです。これは置換段階です。最初の行と一致するすべてのものを2番目の行に置き換えます。この場合は、n後に続かないすべての数値を削除しようとしています。n+1他の異なる番号がとしています。

これを行うには、最初に番号を一致させ1、グループ内のそれぞれをキャプチャします(この場合はグループ番号2をキャプチャします)。次に、肯定的な先読みを使用して、幅がゼロのアサーションを得るために-2、groupによって行われたキャプチャの数2、コンマが後に続くキャプチャの数以下で成功するバランシンググループで繰り返しマッチングを試みます。この一連の数字の後、最初の数字に再び到達するか、行の最後に到達すると満足です。

注:この表現は、完全な数字と一致するものが見つからない場合、数字の最後の部分のみに一致する可能性があります。これは問題ではありません。数値の最初の部分が文字列に残り、置換が完全に成功しなかったことがわかります。

^$

最後に、リストからすべての数字を完全に削除した場合、結果は真実になります。空の文字列を照合し、見つかった一致の数を返します。


1
よくやった!:)の必要はありません\b。これを削除すると、一致が失われますが、番号全体を削除できないため、とにかく空の文字列になりません。
マーティンエンダー

@MartinEnderあなたはもちろん正しいです、ありがとう:)
レオ

1

ゼリー、11バイト

ẋ2ĠṢI_2<"QȦ

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

ẋ2ĠṢI_2<"QȦ  Main link. Argument: A (array)

ẋ2           Repeat A twice to account for wrap-around.
  Ġ          Group all indices of A + A by their respective values, sorting the
             index groups by the associated values.
   Ṣ         Sort the groups lexicographically, i.e., by first appearance in A.
    I        Increments; compute the forward differences of adjacent indices in
             each of the groups.
     _2      Subtract 2 from the differences.
         Q   Unique; yield A, deduplicated.
       <"    Compare all differences in the index group corresponding to the n-th
             unique value in A with the n-th unqiue value in A.
          Ȧ  All; yield 1 if and only if none of the comparisons returned 0.


1

ローダ、50バイト

f a{seq 0,#a-1|[indexOf(a[_],a[_1+1:]..a)<=a[_1]]}

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

最後に!私は待っていました ました、この挑戦...

これは、真の値または偽の値を返す関数です。配列という1つの引数を取ります。

インデックスのストリームを反復処理し_1、現在のインデックスと次のインデックスの距離がをa[_1]超えないことを各インデックスごとにチェックしますa[_1]


どのように正確に機能し_1ますか?
クリチキシリトス

@KritixiLithosこれはのようなもの_ですが、最初にプルされた値を指します。複数_のを使用していた場合、それぞれが個別の値を取得していました。たとえば、[1, 2, 3] | print(_, _, _)prints 123ですが、[1,2,3] | print(_, _1, _1)印刷します111 222 333(別々の行に)。
fergusq

0

05AB1E、13バイト

Dì©v®¦©yky›_P

オンラインでお試しください! またはテストスイートとして

説明

Dì             # duplicate input and prepend the copy to the original
  ©            # store a copy in the register
   v           # for each element in the list
    ®          # push the list from register
     ¦©        # remove the first element and store a copy in the register
       yk      # get the index of the current element in the list
         y›_   # check if it's less than or equal to the current element
            P  # product of stack
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.