Con đường khác nhau về phía trước


23

Đưa ra một danh sách các số nguyên tạo ra sự khác biệt về phía trước theo một thứ tự / độ sâu được chỉ định.

Đối với danh sách các số nguyên:

(10, 18, -12, 4, 8, -3, -5, 67, 9, 14)

Sự khác biệt về phía trước ở các đơn hàng / độ sâu khác nhau là:

0   10,   18,  -12,    4,    8,   -3,   -5,  67,  9,  14
1      8,  -30,   16,    4,  -11,   -2,   72, -58,  5
2       -38,   46,  -12,  -15,    9,   74, -130, 63
3           84,  -58,   -3,   24,   65, -204, 193
4            -142,   55,   27,   41, -269, 397
5               197,  -28,   14, -310, 666
6                 -225,   42, -324, 976
7                    267, -366, 1300
8                      -633, 1666
9                         2299

Vì vậy, với đầu vào của

4, (10, 18, -12, 4, 8, -3, -5, 67, 9, 14)

Bạn sẽ trả lại danh sách

(-142,   55,   27,   41, -269, 397)

Đầu vào

Đầu vào có thể thông qua STDIN hoặc các tham số chức năng.

Một số nguyên chỉ định độ sâu để trả về. Điều này sẽ là 0 đến độ dài của danh sách trừ đi 1

Danh sách các số nguyên để tính chênh lệch chuyển tiếp cho

Đầu ra

Đầu ra có thể thông qua STDOUT hoặc được trả về bởi hàm.

Sự khác biệt về phía trước cho độ sâu được chỉ định dưới dạng danh sách các số nguyên

Quy tắc

Các chức năng được xây dựng trong và bên thứ 3 thực hiện điều này trực tiếp không được phép.

Hạn chế kẽ hở tiêu chuẩn áp dụng.

Mã ngắn nhất sẽ thắng

Câu trả lời:


19

J, 15 9 7 byte

Rất dễ. Có chiều sâu và liệt kê như các đối số trái và phải.

-~/\~&2

Là một định nghĩa rõ ràng mà không có tất cả các mánh khóe trạng từ, điều này giảm xuống

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- Sự khác biệt về phía trước của y.
  • x -~/\~&2 y- Sự xkhác biệt về phía trước của y.

Nếu tôi định đưa ra một định nghĩa nghiêm túc (tức là không chơi gôn) cho chức năng này, tôi có thể sẽ làm một cái gì đó như thế này:

(}. - }:) : ($:@[&0)

Trường hợp đơn tính tính chênh lệch về phía trước trong khi trường hợp dyadic tính toán xchênh lệch chuyển tiếp -th.

Thậm chí đơn giản hơn, nhưng không chính xác bằng:

+/\inv

+/\mang lại một vectơ tổng các tiền tố của đối số. inv(được định nghĩa là ^:_1) là một từ kết hợp đảo ngược một động từ. Điều này hoạt động bất cứ nơi nào J biết cách đảo ngược một động từ và trong trường hợp +/\, J biết làm thế nào.


3
Điều này cho thấy sức mạnh của trạng từ và liên từ như -là động từ duy nhất trong chức năng này.
Randomra

14

Python, 61 59 byte

f=lambda n,L:n and f(n-1,[x-y for x,y in zip(L[1:],L)])or L

Ở đây chúng tôi thực hiện phép trừ bằng cách nén tất cả trừ phần cuối cùng của danh sách với tất cả trừ phần đầu tiên của danh sách. zip(L[1:],L)tương đương với zip(L[1:],L[:-1]), do zipbản chất của việc lấy độ dài tối thiểu của hai danh sách:

>>> zip([1,2,3],[4,5])
[(1, 4), (2, 5)]

Một thay thế chỉ dài như vậy (chỉ Python 2):

f=lambda n,L:n and f(n-1,map(int.__sub__,L[1:],L[:-1]))or L

Thật không may, Python 2 không cắt hết danh sách, vì vậy tôi không thể làm được map(int.__sub__,L,L[1:]). Khó chịu, Python 3 cũng vậy , nhưng mapkhông còn trả về một danh sách nữa nên cuối cùng nó trở thành một byte nhiều hơn (60 byte):

f=lambda n,L:n and f(n-1,list(map(int.__sub__,L[1:],L)))or L

Tuy nhiên, nếu chúng ta cho phép đầu vào là độ sâu theo sau là danh sách như f(3, 2, 5, 6, 7, 5, 10, 25)(tức là độ sâu 3 và danh sách [2, 5, 6, 7, 5, 10, 25]), thì đây là 56 byte :

f=lambda n,*T:n and f(n-1,*map(int.__sub__,T[1:],T))or T

Đây là một giải pháp thay thế khác thực sự gây khó chịu cho bất kỳ ai nhìn thấy mã này trong mã sản xuất (cái này sẽ phá hủy danh sách gốc):

f=lambda n,L:n and f(n-1,[L[1]-L.pop(0)for _ in L[1:]])or L

Mã cuối cùng của bạn là không chính xác. Bạn sẽ cần L[1]-L.pop(0)thay thế.
mbomb007

@ mbomb007 Cảm ơn bạn đã bắt. Điều đó thật khó xử - Tôi đã có những cuộc tranh cãi xung quanh sai thời gian.
Sp3000

Nó rất gần, nhưng một cái gì đó giống như mọi độ sâu khác đều có dấu hiệu đảo ngược.
mbomb007

9

Toán học 23 57 23 byte

Đề nghị của Martin Büttner, khai thác khả năng nghe của phép trừ.

 Rest@#-Most@#&~Nest~##&

ví dụ

Rest@# - Most@# &~Nest~## & @@ {{10, 18, -12, 4, 8, -3, -5, 67, 9, 14}, 4}

{-142, 55, 27, 41, -269, 397}


Rest@#-Most@# thực hiện phép trừ mang lại sự khác biệt.

Nest thực hiện thao tác cho biết số lần chỉ định, hoạt động luôn trong danh sách gần đây nhất.


7

Haskell, 40 34 byte

n#l=iterate(zipWith(-)=<<tail)l!!n

Ví dụ sử dụng: 4 # [10,18,-12,4,8,-3,-5,67,9,14]đầu ra nào [-142,55,27,41,-269,397].

Cách thức hoạt động: liên tục tính toán sự khác biệt giữa các yếu tố lân cận và lưu trữ các kết quả trung gian trong một danh sách. Lấy nyếu tố thứ từ danh sách này.

Chỉnh sửa: @Zgarb tìm thấy 6 byte để lưu. Tuyệt vời!


Bạn có thể sử dụng chức năng đơn nguyên và rút ngắn lambda thành (zipWith(-)=<<tail).
Zgarb

7

JavaScript (ES6), 52 49 byte

Hàm đệ quy đơn giản, sử dụng mapđể quét mảng và slicethả phần tử đầu tiên vào mỗi lệnh gọi đệ quy.

Chỉnh sửa 3 byte đã lưu, cảm ơn @DocMax, đề xuất thực sự thông minh

F=(n,l)=>n?F(n-1,l.slice(1).map((a,k)=>a-l[k])):l

Kiểm tra trong bảng điều khiển Firefox / FireBug

for(i=0;i<10;i++)console.log(F(i,[10, 18, -12, 4, 8, -3, -5, 67, 9, 14]))

[10, 18, -12, 4, 8, -3, -5, 67, 9, 14]
[8, -30, 16, 4, -11, -2, 72, -58, 5]
[-38 , 46, -12, -15, 9, 74, -130, 63]
[84, -58, -3, 24, 65, -204, 193]
[-142, 55, 27, 41, -269, 397 ]
[197, -28, 14,-310, 666]
[-225, 42, -324, 976]
[267, -366, 1300]
[-633, 1666]
[2299]


1
Cắt lát trước bản đồ để tránh hiệu quả nhu cầu pvà lưu 3 ký tự : H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax 24/2/2015

6

CJam, 15 byte

l~{{_@-\}*;]}*p

Lấy đầu vào là một mảng kiểu CJam và sau đó là độ sâu:

[10 18 -12 4 8 -3 -5 67 9 14] 4

và in kết quả dưới dạng mảng kiểu CJam.

Kiểm tra nó ở đây.

Giải trình

l~              "Read and eval input.";
  {         }*  "Repeat this block N times, which computes the forward differences.";
   {    }*      "Fold this block onto the list - this is quite an abuse of folding semantics.";
    _           "Duplicate the current element (for the use in the next difference).";
     @          "Pull up the other copy of the last element.";
      -         "Subtract.";
       \        "Swap the difference and the other copy of the current element.";
          ;     "Discard the last element.";
           ]    "Wrap everything in an array again.";

5

Java, 122 119 byte

int[]a(int[]a,int b){if(b<1)return a;int e=a.length-1,c[]=new int[e],i=e;for(;i-->0;)c[i]=a[i+1]-a[i];return a(c,b-1);}

Cách sử dụng ví dụ: http://ideone.com/ALgYez

3 byte nhờ Geobits: v)>


Bạn nên thoát khỏi thứ hai int và chỉ cần giao i=evới những người khác.
Geobits 23/2/2015

5

> <> 53 50 byte

l:[2-&\~~]r1-:?!vr
&}-@:$/!?&:-1
:;!? &&  lo*84n~<       

Cách sử dụng: Đặt trước ngăn xếp (-v trong trình thông dịch python) với độ sâu trước, sau đó là số nguyên.

Ví dụ:

forward.fish -v 3 2 5 6 7 5 10 25

Trả về

2 -3 10 3

Cảm ơn Sp3000 vì sự giúp đỡ.


1
Có thể sử dụng ?!và di chuyển một số thành phần xung quanh chứ không phải 0=??
Sp3000 24/2/2015

Bắt tốt đẹp! Điều đó giúp một bó
cirpis

5

Mở đầu , 95 92 79 78 byte

?    (1-vv- # ) v  !
  ?     #   ^   #
?(1-)   1  (#)  1)(#)
  1   #(# ) 1  (#

Định dạng đầu vào là

N
M
n_1
n_2
...
n_M

trong đó Nđộ sâu của sự khác biệt và Mlà số nguyên trong đầu vào. Việc thêm Mlà cần thiết, bởi vì không có cách nào để Prelude phân biệt a 0với phần cuối của đầu vào. Đầu ra cũng là một danh sách các số nguyên được phân tách mới. Tôi đã phải giả sử thông số Prelude được điều chỉnh một chút mà chúng tôi đã nghĩ ra cho thử thách này , bởi vì Prelude tiêu chuẩn đọc các số nguyên dưới dạng giá trị byte, khiến cho không thể nhập số âm. Về cơ bản, đây là trình thông dịch PythonNUMERIC_INPUTcờ bổ sung .

Để tham khảo, chỉ có 48 38 37 ký tự không phải khoảng trắng - phần còn lại chỉ cần thiết để căn chỉnh mã chính xác.

Giải trình

Trong Prelude, mỗi dòng là một "tiếng nói" riêng hoạt động trên ngăn xếp riêng của nó. Chương trình được thực hiện theo từng cột, trong đó các giọng nói riêng biệt được thực hiện để hoạt động "song song". Tất cả các lệnh là các ký tự đơn và dấu ngoặc đơn là các vòng lặp giống như Brainfuck (được nhập và lặp lại bất cứ khi nào đỉnh của ngăn xếp khác không). Lưu ý rằng vị trí dọc của dấu ngoặc đơn đóng là không liên quan - đặt nó ở một giọng nói khác vẫn được tính là khớp với dấu ngoặc đơn mở gần đây nhất và ngăn xếp được kiểm tra cho điều kiện vòng lặp luôn là giọng nói (xuất hiện. Bây giờ vào chương trình này ...

Chương trình về cơ bản có thể được tách thành hai phần. Hai dòng dưới cùng chỉ được sử dụng cho hầu hết các vòng lặp trong chương trình (ngoại trừ vòng lặp chính qua N), truyền qua 1lại. Hai dòng trên cùng chứa vòng lặp chính và sự khác biệt thực tế. Chú thích sau đây có mã được chuyển đổi, vì vậy tôi có thể chú thích các cột riêng lẻ:

? ?   # Read two integers. Read instructions are processed top to bottom, so the first voice 
      # reads N and the third voice reads M.
  (   # Start a loop on the third voice. This loop will execute M times, reading the input list
      # and pushing M 1s onto the fourth voice - i.e. a unary representation of M.
 ?11  # Read an integer onto the second voice, push 1s onto the third and fourth voice.
  -   # Subtract the 1 from the third voice, decrementing M down to 0.
  )   # End of loop, if the third voice is not 0 yet, to back two columns.
(     # Start a loop on the first voice. This is the main loop and will execute N times. Each
      # iteration will compute the forward differences once and thereby shorten the list by one
      # element and also reduce the stack of 1s on the bottom voice by one.
1  #  # Push a 1 onto the first voice and pop a 1 from the last. Together with the next column,
      # this decrements both N and (the unary) M.
-  (  # Subtract the 1 from the first voice (decrementing N), and start a loop on the fourth 
      # voice over whatever is left of M (the length of the resulting difference list). Note 
      # that this column is *not* part of the loop, so the - on the first voice will only be 
      # executed once. This loop builds the differences in reverse order on the first voice.
v#1#  # Pop a 1 from the fourth voice and push a 1 onto the third. This loops over M while
      # shifting its unary representation to the other stack. In addition, shift the top stack
      # element from the second to the first voice.
v     # Copy the next element from the second voice to the first, without popping.
-  )  # Subtract the two elements on the first voice and end the loop if the fourth voice is 
      # empty. Note that his column *is* part of the loop.
  (   # Start a loop on the third voice. This is another loop over M, shifting the stack of 1s 
      # back to the fourth voice, and reversing the differences by shifting them onto the 
      # second.
#^#1  # As stated above, shift an element from the first to the second voice, a 1 from the
      # third to the fourth.
  )   # End the loop. After this point, we're back to the original situation, except that the
      # second voice has been replaced by its differences. The bottom stack element the
      # previous list is also still on that stack, but the decreasing loop lengths on the third
      # and fourth voices ensures that this element is never touched again.
)     # End the main loop when N has been reduced to 0.
   (  # Start another loop over the remaining list length, shifting and reversing the result.
v#1#  # Shift a 1 back to the third voice and an element from the second to the first voice.
  )   # End the loop. Note that this parenthesis is not on the same voice as the corresponding
      # opening parenthesis, but its exact position is irrelevant. Moving it to this voice
      # saves a byte.
  (   # Start one last loop over the length of the result.
! #   # Pop a 1 from the third voice while printing (and popping) one element of the result.
  )   # End the loop.

5

Python, 70 68 67 59 byte

f=lambda x,n:n and f([x[1]-x.pop(0)for i in x[1:]],n-1)or x

Phiên bản không chơi gôn trước khi tôi đi đệ quy:

def f(x,n):
    for j in range(n):
        for i in range(len(x)-1):
            x[i]=x[i+1]-x[i]
    return x[:-n]

5

R, 48 39 46 44 byte

Đệ quy!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • xlà số lần lặp để thực hiện và ylà một vectơ số nguyên.
  • if(x)là đúng miễn là x>0.
  • Recall gọi hàm hiện tại nhưng với các đối số mới.
  • Diff đưa ra sự khác biệt giữa các yếu tố danh sách / vector liên tiếp.

Những phiên bản trước:

#does not work for x=0:
function(x,y){for(i in 1:x)y=diff(y);y}

#does not use diff function:
function(x,y){for(i in 1:x)y=y[-1]-head(y,-1);y}

y[-1]       is a list minus its first element
head(y,-1)  is a list minus its last element

Có cách nào tốt hơn để lặp lại hàm diff x lần không? Sử dụng một vòng lặp for cảm thấy quá mức.
freekvd

Có Giảm, nhưng tôi nghĩ sẽ tốn nhiều ký tự hơn.
MickyT

Có một vấn đề nhỏ. Khi được gọi với độ sâu 0, nó trả về độ sâu 2
MickyT

Đã đi cho một cách tiếp cận khác, vấn đề được giải quyết nhưng phải thêm 7 ký tự.
freekvd

2
Sử dụng tốt đẹp của Recall().
Alex A.

3

Python, 92 87 86 byte

def a(b,c):
 if c<1:return b
 d=[];e=b[0]
 for f in b[1:]:d+=f-e,;e=f
 return a(d,c-1)

Đây là sân gôn Python đầu tiên của tôi. Bất kỳ đề xuất sẽ được đánh giá cao :)

5 6 byte nhờ Sp3000: D


Tôi muốn giới thiệu một sự hiểu biết danh sách.
mbomb007 23/2/2015

Bạn có thể biến appendthành d+=f-e,. Nói chung, đối với môn đánh gôn, bạn sẽ không bao giờ cần phải sử dụng L.appendvì điều này.
Sp3000

3

c, 68 55 byte

f(int *l){for(--l[-1]?f(l):0;*l;l++)*l=l[1]-*l;*--l=0;}

Điều này có thể được tự do với thông số kỹ thuật đầu vào một chút. Một mảng int được xây dựng sao cho phần tử 0 là độ sâu và các phần tử 1 đến (n ​​+ 1) là các phần tử danh sách đầu vào 0 đến n. Sau đó, địa chỉ của phần tử 1 được truyền cho hàm.

Mảng phải được kết thúc bằng không. Các mảng được chỉnh sửa tại chỗ.

Ví dụ:

#include <stdio.h>

f(int *l){for(--l[-1]?f(l):0;*l;l++)*l=l[1]-*l;*--l=0;}

int main (int argc, char **argv)
{
  int list[] = {4, 10, 18, -12, 4, 8, -3, -5, 67, 9, 14, 0};
  int *elem;

  f(list + 1);

  for (elem = list + 1; *elem; elem++) {
    printf("%d, ", *elem);
  }
}

http://ideone.com/m5PDgF


Tại sao bạn để lại một không gian trong int *l?
Jonathan Frech

2

Powershell 115 111 byte

$p={param($a, $b)0..($a-1)|%{$b=@($l=$b.length;for($i=0;$i-lt$l;$i++){$b[$i+1]-$b[$i]})[0..($l-2)]};$b-join','}

Thực thi như vậy:

.$p 4 @(10,18,-12,4,8,-3,-5,67,9,14)

Đầu ra:

-142,55,27,41,-269,397

Di chuyển một dấu ngoặc nhọn đến một vị trí khác cho phép điều này hiển thị từng bước cho câu trả lời.

8,-30,16,4,-11,-2,72,-58,5
-38,46,-12,-15,9,74,-130,63
84,-58,-3,24,65,-204,193
-142,55,27,41,-269,397

2

STATA, 126 byte

di _r(a)_r(b)
token $b
gl $c=wordcount($b)
forv x=1/$a{
gl $c--
forv y=1/$c{
loc `y'=``y'+1'-``y''
}
}
forv z=1/$c{
di ``z''
}

Yêu cầu đầu vào là một số nguyên biểu thị độ sâu, theo sau là danh sách các số nguyên được phân tách bằng dấu cách, cả hai được đưa ra thông qua dấu nhắc tiêu chuẩn. Đầu ra là danh sách các số nguyên được phân tách.

Đầu tiên, nó chuyển đổi danh sách các số nguyên (mà nó xem là 1 chuỗi dài) thành một danh sách các biến cục bộ có tên là 1,2,3, ... Sau đó, nó tính toán các khác biệt về phía trước bằng cách đặt giá trị của biến cục bộ thứ y thành giá trị của biến cục bộ y + 1 trừ đi giá trị của biến cục bộ yth (tức là 18-10 = 8), ghi đè các giá trị hiện có chỉ sau khi sử dụng. Nó thực hiện điều này $ a (giá trị của biến toàn cục a) lần. Sau đó, nó sẽ hiển thị giá trị của từng biến cục bộ, 1 tại một thời điểm.


+1 để giải thích. Đây là một cách xử lý danh sách khủng khiếp.
Zgarb

@Zgarb, tôi không biết cách để STATA lấy đầu vào dưới dạng một mảng / danh sách ngoại trừ thông qua tệp (không hoạt động ở đây vì đầu vào khác). Đó là lý do tại sao nó phải làm việc như thế này.
đánh dấu

2

T-SQL, quá nhiều :)

Khi tôi lần đầu tiên nhìn thấy vấn đề này, tôi tự hỏi liệu có cách nào để làm điều này trong một truy vấn không. Mặc dù tầm thường đối với hầu hết các ngôn ngữ, nhưng nó không quá nhiều cho truy vấn SQL.

Đầu vào đi vào các biến @ (cho độ sâu) và @L cho danh sách số nguyên. @L là loại bảng do người dùng xác định

CREATE TYPE L AS TABLE(n INT IDENTITY(0,1),v INT)

Thiết lập đầu vào

DECLARE @L L,@ INT=4
INSERT @L(v)values(10),(18),(-12),(4),(8),(-3),(-5),(67),(9),(14)

Truy vấn với một số ý kiến

WITH R AS( 
    -- Recursive query to calculate the level of a pascal triangle with alternating negatives
    -- For 4 this is 1 -4  6 -4  1  
    SELECT 1c,0g UNION ALL SELECT-c*(@-g)/(g+1),g+1FROM r WHERE g<@
    ),
    O AS( 
    --Multiple N values of list by reversed pascal triangle values
    --shifting the start for each iteration (list length) - N
    SELECT c*v v,F 
    FROM @L L 
        CROSS APPLY(
            SELECT TOP((SELECT COUNT(*)FROM @L)-@)ROW_NUMBER()OVER(ORDER BY(SELECT\))-1F FROM sys.all_views a,sys.all_views b)c 
        JOIN R ON N=F+@-G
    )
-- Sum the multiplied values
SELECT SUM(V)FROM o GROUP BY F ORDER BY F

Kết quả

-142
55
27
41
-269
397

2

Japt -h , 17 5 byte

12 byte được lưu nhờ @Shaggy

VÆ=än

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



Hoặc một cách thực hiện khác cung cấp 12 byte
Shaggy

Bạn có thể thay thế äÏ-Xbằng äncả hai để tiết kiệm thêm 2 byte.
Shaggy

Có nó xuống đến 5 byte !
Xù xì

@Shaggy chết tiệt, bạn quá giỏi trong japt xD Bạn nên đăng câu trả lời 5 byte của mình
Luis felipe De jesus Munoz

0

SmileBASIC, 76 byte

Cuối cùng là một lý do để sử dụng ARYOP!

DEF F L,D
IF!D THEN@R
DIM B[0]COPY B,L
T=SHIFT(L)ARYOP 1,L,L,B
F L,D-1@R
END

0

Clojure, 47 byte

#(if(= 0 %)%2(recur(dec %)(map -(rest %2)%2))))

Một đệ quy đơn giản về chức năng ẩn danh. Bạn lưu 1 byte nếu thứ tự các đối số được hoán đổi vì bây giờ %2xảy ra thường xuyên hơn %.



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.