別の方法


23

整数のリストを指定すると、指定した順序/深さで前方差分が生成されます。

整数のリストの場合:

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

さまざまな注文/深さでの前方差異は次のとおりです。

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

だからの入力で

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

あなたはリストを返します

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

入力

入力には、STDINまたは関数パラメーターを使用できます。

返す深さを指定する整数。これは、0からリストの長さから1を引いた値になります。

前方差分を計算する整数のリスト

出力

出力は、STDOUTを介するか、関数によって返されます。

整数のリストとして指定された深さの前方差分

ルール

これを直接行うビルトインおよびサードパーティの機能は許可されていません。

標準的な抜け穴の制限が適用されます。

最短のコードが勝つ

回答:


19

J、15 9 7バイト

非常に簡単。左右の引数として深さとリストを取ります。

-~/\~&2

副詞的なトリックを一切使用しない明示的な定義として、これは

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y–の前方差y
  • x -~/\~&2 y–- x番目の前方差分y

私が作るとしたら、重大な(。。すなわち非golfed)この関数の定義、私はおそらくこのような何かをするだろう。

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

モナドの場合は前方差分を計算し、ダイアディックの場合はx-番目の前方差分を計算します。

さらに簡単ですが、正確に等しくありません:

+/\inv

+/\引数のプレフィックスの合計のベクトルを生成します。inv(として定義される^:_1)は、動詞を逆にする接続詞です。これは+/\、Jが動詞を逆にする方法を知っていればどこでも機能し、の場合、Jはその方法を知っています。


3
これは、-この関数の唯一の動詞である副詞と接続詞の力を示しています。
randomra

14

Python、61 59バイト

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

ここでは、リストの最後を除くすべてをリストの最初を除くすべてで圧縮することにより、減算を実行します。zip(L[1:],L)は、2つのリストの最小長を取得するという性質zip(L[1:],L[:-1])により、と同等zipです。

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

同じ長さの代替案(Python 2のみ):

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

残念ながら、Python 2はリストの最後を切り捨てないので、できませんmap(int.__sub__,L,L[1:])。うるさく、Pythonの3はしませんが、mapより多くのバイト(60バイト)であることまで、この両端ので、もはや戻っリスト:

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

ただし、入力が深さの後にリストf(3, 2, 5, 6, 7, 5, 10, 25)(つまり、深さ3とリスト[2, 5, 6, 7, 5, 10, 25])が続くことを許可する場合、これは56バイトになります

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

生産コードでこれを見た人を本当に困らせる別の選択肢があります(これは元のリストを破壊します):

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

最後のコードが間違っています。L[1]-L.pop(0)代わりに必要になります。
mbomb007

@ mbomb007キャッチしてくれてありがとう。それは厄介でした-私はずっと間違った方法の周りの議論をしてきました。
Sp3000

それは近かったが、他のすべての深さのようなものは記号が逆になっていた。
mbomb007

9

Mathematica 23 57 23バイト

減算のリスト可能性を利用したMartinBüttnerの提案。

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

例えば

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

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


Rest@#-Most@# 差をもたらす減算を実行します。

Nestは、指定された回数だけ上記の操作を実行し、常に最新のリストで操作します。


7

Haskell、40 34バイト

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

使用例:4 # [10,18,-12,4,8,-3,-5,67,9,14]whichはを出力します[-142,55,27,41,-269,397]

仕組み:隣接する要素間の差を繰り返し計算し、中間結果をリストに保存します。テイクnリストから番目の要素を。

編集:@Zgarbは保存する6バイトを見つけました。驚くばかり!


関数モナドを使用して、ラムダをに短縮できます(zipWith(-)=<<tail)
ズガルブ

7

JavaScript(ES6)、52 49バイト

map配列をスキャンし、slice各再帰呼び出しで最初の要素を削除するために使用する単純な再帰関数。

3バイトの保存を編集、@ DocMaxに感謝、本当に賢い提案

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

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
マップの前にスライスしてp、3文字の必要性を効率的に回避して保存しますH=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l
DocMax

6

CJam、15バイト

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

入力をCJamスタイルの配列として受け取り、次に深さを取得します。

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

結果をCJamスタイルの配列として出力します。

ここでテストしてください。

説明

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バイト

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

使用例:http : //ideone.com/ALgYez

Geobitsのおかげで3バイト:v)>


2番目int を削除i=eし、他のユーザーに割り当てる必要があります。
ジオビット

5

> <> 53 50バイト

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

使用法:まずスタック(Pythonインタープリターの-v)に深さを事前に設定し、次に整数を入力します。

例えば:

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

返品

2 -3 10 3

助けてくれたSp3000に感謝します。


1
?!ではなく、いくつかのコンポーネントを使用して移動することは可能0=?ですか?
Sp3000

ナイスキャッチ!それは束に役立ちます
-cirpis

5

プレリュード95 92 79 78バイト

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

入力形式は

N
M
n_1
n_2
...
n_M

ここNで、差の深さはM入力の整数の数です。MPreludeがa 0を入力の終わりと区別する方法がないため、追加が必要でした。出力は、改行で区切られた整数リストでもあります。標準のPreludeは整数をバイト値として読み取るため、負の数を入力することができないため、この課題のために考案たわずかに調整されたPrelude仕様を想定する必要がありました。基本的に、これは追加のフラグを持つPythonインタープリターNUMERIC_INPUTです。

参考のために、スペース以外の文字は48 38 37 のみです。残りは、コードを正しく配置するためにのみ必要でした。

説明

Preludeでは、各行は独自のスタックで動作する個別の「音声」です。プログラムは列ごとに実行されます。そこでは、別々の音声が「並行して」動作するように取得されます。すべてのコマンドは単一の文字であり、括弧はBrainfuckのようなループです(スタックの最上部がゼロ以外の場合はいつでも入力および繰り返されます)。閉じ括弧の垂直位置は無関係であることに注意してください-別の音声に入れても、最新の開き括弧と一致するものとしてカウントされ、ループ状態がチェックされるスタックは常に(出現した音声です。さあ、このプログラムに...

プログラムは基本的に2つの部分に分けることができます。下の2行は、プログラム内のほとんどのループ(メインループオーバーを除くN)でのみ使用され、1sを前後に渡します。上の2行には、メインループと実際の差分が含まれています。次の注釈ではコードが転置されているため、個々の列に注釈を付けることができます。

? ?   # 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バイト

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

再帰する前の非ゴルフバージョン:

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バイト

再帰!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • xは、実行する反復回数でありy、整数のベクトルです。
  • if(x)限り限りtrue x>0です。
  • Recall 現在の関数を呼び出しますが、新しい引数を使用します。
  • Diff 連続するリスト/ベクトル要素間の差を出力します。

以前のバージョン:

#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

diff関数をx回繰り返すより良い方法はありますか?forループの使用は過度に感じます。
freekvd

リデュースがありますが、より多くのキャラクターがかかると思います。
MickyT

1つの小さな問題があります。深さ0で呼び出された場合、深さ2を返します
-MickyT

別のアプローチに進み、問題は解決しましたが、7文字を追加する必要がありました。
freekvd

2
のいい使い方Recall()
アレックスA.

3

Python、92 87 86バイト

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)

これは私の最初のパイソンゴルフです。どんな提案も大歓迎です:)

Sp3000:Dのおかげで5 6バイト


リストの理解をお勧めします。
mbomb007

あなたは変えることができますappendにしますd+=f-e,。一般的に、コードゴルフL.appendでは、このために使用する必要はありません。
Sp3000

3

c、68 55バイト

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

これは、入力仕様を少し自由に取っている可能性があります。int配列は、要素0が深さで、要素1〜(n + 1)が入力リストの要素0〜nになるように構築されます。次に、要素1のアドレスが関数に渡されます。

配列はゼロで終了する必要があります。配列はその場で編集されます。

例えば:

#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


なぜあなたはスペースを残したのint *lですか?
ジョナサンフレッチ

2

Powershell 115 111バイト

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

そのように実行します:

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

出力:

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

中かっこを別の場所に移動すると、回答へのすべてのステップを表示できます。

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バイト

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

入力は深さを表す整数として期待され、その後にスペースで区切られた整数のリストが続きます。どちらも標準プロンプトを介して与えられます。出力は、改行で区切られた整数のリストです。

最初に、整数のリスト(1つの長い文字列として表示)を名前が1,2,3、...であるローカル変数のリストに変換します。次に、y番目のローカル変数の値をy + 1番目のローカル変数の値からy番目のローカル変数の値を引いた値(18-10 = 8)。使用後にのみ既存の値を上書きします。これは$ a(グローバル変数aの値)回実行します。次に、各ローカル変数の値を一度に1つずつ表示します。


説明のために+1。これは、リストを処理する非常に複雑な方法です。
ズガルブ

@ Zgarb、STATAが入力を配列/リストとして取得する方法を知りません(ファイルを経由する場合を除きます(他の入力のためここでは機能しません)。それがこのように動作しなければならない理由です。
bmarks

2

T-SQL、多すぎる:)

この問題を初めて見たとき、クエリでこれを行う方法があるかどうか疑問に思いました。ほとんどの言語ではささいなことですが、SQLクエリではそれほどではありません。

入力は、変数@(深さ)および整数リストの@Lに入ります。@Lはユーザー定義のテーブルタイプです

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

入力設定

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

コメント付きのクエリ

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

結果

-142
55
27
41
-269
397

2

Japt -h17 5バイト

@Shaggyのおかげで12バイト節約

VÆ=än

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



あるいは異なる実装ができます12バイト
シャギー

両方でを置き換えるäÏ-Xän、さらに2バイト節約できます。
シャギー

それを降りて5つのバイト
シャギー

@Shaggyは、あなたがあなたの5の答えバイト投稿する必要がありますJAPTのxDであまりにも良いですいまいましい
ルイス・フェリペ・デ・イエスムニョス

0

SmileBASIC、76バイト

最後に使用する理由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バイト

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

無名関数の単純な再帰。引数の順序が入れ替わった場合、現在%2よりも頻繁に発生するため、1バイトを節約できます%



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.