Berbeda Maju


23

Diberikan daftar bilangan bulat menghasilkan Perbedaan Maju pada urutan / kedalaman yang ditentukan.

Untuk daftar bilangan bulat:

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

Perbedaan Forward pada berbagai urutan / kedalaman adalah:

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

Begitu juga dengan input dari

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

Anda akan mengembalikan daftarnya

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

Memasukkan

Input dapat melalui STDIN atau parameter fungsi.

Integer yang menentukan kedalaman untuk kembali. Ini akan menjadi 0 sepanjang daftar minus 1

Daftar bilangan bulat untuk menghitung perbedaan penerusan

Keluaran

Outputnya bisa melalui STDOUT atau dikembalikan oleh fungsi.

Perbedaan penerusan untuk kedalaman yang ditentukan sebagai daftar bilangan bulat

Aturan

Fungsi bawaan dan Pihak Ketiga yang melakukan ini secara langsung tidak diperbolehkan.

Batasan celah standar berlaku.

Kode terpendek menang

Jawaban:


19

J, 15 9 7 byte

Sangat mudah. Membawa kedalaman dan daftar sebagai argumen kiri dan kanan.

-~/\~&2

Sebagai definisi eksplisit tanpa semua tipuan kata keterangan, ini dikurangi menjadi

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- Perbedaan ke depan y.
  • x -~/\~&2 y- Perbedaan xke depan -th y.

Jika saya membuat definisi yang serius (misalnya non-golf) dari fungsi ini, saya mungkin akan melakukan sesuatu seperti ini:

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

Kasing monadik menghitung selisih maju sedangkan kasidik menghitung xselisih kedepan.

Lebih sederhana, tetapi tidak persis sama:

+/\inv

+/\menghasilkan vektor dari jumlah awalan argumen. inv(Didefinisikan sebagai ^:_1) adalah konjungsi yang membalik kata kerja. Ini bekerja di mana pun J tahu cara membalikkan kata kerja dan untuk kasus +/\, J tahu caranya.


3
Ini menunjukkan kekuatan kata keterangan dan kata sambung seperti -satu-satunya kata kerja dalam fungsi ini.
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

Di sini kita melakukan pengurangan dengan zipping semua kecuali yang terakhir dari daftar dengan semua kecuali yang pertama dari daftar. zip(L[1:],L)setara dengan zip(L[1:],L[:-1]), karena zipsifat mengambil panjang minimum dari dua daftar:

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

Alternatif yang sama panjangnya (hanya Python 2):

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

Sayangnya Python 2 tidak memotong bagian akhir daftar, jadi saya tidak bisa melakukannya map(int.__sub__,L,L[1:]). Yang menjengkelkan, Python 3 tidak , tetapi maptidak lagi mengembalikan daftar jadi ini akhirnya menjadi byte lebih banyak (60 byte):

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

Namun, jika kita mengizinkan input menjadi kedalaman diikuti oleh daftar seperti f(3, 2, 5, 6, 7, 5, 10, 25)(yaitu kedalaman 3 dan daftar [2, 5, 6, 7, 5, 10, 25]), maka ini adalah 56 byte :

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

Berikut alternatif lain yang akan sangat mengganggu siapa pun yang melihat ini dalam kode produksi (yang satu ini menghancurkan daftar asli):

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

Kode terakhir Anda salah. Anda akan membutuhkannya L[1]-L.pop(0).
mbomb007

@ mbomb007 Terima kasih atas tangkapannya. Itu aneh - saya punya argumen di jalan yang salah sepanjang waktu.
Sp3000

Itu dekat, tetapi sesuatu seperti setiap kedalaman lainnya memiliki tanda-tanda terbalik.
mbomb007

9

Mathematica 23 57 23 byte

Saran Martin Büttner, memanfaatkan kelicikan pengurangan.

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

misalnya

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

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


Rest@#-Most@# melakukan pengurangan yang menghasilkan perbedaan.

Nest melakukan operasi tersebut beberapa kali, beroperasi selalu pada daftar terbaru.


7

Haskell, 40 34 byte

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

Contoh penggunaan: 4 # [10,18,-12,4,8,-3,-5,67,9,14]output mana [-142,55,27,41,-269,397].

Cara kerjanya: berulang kali menghitung perbedaan antara elemen tetangga dan menyimpan hasil antara dalam daftar. Ambil nelemen th dari daftar ini.

Sunting: @Zgarb menemukan 6 byte untuk disimpan. Luar biasa!


Anda dapat menggunakan fungsi monad dan mempersingkat lambda menjadi (zipWith(-)=<<tail).
Zgarb

7

JavaScript (ES6), 52 49 byte

Fungsi rekursif sederhana, digunakan mapuntuk memindai array dan sliceuntuk menjatuhkan elemen pertama pada setiap panggilan rekursif.

Edit 3 byte yang disimpan, terima kasih @DocMax, saran yang sangat cerdas

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

Uji di Firefox / konsol 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
Slice sebelum peta untuk efisien menghindari kebutuhan untuk pdan Hemat 3 karakter: H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax

6

CJam, 15 byte

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

Mengambil input sebagai larik gaya CJam dan kemudian kedalamannya:

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

dan mencetak hasilnya sebagai larik gaya CJam.

Uji di sini.

Penjelasan

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

Contoh Penggunaan: http://ideone.com/ALgYez

3 byte berkat Geobits: v)>


Anda harus menyingkirkan yang kedua int dan hanya menetapkan i=edengan yang lain.
Geobits

5

> <> 53 50 byte

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

Penggunaan: Mempopulasikan tumpukan (-v dalam python interpreter) dengan kedalaman terlebih dahulu, diikuti oleh bilangan bulat.

Sebagai contoh:

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

Kembali

2 -3 10 3

Terima kasih kepada Sp3000 untuk bantuannya.


1
Apakah mungkin menggunakan ?!dan memindahkan beberapa komponen daripada menggunakan 0=??
Sp3000

Tangkapan bagus! Itu membantu banyak
cirpis

5

Prelude , 95 92 79 78 byte

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

Format input adalah

N
M
n_1
n_2
...
n_M

di mana Nkedalaman perbedaan dan Mjumlah bilangan bulat dalam input. MenambahkanM diperlukan, karena tidak ada cara bagi Prelude untuk membedakan a 0dari akhir input. Output juga sebagai daftar bilangan bulat yang dipisahkan baris baru. Saya harus mengasumsikan spec Prelude yang sedikit disesuaikan yang kami buat untuk tantangan ini , karena Prelude standar membaca integer sebagai nilai byte, yang membuatnya tidak mungkin untuk memasukkan angka negatif. Pada dasarnya, ini adalah juru bahasa Python dengan NUMERIC_INPUTbendera tambahan .

Untuk referensi hanya ada 48 38 37 karakter non-spasi - sisanya hanya diperlukan untuk menyelaraskan kode dengan benar.

Penjelasan

Di Prelude, setiap baris adalah "suara" terpisah yang beroperasi pada tumpukannya sendiri. Program ini dieksekusi kolom demi kolom, di mana suara terpisah diambil untuk beroperasi "secara paralel". Semua perintah adalah karakter tunggal, dan tanda kurung adalah loop seperti Brainfuck (yang dimasukkan dan diulang setiap kali bagian atas tumpukan tidak nol). Perhatikan bahwa posisi vertikal tanda kurung tutup tidak relevan - menempatkannya dalam suara yang berbeda masih dianggap cocok dengan tanda kurung pembuka terbaru, dan tumpukan yang diperiksa untuk kondisi loop selalu suara di mana suara( muncul. Sekarang ke program ini ...

Program ini pada dasarnya dapat dipisahkan menjadi dua bagian. Dua baris terbawah hanya digunakan untuk sebagian besar loop dalam program (kecuali loop utama berakhir N), lewat1 bolak-balik. Dua baris teratas berisi loop utama dan perbedaan aktual. Anotasi berikut mengubah kode, jadi saya dapat memberi anotasi pada masing-masing kolom:

? ?   # 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

Versi non-golf sebelum saya menjadi rekursif:

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

Rekursi!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • xadalah jumlah iterasi yang harus dilakukan, dan ymerupakan vektor bilangan bulat.
  • if(x)benar selama x>0.
  • Recall memanggil fungsi saat ini tetapi dengan argumen baru.
  • Diff menampilkan perbedaan antara elemen daftar / vektor berturut-turut.

Versi sebelumnya:

#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

Apakah ada cara yang lebih baik untuk mengulangi fungsi diff x kali? Menggunakan for for terasa berlebihan.
freekvd

Ada Mengurangi, tetapi saya pikir itu akan membutuhkan lebih banyak karakter.
MickyT

Ada satu masalah kecil. Ketika dipanggil dengan 0 kedalaman, ia mengembalikan kedalaman 2
MickyT

Pergi untuk pendekatan yang berbeda, masalah diselesaikan tetapi harus menambahkan 7 karakter.
freekvd

2
Penggunaan yang bagus 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)

Ini golf Python pertamaku. Setiap saran akan dihargai :)

5 6 byte berkat Sp3000: D


Saya akan merekomendasikan daftar pemahaman.
mbomb007

Anda bisa mengubahnya appendmenjadi d+=f-e,. Secara umum, untuk kode-golf Anda tidak perlu menggunakan L.appendkarena ini.
Sp3000

3

c, 68 55 byte

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

Ini mungkin mengambil kebebasan dengan spesifikasi input sedikit. Array int dibangun sedemikian rupa sehingga elemen 0 adalah kedalaman dan elemen 1 hingga (n + 1) adalah elemen daftar input 0 hingga n. Kemudian alamat elemen 1 diteruskan ke fungsi.

Array harus nol diakhiri. Array diedit di tempat.

Misalnya:

#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


Mengapa Anda meninggalkan ruang 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','}

Jalankan seperti itu:

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

Keluaran:

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

Memindahkan penahan keriting ke tempat yang berbeda memungkinkan ini untuk menampilkan setiap langkah ke jawabannya.

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

Mengharapkan input sebagai integer yang mewakili kedalaman, diikuti oleh daftar integer yang dipisahkan spasi, keduanya diberikan melalui prompt standar. Output adalah daftar integer yang dipisahkan oleh baris baru.

Pertama itu mengkonversi daftar bilangan bulat (yang dilihat sebagai 1 string panjang) menjadi daftar variabel lokal yang namanya 1,2,3, ... Kemudian menghitung perbedaan maju dengan menetapkan nilai variabel lokal y menjadi nilai variabel lokal y + 1 dikurangi nilai variabel lokal y (yaitu 18-10 = 8), yang menimpa nilai yang ada hanya setelah digunakan. Itu melakukan ini $ a (nilai variabel global a) kali. Kemudian akan ditampilkan nilai setiap variabel lokal, 1 pada satu waktu.


+1 untuk penjelasan. Ini adalah cara pemrosesan daftar yang sangat rumit.
Zgarb

@ Zgarb, saya tidak tahu cara STATA untuk mengambil input sebagai array / daftar kecuali melalui file (yang tidak akan berfungsi di sini karena input lainnya). Itu sebabnya harus bekerja seperti ini.
tanda

2

T-SQL, Terlalu Banyak :)

Ketika saya pertama kali melihat masalah ini, saya bertanya-tanya apakah ada cara untuk melakukan ini dalam kueri. Meskipun sepele untuk sebagian besar bahasa, tidak terlalu banyak untuk query SQL.

Input masuk ke variabel @ (untuk kedalaman) dan @L untuk daftar bilangan bulat. @ L adalah tipe tabel yang ditentukan pengguna

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

Pengaturan input

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

Permintaan dengan beberapa komentar

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

Hasil

-142
55
27
41
-269
397


0

SmileBASIC, 76 byte

Akhirnya alasan untuk menggunakan 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))))

Rekursi sederhana pada fungsi anonim. Anda menghemat 1 byte jika urutan argumen bertukar seperti sekarang%2 terjadi lebih sering daripada %.


0

Jelly , 2 byte

Cobalah online!

Penjelasan

I¡  Main Link
 ¡  Repeat `n` times; this repeats the previous link by <right argument> times
I   Get forward differences

Jawaban yang sangat mudah: P


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.