Sự khác biệt thứ n


26

Trong toán học, một cách để tìm ra loại quan hệ đã cho (tuyến tính, bậc hai, v.v.) là gì để tính toán sự khác biệt. Để làm như vậy, bạn lấy một danh sách các giá trị y mà khoảng cách giữa các giá trị x tương ứng là như nhau và trừ đi từng giá trị từ số trên nó, tạo một danh sách các số ngắn hơn danh sách trước đó. Nếu danh sách kết quả hoàn toàn gồm các số giống nhau, thì mối quan hệ có chênh lệch 1 (nó là tuyến tính). Nếu chúng không giống nhau, thì bạn lặp lại quy trình trong danh sách mới. Nếu bây giờ chúng giống hệt nhau, mối quan hệ có chênh lệch là 2 (nó là bậc hai). Nếu chúng không giống nhau, bạn chỉ cần tiếp tục quá trình này cho đến khi chúng được. Ví dụ: nếu bạn có danh sách các giá trị y [1,6,15,28,45,66] để tăng dần các giá trị x:

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

Nhiệm vụ của bạn:

Viết chương trình hoặc hàm, khi được cung cấp một mảng số nguyên làm đầu vào, trả về sự khác biệt của mối quan hệ được mô tả bởi mảng, như được giải thích ở trên.

Đầu vào:

Một mảng các số nguyên, có thể có độ dài bất kỳ> 1.

Đầu ra:

Một số nguyên biểu thị sự khác biệt của mối quan hệ được mô tả bởi đầu vào.

Các trường hợp thử nghiệm:

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

Ghi điểm:

Đây là , điểm số thấp nhất tính theo byte trong mỗi ngôn ngữ sẽ giành chiến thắng cho ngôn ngữ đó. Điểm thấp nhất tổng thể được đánh dấu màu xanh lá cây.


Đầu vào có thể "không hợp lệ" như trong, nếu đầu vào KHÔNG phù hợp với thông số kỹ thuật được cung cấp, chúng ta có nên lỗi không? Cung cấp -1 làm đầu ra?
Bạch tuộc ma thuật Urn

Hành vi không được xác định cho đầu vào không hợp lệ (Tôi không quan tâm mã của bạn làm gì)
Gryphon - Phục hồi Monica

Không nên [1,2,1]cho 2? [1,2,1] -> [1,-1] -> [-2]
HyperNeutrino

@HyperNeutrino, vâng, xin lỗi. Tôi bị đánh rắm não ở đó
Gryphon - Tái lập Monica

Thêm trường hợp thử nghiệm này [1,3,9,26,66,150,313,610]-> 6nếu bạn thích
J42161217

Câu trả lời:


10

Husk , 6 byte

Cảm ơn Leo đã cho tôi sử dụng phiên bản của anh ấy phù hợp với[1,1,1,1,1,1]

←VE¡Ẋ-

Hãy thử trực tuyến!

Giải trình

   ¡     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
Bất cứ khi nào ai đó nói Husk là Jelly mới, họ đều rất nguy hiểm. > _ <
Zacharý

Chết tiệt, tôi sẽ đăng cái này . Làm tốt lắm, +1!
Leo

@Leo, trường hợp thử nghiệm tôi không thấy [1,1,1,1], tôi có thể sử dụng của bạn không?
H.PWiz

@ H.PWiz chắc chắn, tiếp tục!
Leo

7

JavaScript (ES6), 47 byte

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

Các trường hợp thử nghiệm


7

MATL , 8 byte

`dta}x@q

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Điều này bao gồm các khác biệt liên tiếp lặp đi lặp lại cho đến khi kết quả là tất cả các số không hoặc trống. Đầu ra là số lần lặp yêu cầu trừ đi 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

Toán học, 49 byte

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

thanx @alephalpa cho -6 byte và @hftf -1 byte

và đây là một cách tiếp cận khác từ @hftf

Toán học, 49 byte

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

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

1
UnsameQ[1,2,1]là sai; !SameQ[1,2,1]là đúng. Tôi không nghĩ rằng vòng lặp thủ công cũng lưu các ký tự: Length@NestWhileList[Differences,#,!SameQ@@#&]-1&đã có cùng độ dài với vòng lặp của bạn sau khi thay thế UnsameQbằng !SameQ.
hftf


4

Japt , 10 7 byte

è@=ä-)d

Hãy thử trực tuyến!

Dựa vào thực tế là kết quả được đảm bảo nằm trong độ dài của mảng đầu vào.

Giải trình

è@=ä-)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

Cuối cùng, điều này sẽ ánh xạ mảng
[1, 3, 9, 26, 66, 150, 313, 610]tới [true, true, true, true, true, true, false, false],
chứa 6 trues.

Phiên bản 10 byte trước đó

@=ä-)e¥0}a

Hãy thử trực tuyến!


4

Perl 6 , 37 byte

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

Hãy thử trực tuyến!

Giải thích: Hàm lấy đầu vào làm một danh sách. Sau đó, nó xây dựng một chuỗi đệ quy như thế này: phần tử đầu tiên là danh sách gốc ( $_), các phần tử tiếp theo được trả về bằng cách {@(@$_ Z- .[1..*])}được gọi trên phần tử trước đó và được lặp lại cho đến khi điều kiện *.nonelà đúng, chỉ xảy ra khi danh sách là trống hoặc chỉ chứa các số 0 (hoặc, về mặt kỹ thuật, các giá trị falsey khác). Sau đó, chúng tôi lấy danh sách và trừ 2 từ nó, trước tiên nó buộc nó vào bối cảnh số (và danh sách trong ngữ cảnh số bằng với số phần tử của chúng) và, cuối cùng, trả về 2 ít hơn số phần tử trong danh sách.

Khối lạ {@(@$_ Z- .[1..*])}chỉ lấy danh sách đã cho ( .[]- còn gọi là Zen lát - lập chỉ mục với dấu ngoặc rỗng mang lại toàn bộ danh sách), nén nó bằng toán tử trừ ( Z-) với cùng một danh sách mà không có phần tử đầu tiên ( .[1..*]) và buộc nó vào danh sách ( @(...)- chúng tôi cần điều đó bởi vì zip chỉ trả về một Seq, về cơ bản là danh sách một chiều có thể được lặp lại một lần. Đó là điều chúng tôi không thích.) Và đó là điều đó.


Thay đổi @(.[] Z- .[1..*])thành [.[] Z-.[1..*]]nên tiết kiệm hai byte.
nwellnhof

4

Java 8, 191 + 58 = 249 198 140 byte.

Cảm ơn PunPun1000 cho 51 byte.
Cảm ơn Nevay cho 58 byte.

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);}

Hãy thử trực tuyến!

Dùng thử trực tuyến (phiên bản 198 byte)

Vì vậy, đây là lần đầu tiên tôi đăng bài ở đây trong PPCG (và lần đầu tiên thực hiện một thử thách golf mã). Bất kỳ lời phê bình mang tính xây dựng đều được chào đón và đánh giá cao. Tôi đã cố gắng làm theo các hướng dẫn để đăng, nếu bất cứ điều gì không đúng hãy thoải mái chỉ ra nó.

Phiên bản làm đẹp:

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
Chào mừng đến với trang web!
DJMcMayhem

Thay vì nhập các mô-đun đó, bạn chỉ có thể sử dụngjava.util.stream.IntStream k = java.util.Arrays.stream(a);
PunPun1000

Trong thực tế, có một vài thay đổi bạn có thể thực hiện miễn phí. 1) publickhông cần đưa vào số byte. 2) Bạn không nên chấp nhận tham số thứ hai, nhưng loại bỏ nó thực sự có thể lưu byte. 3) bạn có thể xóa một số dấu ngoặc không cần thiết ở đó
PunPun1000

4) Không phải là trình tiết kiệm nhưng bạn nên bao gồm TIO nếu có thể, đây là một ví dụ với những gợi ý đó ở 198 byte TIO
PunPun1000


3

Haskell, 46 byte

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

điều này chỉ đơn giản là đệ quy - zipWith(-)l$last llà danh sách khác biệt của l. và glà chức năng trả lời câu hỏi.


giải pháp đệ quy là một giải pháp tốt.
jferard

@jferard điều đó rất đúng
tự hào

3

Kotlin , 77 byte

bài đăng đầu tiên, đã cố gắng chỉnh sửa câu trả lời cuối cùng trên kotlin 2 lần; D

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

đã tham gia thử nghiệm từ @jrtapsell

Dùng thử


Chào mừng đến với PPCG! Câu trả lời đầu tiên tốt đẹp, một outgolf quá.
H.PWiz

3

APL (Dyalog Classic) , 22 17 byte

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

Hãy thử trực tuyến!

Cảm ơn @ngn cho -5 byte!

Làm sao?

  • { ... }, chức năng
  • 1=≢∪⍵:0, nếu mọi phần tử đều bằng nhau trong đối số, trả về 0
  • 1+∇2-/⍵, nếu không, trả lại 1 + ncủa sự khác biệt (nghĩa là n-1thêm một điểm khác biệt n)

nó ngắn hơn nếu bạn hy sinh tính đệ quy đuôi:{1=≢∪⍵:0⋄1+∇2-/⍵}
ngn

2

Thạch , 7 byte

IÐĿEÐḟL

Hãy thử trực tuyến!

Giải trình

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 byte nhờ Jonathan Allan


1
@Gryphon Xong! :)
HyperNeutrino

IÐĿEÐḟLtrong bảy (tôi thấy Miles cũng tìm thấy bảy bằng cách sử dụng đệ quy).
Jonathan Allan

@Jonathan ALLan Cảm ơn tuyệt vời!
HyperNeutrino


2

JavaScript (ES6), 58 byte

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

+0, không đủ Jquery: p. Thực sự, +1, công việc tốt, tôi biết tôi sẽ không bao giờ có thể chơi gôn trong JS.
Zacharý

2

Python 2 , 65 byte

-7 byte nhờ 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

Hãy thử trực tuyến!


Lưu một byte initialising cđến 1, decrementing và sau đó sử dụng print-c.
Jonathan Allan

Tiết kiệm thêm sáu bằng cách biến nó thành một hàm đệ quy:f=lambda l,c=1:any(l)and f([j-i for i,j in zip(l,l[1:])],c-1)or-c
Jonathan Allan

Có phải chỉ tôi hay là việc chuyển sang lambda đệ quy không lưu đủ byte? : P Cảm ơn!
hoàn toàn là

Tôi nghĩ rằng điều này cần max(...,0)phải vượt qua các [1, 1, 1, 1, ...]trường hợp thử nghiệm.
Yonatan N

2

APL Dyalog, 19 byte

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

Giải trình:

≢                      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
Nó có hoạt động không? ≢-1+∘≢2-/⍣{1=≢∪⍵}⊢
Zacharý

2

k , 21 byte

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

Điều này hoạt động trong k, nhưng không phải trong oK, bởi vì vòng lặp while của oK chạy trước khi kiểm tra điều kiện (trái ngược với việc kiểm tra điều kiện trước, sau đó chạy mã). Do đó, trong oK, 1 1 1 1 1ví dụ sẽ không hoạt động đúng.

Hãy thử oK trực tuyến!

Chạy ví dụ k với 1 1 1 1 1 1 trong trình thông dịch k.

Giải trình:

   (        )       \ /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

Haskell , 66 61 60 byte

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

Hãy thử trực tuyến!

Đã lưu 5 byte nhờ Christian Sievers

Đã lưu 1 byte nhờ kiêu hãnh

iterate(z(-)) tính toán các danh sách khác nhau.

or.z(/=) kiểm tra nếu có các yếu tố không bằng nhau trong các danh sách đó.

length.takeWhile đếm các danh sách khác nhau với các yếu tố không bằng nhau.


Tôi nghĩ bạn có thể kiểm tra các yếu tố không bằng nhau vớior.z(/=)
Christian Sievers

@ChristianSievers cảm ơn! Điều đó là hiển nhiên, nhưng tôi đã không nhìn thấy nó ...
jferard

Bạn cũng có thể sử dụng z=(=<<tail).zipWith, ngắn hơn một byte
tự hào

@proudhaskeller và thanh lịch hơn, như mọi khi với các định nghĩa miễn phí điểm. Cảm ơn!
jferard


2

Japt , 7 byte

Cách tiếp cận tương tự (nhưng xuất phát độc lập) như Justin với cách thực hiện khác.

£=äaÃèx

Kiểm tra nó


Giải trình

Đầu vào ngầm định của mảng U.

£   Ã

Bản đồ qua từng yếu tố.

äa

Lấy từng cặp ( ä) các phần tử liên tiếp Uvà giảm nó bằng sự khác biệt tuyệt đối ( a).

=

Tái chỉ định mảng đó cho U.

èx

Đếm ( è) số lượng các mảng con trả về giá trị trung thực (nghĩa là khác không) khi được giảm bằng phép cộng.


1

TI-Basic, 19 byte

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

Theo mặc định, các biến bắt đầu từ 0. Ngoài ra, không bao giờ nghĩ rằng tôi đang sử dụng IS>(cho bất cứ điều gì hữu ích.


1

C # (.NET Core) , 70 69 + 18 byte

-1 byte nhờ Kevin Cruijssen

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

Phải được cho 0 khi gọi để hoạt động chính xác. Cũng bao gồm trong số byte:

using System.Linq;

Hãy thử trực tuyến!

Giải trình:

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

Phiên bản lặp 84 + 18 byte:

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

Hãy thử trực tuyến!


1
Bạn có thể loại bỏ không gian dư thừa tại (y,z)=>y-z. Nhưng câu trả lời hay, +1 từ tôi.
Kevin Cruijssen

@KevinCruijssen cảm ơn bạn! Ngoài ra, rất tiếc.
Grzegorz Puławski

1

Clojure, 62 byte

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

Hoàn toàn =có thể lấy bất kỳ số lượng đối số nào và một đối số duy nhất giống hệt với "chính nó". (apply = [1 2 3])được thực hiện như (= 1 2 3).


Đẹp, chính xác những gì tôi đã cố gắng để làm nhưng tôi đã đấu tranh cho một cặp đôi nhỏ gọn khác nhau. Thật tuyệt vời, tôi sẽ phải nhớ điều đó cho tương lai.
MattPutnam

1

Bình thường , 15 byte

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

Xác nhận tất cả các trường hợp thử nghiệm.

Làm sao?

Giải thích số 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 byteWtl{Q=hZ=.+Q)Z
Dave

@Dave Thậm chí tốt hơn : WP{Q=hZ=.+Q)Z. Cảm ơn!
Ông Xcoder

0

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

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

Hãy thử trực tuyến!

Nhập dưới dạng danh sách các số cách nhau bởi một khoảng trắng.



0

Bình thường, 10 byte

tf!t{.+FQt

Nếu chúng ta có thể lập chỉ mục từ 1, chúng ta có thể lưu một byte bằng cách loại bỏ hàng đầu t.

Dùng thử trực tuyến

Giải trình

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 byte

{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}

Làm đẹp

{
    // 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
}

Kiểm tra

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")}
    }
}

Dùng thử


Nếu ai đó có thể chỉnh sửa để sửa chữa gợi ý ngôn ngữ của tôi, tôi dường như không thể khiến họ làm việc
jrtapsell

Đó là lang-kotlin, không chỉ đơn giản kotlin, trong các gợi ý highllight.
Ruslan

0

Swift 4 , 90 byte

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

Thay thế, thực hiện dựa trên đóng cửa:

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

trường hợp thử nghiệm:

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!")
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.