N番目の違い


26

数学では、与えられた関係のタイプ(線形、二次など)を把握する1つの方法は、差を計算することです。これを行うには、対応するx値間のギャップが同じy値のリストを取得し、その上の数値からそれぞれを減算し、前のリストより1つ短い数値のリストを作成します。結果のリストが完全に同一の数値で構成されている場合、関係には1の差があります(線形です)。同一でない場合は、新しいリストでプロセスを繰り返します。それらが現在同一である場合、関係には2の差があります(2次です)。それらが同一でない場合は、それらが同一になるまでこのプロセスを続行します。たとえば、x値を増分的に増やすためのy値[1,6,15,28,45,66]のリストがある場合:

First Differences:

1
6   1-6  =-5
15  6-15 =-9
28  15-28=-13
45  28-45=-17
66  45-66=-21

Second differences:

-5 
-9  -5+9  =4
-13 -9+13 =4
-17 -13+17=4
-21 -17+21=4

As these results are identical, this relation has a difference of 2

あなたのタスク:

入力として整数の配列が与えられると、上で説明したように、配列によって記述された関係の差を返すプログラムまたは関数を書きます。

入力:

整数の配列。長さは1より大きい場合があります。

出力:

入力によって記述された関係の差を表す整数。

テストケース:

Input                            => Output
[1,2,3,4,5,6,7,8,9,10]           => 1
[1,4,9,16,25,36]                 => 2
[1,2,1]                          => 2 (when there is only one value left, all values are automatically identical, so the largest difference an array can have is equal to the length of the array-1)
"Hello World"                    => undefined behavior (invalid input)
[1,1,1,1,1,1,1,1,1]              => 0 (all elements are already identical)
[1, 3, 9, 26, 66, 150, 313, 610] => 6

得点:

これは、各言語のバイト単位の最低スコアがその言語で勝ちます。総合的に最低スコアは緑色のチェックマークを取得します。


入力が指定された仕様に適合しない場合、入力は「無効」にできますか?出力として-1を指定しますか?
魔法のタコUr

無効な入力に対する動作は未定義です(コードが何をするかは気にしません)
グリフォン-モニカの復活

[1,2,1]2を与えるべきではありませんか?[1,2,1] -> [1,-1] -> [-2]
ハイパーニュートリノ

@HyperNeutrino、うん、ごめんなさい。私はそこで頭を抱えていました
グリフォン-モニカの復活

このテストケースを追加[1,3,9,26,66,150,313,610]> - 6あなたが好きなら
J42161217

回答:


10

、6バイト

おかげでレオを、私は彼のために働くのバージョンを使用させるための[1,1,1,1,1,1]

←VE¡Ẋ-

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

説明

   ¡     Repeatedly apply function, collecting results in a list
    Ẋ-     Differences
 VE      Get the index of the first place in the list where all the elements are equal
←        Decrement

2
誰かがハスクが新しいゼリーだと言ったときはいつでも、彼らはかなり適切でした。> _ <
ザカリー

くそー、私はこれを投稿するつもりだった。いい仕事だ、+ 1!
レオ

@Leo、私が見なかったテストケース[1,1,1,1]、あなたのものを使用できますか?
H.PWiz

@ H.PWiz確かに、続けてください!
レオ

7

JavaScript(ES6)、47バイト

f=a=>-a.every(x=>i=!x)||1+f(a.map(n=>n-a[++i]))

テストケース


7

MATL、8バイト

`dta}x@q

オンラインでお試しください!または、すべてのテストケースを確認します

説明

これにより、結果がすべてゼロになるか空になるまで、連続した差異が反復的に強制されます。出力は、必要な反復回数から1を引いたものです。

`      % Do... while
  d    %   Consecutive diffferences. Takes input (implicitly) the first time
  t    %   Duplicate
  a    %   True if any element is nonzero. This is the loop condition
}      % Finally (execute before exiting the loop)
  x    %   Delete. This removes the array of all zeros
  @    %   Push iteration index
  q    %   Subtract 1. Implicitly display
       % End (implicit). Proceed with next iteration if top of the stack is true

7

R50 44バイト

function(l){while(any(l<-diff(l)))F=F+1
F*1}

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

diffofを取り、lそれをに設定しl、結果にゼロ以外の値が含まれているかどうかを確認します。存在する場合、インクリメントFFALSE暗黙的に初期化)し、すべてが既に同一である場合F*1に変換FALSEに戻ります。0l



5

Mathematica、49バイト

(s=#;t=0;While[!SameQ@@s,s=Differences@s;t++];t)&  

-6バイトと@hftf -1バイトの@alephalpaに感謝

そして、これは@hftfからの別のアプローチです

Mathematica、49バイト

Length@NestWhileList[Differences,#,!SameQ@@#&]-1&

(s=#;t=0;While[UnsameQ@@s,s=Differences@s;t++];t)&
alephalpha

1
UnsameQ[1,2,1]Falseです。!SameQ[1,2,1]本当です。:私は手動ループがいずれかの文字を保存しないと思うLength@NestWhileList[Differences,#,!SameQ@@#&]-1&すでに交換した後、あなたと同じ長さであるUnsameQ!SameQ
hftf


4

Japt10 7バイト

è@=ä-)d

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

結果が入力配列の長さ内にあることが保証されているという事実に依存しています。

説明

è@=ä-)d     Implcit input of array U
 @          For each value in U...
  =ä-)      Update U to be equal to its subsections, each reduced by subtraction
      d     Check if any values in that are truthy
è           Count how many items in that mapping are true

年末までに、これは配列にマップされます
[1, 3, 9, 26, 66, 150, 313, 610][true, true, true, true, true, true, false, false]
含まれている6 trueのを。

以前の10バイトバージョン

@=ä-)e¥0}a

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


4

Perl 6、37バイト

{($_,{@(.[] Z- .[1..*])}...*.none)-2}

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

説明:この関数は入力を1つのリストとして受け取ります。次に、このような再帰シーケンスを構築します。最初の要素は元のリスト($_)で、次の要素は{@(@$_ Z- .[1..*])}前の要素で呼び出されることで返され、条件*.noneがtrueになるまで繰り返されます。空またはゼロのみを含む(または技術的には他の偽の値)。次に、リストを取得し、そこから2を減算します。これにより、最初にリストが数値コンテキストに強制され(そして数値コンテキストのリストは要素の数に等しくなります)、最後に、リスト。

奇妙なブロック{@(@$_ Z- .[1..*])}は、指定されたリストを取得し(.[]—いわゆるZenスライス —空の括弧でインデックス付けすると、リスト全体が生成されます)、Z-最初の要素(.[1..*])のない同じリストでマイナス演算子()を使用して圧縮し、リストに強制します(@(...)— zipはSeqのみを返すため、これが必要です。これは基本的に、1回だけ反復できる一方向のリストです。これは私たちが嫌いなことです。)それだけです。


に変更@(.[] Z- .[1..*])する[.[] Z-.[1..*]]と、2バイト節約されます。
nwellnhof

4

Java 8、191 + 58 = 249 198 140バイト。

51バイトをありがとうPunPun1000。
58バイトをありがとう。

int f(int[]a){int x=a.length-1,b[]=new int[x];for(;x-->0;)b[x]=a[x+1]-a[x];return java.util.Arrays.stream(a).distinct().count()<2?0:1+f(b);}

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

オンラインで試す(198バイトバージョン)

したがって、PPCGでの投稿はこれが初めてです(コードゴルフチャレンジは初めてです)。建設的な批判は歓迎します。正しくないことがあれば、投稿のガイドラインに従ってください。

美化バージョン:

int f(int[] a) {
    int x = a.length - 1, b[] = new int[x];
    for (; x-- > 0;) {
        b[x] = a[x + 1] - a[x];
    }
    return java.util.Arrays.stream(a).distinct().count() < 2 ? 0 : 1 + f(b);
}

3
サイトへようこそ!
DJMcMayhem

これらのモジュールをインポートする代わりに、ただ使用できますjava.util.stream.IntStream k = java.util.Arrays.stream(a);
PunPun1000

実際、無料で行える変更がいくつかあります。1)publicバイトカウントに含める必要はありません。2)2番目のパラメーターを受け入れるべきではありませんが、それを削除すると実際にバイトを節約できます。3)不要なブラケットをそこから削除できます
PunPun1000

4)未セーバーが、可能な場合にはTIOを含める必要があり、ここでバイト198でこれらの提案を持つ例であるTIO
PunPun1000



3

Kotlin、77バイト

最初の投稿、kotlinに関する最後の回答を2回編集しようとしました; D

{var z=it;while(z.any{it!=z[0]})z=z.zip(z.drop(1),{a,b->a-b});it.size-z.size}

@jrtapsellからテストの一部を取りました

TryItOnline


PPCGへようこそ!素敵な最初の答え、アウトゴルフも。
H.PWiz

3

APL(Dyalog Classic)22 17バイト

{1=≢∪⍵:01+∇2-/⍵}

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

-5バイトの@ngnに感謝します!

どうやって?

  • { ... }、 関数
  • 1=≢∪⍵:0、引数のすべての要素が等しい場合、戻ります 0
  • 1+∇2-/⍵、それ以外の場合、n差分の1 + を返します(n-1つまり、1を追加するとが得られますn

末尾再帰性を犠牲にすると短くなります{1=≢∪⍵:0⋄1+∇2-/⍵}
。– ngn

2

ゼリー、7バイト

IÐĿEÐḟL

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

説明

IÐĿEÐḟL  Main link
 ÐĿ      While results are unique (which is never so it stops at [])
I        Take the increments, collecting intermediate values # this computes all n-th differences
    Ðḟ   Filter out
   E     Lists that have all values equal (the first n-th difference list that is all equal will be removed and all difference lists after will be all 0s)
      L  Take the length (this is the number of iterations required before the differences become equal)

ジョナサン・アランのおかげで-1バイト


1
@Gryphon完了!:)
HyperNeutrino

IÐĿEÐḟL7日間(Milesは再帰を使用して7を見つけました)。
ジョナサンアラン

@JonathanAllanどうもありがとう!
ハイパーニュートリノ


2

JavaScript(ES6)、58バイト

f=a=>+(b=a.slice(1).map((e,i)=>e-a[i])).some(e=>e)&&1+f(b)

+0、不十分なJquery:p。本当に、+ 1、いい仕事だ、JSでゴルフができなくなることはわかっている。
ザカリー

2

Python 2、65バイト

ジョナサン・アランのおかげで-7バイト。

f=lambda l,c=1:any(l)and f([j-i for i,j in zip(l,l[1:])],c-1)or-c

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


バイトを初期化cして保存し1、デクリメントしてから使用しprint-cます。
ジョナサンアラン

保存6より再帰関数にそれを行うことによって:f=lambda l,c=1:any(l)and f([j-i for i,j in zip(l,l[1:])],c-1)or-c
ジョナサン・アラン

それは私だけですか、それとも再帰的なラムダへの切り替えは十分なバイトを保存していませんか?:Pありがとう!
完全に人間

これにはmax(...,0)[1, 1, 1, 1, ...]テストケースに合格する必要があると思います。
ヨナタンN

2

Dyalog APL、19バイト

≢-1+(≢2-/⍣{1=≢∪⍵}⊢)

説明:

≢                      length of input
 -1+(             )    minus 1+
     ≢                 length of
      2-/              differences between elements
         ⍣             while
          {1=≢∪⍵}      there is more than 1 unique element
                 ⊢     starting with the input

1
これは機能しますか?≢-1+∘≢2-/⍣{1=≢∪⍵}⊢
ザカリー

2

k、21バイト

#1_(~&/1_=':)(1_-':)\

これはkでは機能しますが、oKでは機能しません。これは、条件をチェックする前にoKのwhileループが実行されるためです(最初に条件をチェックしてからコードを実行するのとは対照的です)。したがって、OKでは、この1 1 1 1 1例は適切に機能しません。

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

kインタープリターで1 1 1 1 1 1を使用してkの例を実行します。

説明:

   (        )       \ /while(
    ~&/               /      not(min(
       1_=':          /              check equality of all pairs))) {
             (1_-':)  /    generate difference list
                      /    append to output }
#1_                   /(length of output) - 1

~&/1_=':->1<#?
ngn

2

Haskell66 61 60バイト

z=(=<<tail).zipWith
f=length.takeWhile(or.z(/=)).iterate(z(-))

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

Christian Sieversのおかげで5バイト節約

proud-haskellerのおかげで1バイト節約

iterate(z(-)) 差分リストを計算します。

or.z(/=) これらのリストに等しくない要素があるかどうかをテストします。

length.takeWhile 等しくない要素を持つ差分リストをカウントします。


等しくない要素をテストできると思いますor.z(/=)
クリスチャンシーバーズ

@ChristianSieversありがとう!それは明らかだったが、私はそれを見ていない...
jferard

を使用することもできますz=(=<<tail).zipWith、1バイト短く
誇りに思ってhaskeller

@proudhaskellerおよびよりエレガントな、いつものようにポイントフリーの定義。ありがとう!
jferard


2

Japt、7バイト

実装が異なるジャスティンと同じアプローチ(ただし、独立して派生)。

£=äaÃèx

試して


説明

arrayの暗黙的な入力U

£   Ã

各要素にマップします。

äa

ä要素の各連続ペア()を取得しU、絶対差(a)で減らします。

=

その配列をに再割り当てしUます。

èx

è加算によって削減されたときに真理値(ゼロ以外)を返すサブ配列の数をカウントします。


1

TI-Basic、19バイト

While max(abs(ΔList(Ans
ΔList(Ans
IS>(A,9
End
A

デフォルトでは、変数はゼロから始まります。また、私がIS>(有用なものに使用するとは思わなかった。


1

C#(.NET Core)70 69 + 18バイト

-1バイト、Kevin Cruijssenに感謝

g=a=>i=>a.Distinct().Count()>1?g(a.Zip(a.Skip(1),(y,z)=>y-z))(i+1):i;

正しく動作するために呼び出す場合は0を指定する必要があります。バイトカウントにも含まれます。

using System.Linq;

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

説明:

g = a => i =>                      // Function taking two arguments (collection of ints and an int)
    a.Distinct()                   // Filter to unique elements
    .Count() > 1 ?                 // If there's more than one element
        g(                         //     Then recursively call the function with
            a.Zip(                 //     Take the collection and perform an action on corresponding elements with another one
                a.Skip(1),         //         Take our collection starting at second element
                (y, z) => y - z    //         Perform the subtraction
            )
        )(i + 1)                   //     With added counter
        : i;                       // Otherwise return counter

反復バージョン84 + 18バイト:

a=>{int i=0;for(;a.Distinct().Count()>1;i++)a=a.Zip(a.Skip(1),(y,z)=>y-z);return i;}

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


1
冗長スペースはで削除でき(y,z)=>y-zます。しかし、いい答えです、私から+1。
ケビンCruijssen

@KevinCruijssenありがとうございます!また、おっと。
グルジェゴルツプワフスキ

1

Clojure、62バイト

#(loop[c % i 0](if(apply = c)i(recur(map -(rest c)c)(inc i))))

素敵な=任意の数の引数を取り、単一の引数には、「自分自身」と同じですことができます。(apply = [1 2 3])として実行され(= 1 2 3)ます。


ニース、まさに私がやろうとしていたことですが、コンパクトなペアワイズdiffに苦労していました。それは素晴らしいです。将来のためにそれを覚えておく必要があります。
MattPutnam

1

Pyth、15バイト

W.E.+Q=.+Q=hZ)Z

すべてのテストケースを確認します。

どうやって?

説明#1

W.E.+Q=hZ=.+Q)Z   ~ Full program.

W                 ~ While...
 .E.+Q            ~ ... The deltas of Q contain a truthy element.
      =hZ         ~ Increment a variable Z, which has the initial value of 0.
         =        ~ Transform the variable to the result of a function applied to itself...
          .+Q     ~ ... Operate on the current list and deltas.
             )Z   ~ Close the loop and output Z.

-1バイトWtl{Q=hZ=.+Q)Z
Dave

@Daveさらに良い:WP{Q=hZ=.+Q)Z。ありがとう!
ミスターXcoder



0

Pyth、10バイト

tf!t{.+FQt

1からインデックスを作成できる場合は、先頭のを削除して1バイト節約できますt

オンラインで試す

説明

tf!t{.+FQt
 f        T  Find the first (1-indexed) value T...
     .+FQt   ... such that taking the difference T - 1 times...
  !t{        ... gives a set with more than one value in it.
t            0-index.

0

Kotlin、83バイト

{var z=it
var c=0
while(z.any{it!=z[0]}){c++
z=(0..z.size-2).map{z[it+1]-z[it]}}
c}

美化

{
    // Make input mutable
    var z=it
    // Count for returning
    var c=0
    // While the array is not identical
    while (z.any { it != z[0] }) {
        // Increment count
        c++
        // Update list to differences
        z = (0..z.size-2).map { z[it+1] - z[it] }
    }
    // Return count
    c
}

テスト

var n:(List<Int>)->Int =
{var z=it
var c=0
while(z.any{it!=z[0]}){c++
z=(0..z.size-2).map{z[it+1]-z[it]}}
c}

data class TestData(var input: List<Int>, var output: Int)

fun main(args: Array<String>) {
    val items = listOf(
        TestData(listOf(1,2,3,4,5,6,7,8,9,10), 1),
        TestData(listOf(1,4,9,16,25,36), 2),
        TestData(listOf(1,2,1), 2),
        TestData(listOf(1,1,1,1,1,1,1,1,1), 0),
        TestData(listOf(1, 3, 9, 26, 66, 150, 313, 610), 6)
    )

    val fails = items.map { it to n(it.input) }.filter { it.first.output != it.second }

    if (fails.isEmpty()) {
        println("Test passed")
    } else {
        fails.forEach {println("FAILED: $it")}
    }
}

TryItOnline


誰かが私の言語のヒントをください修正するために編集することができれば、私は彼らが働くように見えることはできません
jrtapsell

それはだlang-kotlinていないだけで、kotlin蛍光ペンのヒントで、。
ルスラン

0

Swift 4、90バイト

func f(_ a:[Int])->Int{return a.contains{$0 != a[0]} ?f(zip(a, a.dropFirst()).map(-))+1:0}

代替のクロージャーベースの実装:

var f: ((_ input: [Int]) -> Int)!
f = {a in a.contains{$0 != a[0]} ?f(zip(a, a.dropFirst()).map(-))+1:0}

テストケース:

let testcases: [(input: [Int], expected: Int)] = [
    (input: [1,2,3,4,5,6,7,8,9,10],           expected: 1),
    (input: [1,4,9,16,25,36],                 expected: 2),
    (input: [1,2,1],                          expected: 2),
    (input: [1,1,1,1,1,1,1,1,1],              expected: 0),
    (input: [1, 3, 9, 26, 66, 150, 313, 610], expected: 6),
]

for (caseNumber, testcase) in testcases.enumerated() {
    let actual = f(testcase.input)
    assert(actual == testcase.expected,
        "Testcase #\(caseNumber) \(testcase.input) failed. Got \(actual), but expected \(testcase.expected)!")
    print("Testcase #\(caseNumber) passed!")
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.