第N个差异


26

在数学中,一种计算给定关系的类型(线性,二次等)的方法是计算差异。为此,您要获取一个y值列表,其对应的x值之间的差距相同,然后从其上的数字中减去每个数字,从而创建一个比上一个列表短一的数字列表。如果结果列表完全由相同的数字组成,则该关系的差为1(线性)。如果它们不相同,则在新列表上重复该过程。如果它们现在相同,则该关系具有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作为输出?
魔术章鱼缸

行为对于无效的输入是不确定的(我不在乎您的代码做什么)
Gryphon-恢复Monica

不应该[1,2,1]给2吗?[1,2,1] -> [1,-1] -> [-2]
HyperNeutrino

@HyperNeutrino,是的,对不起。我有一个脑放屁有
狮鹫-恢复莫妮卡

添加此测试用例[1,3,9,26,66,150,313,610]-> 6如果您喜欢
J42161217'9

Answers:


10

外壳,6个字节

感谢Leo让我使用他的适用于[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


5

Mathematica,49个字节

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

thanx @alephalpa为-6个字节和@hftf -1个字节

这是@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]是错误的;!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}

在线尝试!

说明:该函数将输入作为一个列表。然后,它构建一个类似的递归序列:第一个元素是原始列表($_),下一个元素通过{@(@$_ Z- .[1..*])}在前一个元素上调用而返回,并且迭代直到条件*.none为真为止,只有在列表为为空或仅包含零(或从技术上讲,为其他虚假值)。然后,我们抓取列表并从中减去2,这首先将其强制到数字上下文中(并且数字上下文中的列表等于其元素的数量),最后,返回的值比列表中元素的数量少2。清单。

怪异的代码块{@(@$_ Z- .[1..*])}仅获取给定的列表(.[]-称为Zen slice-用括号括起来的索引会产生整个列表),使用减号运算符(Z-)将其压缩,并且列表相同,但不包含第一个元素(.[1..*]),并将其强制到列表(@(...)—我们需要它,因为zip仅返回一个Seq,这基本上是一个单向列表,只能迭代一次。这是我们不喜欢的。)就是这样。


更改@(.[] Z- .[1..*])[.[] Z-.[1..*]]应该节省两个字节。
nwellnhof

4

爪哇8,191 + 58 = 249个 198 140字节。

感谢PunPun1000 51字节。
感谢Nevay提供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)您不应该接受第二个参数,但是删除它实际上可以节省字节。3)您可以在那里删除一些不需要的支架
PunPun1000

4)不是保护程序,但是如果可能的话,您应该包括一个TIO,下面是带有198字节TIO
PunPun1000


3

Haskell,46个字节

g l|all(==l!!0)l=0|0<1=1+g(zipWith(-)l$tail l)

这只是递归- zipWith(-)l$last l是的差异列表l。并且g是回答问题的功能。


递归解决方案是个好方法。
jferard

@jferard这是真的
骄傲的haskeller

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参加测试

在线试用


欢迎来到PPCG!不错的第一答案,也是一个室外高尔夫球场。
H.PWiz

3

APL(Dyalog Classic)22 17字节

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

在线尝试!

感谢@ngn提供-5个字节!

怎么样?

  • { ... }, 功能
  • 1=≢∪⍵:0,如果参数中的每个元素都相等,则返回 0
  • 1+∇2-/⍵,否则,返回1 + n的差(即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ÐḟL七(我看到迈尔斯还发现使用递归的七)。
乔纳森·艾伦

@JonathanAllan酷,谢谢!
HyperNeutrino

2

05AB1E,7个字节

[DË#¥]N

在线尝试!

说明

[         # start loop
 D        # duplicate current list
  Ë       # are all elements equal?
   #      # if so, break
    ¥     # calculate delta's
     ]    # end loop
      N   # push iteration counter

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个字节感谢Jonathan Allan。

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
乔纳森·艾伦


仅仅是我还是切换到递归Lambda不能节省足够的字节数?:P谢谢!
–totalhuman

我认为这需要max(...,0)通过[1, 1, 1, 1, ...]测试用例。
Yonatan 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循环在检查条件之前运行(与先检查条件然后运行代码相反)。因此,在1 1 1 1 1正常情况下,该示例将无法正常工作。

在线尝试确定!

在k解释器中使用1 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个字节

多亏了骄傲的haskeller,节省了1个字节

iterate(z(-)) 计算差异列表。

or.z(/=) 测试这些列表中是否有不相等的元素。

length.takeWhile 计算具有不相等元素的差异列表。


我认为您可以使用以下方法测试不相等的元素or.z(/=)
Christian Sievers

@ChristianSievers谢谢!那是显而易见的,但是我没有看到……
jferard

您还可以使用z=(=<<tail).zipWith,短1个字节
骄傲的haskeller

@proudhaskeller更加优雅,一如既往地带有无点定义。谢谢!
jferard


2

Japt,7个字节

Justin相同的方法(但独立派生),但实现方式不同。

£=äaÃèx

测试一下


说明

数组的隐式输入U

£   Ã

映射每个元素。

äa

ä元素中的每个顺序对(),U并通过绝对差(a)减少它。

=

将该数组重新分配给U

èx

计数(è)当加法运算减少时返回真值(即非零)的子数组的数量。


1

TI基本(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。
凯文·克鲁伊森

@KevinCruijssen谢谢!另外,哎呀。
GrzegorzPuławski17年

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)


很好,正是我想做的,但我一直在努力寻找紧凑的成对差异。太好了,我将来必须记住这一点。
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先生17年

0

Perl 5,83 +1(-a)= 84字节

sub c{$r=0;$r||=$_-$F[0]for@F;$r}for(;c;$i=0){$_-=$F[++$i]for@F;$#F--}say y/ //-$#F

在线尝试!

输入为以空格分隔的数字列表。



0

Pyth,10个字节

tf!t{.+FQt

如果我们可以从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

科特林,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")}
    }
}

在线试用


如果有人可以编辑以解决我的语言提示,我似乎无法使它们正常工作
jrtapsell

lang-kotlin,不是简单的kotlin,在荧光笔提示。
Ruslan

0

斯威夫特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!")
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.