Anderer Weg nach vorne


23

Bei einer gegebenen Liste von ganzen Zahlen wird ein Vorwärtsunterschied in einer bestimmten Reihenfolge / Tiefe erzeugt.

Für die Liste der ganzen Zahlen:

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

Die Vorwärtsdifferenzen bei den verschiedenen Aufträgen / Tiefen sind:

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

Also mit der Eingabe von

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

Sie würden die Liste zurückgeben

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

Eingang

Die Eingabe kann über STDIN oder Funktionsparameter erfolgen.

Eine Ganzzahl, die die zurückzugebende Tiefe angibt. Dies ist 0 bis zur Länge der Liste minus 1

Eine Liste von Ganzzahlen, für die die Vorwärtsdifferenz berechnet werden soll

Ausgabe

Die Ausgabe kann über STDOUT erfolgen oder von der Funktion zurückgegeben werden.

Die Vorwärtsdifferenzen für die angegebene Tiefe als Liste von Ganzzahlen

Regeln

Eingebaute Funktionen und Funktionen von Drittanbietern, die dies direkt ausführen, sind nicht zulässig.

Es gelten die üblichen Lückenbeschränkungen.

Kürzester Code gewinnt

Antworten:


19

J, 15 9 7 Bytes

Sehr leicht. Nimmt Tiefe und Liste als linkes und rechtes Argument.

-~/\~&2

Als explizite Definition ohne alle adverbialen Tricks reduziert sich dies auf

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- Der Vorwärtsunterschied von y.
  • x -~/\~&2 y- Die x-te Vorwärtsdifferenz von y.

Wenn ich diese Funktion ernsthaft (d. H. Ohne Golf) definieren würde, würde ich wahrscheinlich so etwas tun:

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

Der monadische Fall berechnet die Vorwärtsdifferenz, während der dyadische Fall die x-te Vorwärtsdifferenz berechnet .

Noch einfacher, aber nicht genau gleich:

+/\inv

+/\liefert einen Vektor der Summen der Präfixe des Arguments. inv(definiert als ^:_1) ist eine Konjunktion, die ein Verb umkehrt. Dies funktioniert überall dort, wo J weiß, wie man ein Verb umkehrt, und für den Fall +/\, dass J weiß, wie man es tut.


3
Dies zeigt die Potenz von Adverbien und Konjunktionen, da dies -das einzige Verb in dieser Funktion ist.
Randomra

14

Python, 61 59 Bytes

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

Hier führen wir die Subtraktion durch, indem wir alle bis auf den letzten Teil der Liste mit allen bis auf den ersten Teil der Liste komprimieren. zip(L[1:],L)entspricht zip(L[1:],L[:-1])aufgrund der zipArt der Aufnahme der Mindestlänge der beiden Listen:

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

Eine ebenso lange Alternative (nur Python 2):

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

Leider schneidet Python 2 das Ende der Liste nicht ab, daher kann ich das nicht tun map(int.__sub__,L,L[1:]). Es ist ärgerlich, dass Python 3 dies tut , aber mapkeine Liste mehr zurückgibt, sodass dies ein Byte mehr ist (60 Byte):

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

Wenn wir jedoch zulassen, dass die Eingabe die Tiefe ist, auf die die Liste folgt f(3, 2, 5, 6, 7, 5, 10, 25)(dh Tiefe 3 und Liste [2, 5, 6, 7, 5, 10, 25]), dann sind dies 56 Bytes :

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

Hier ist eine weitere Alternative, die wirklich jeden nerven würde, der dies im Produktionscode gesehen hat (diese zerstört die ursprüngliche Liste):

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

Ihr letzter Code ist falsch. Du würdest L[1]-L.pop(0)stattdessen brauchen .
mbomb007

@ mbomb007 Danke für den Fang. Das war umständlich - ich habe die ganze Zeit über falsch argumentiert.
Sp3000

Es war nah dran, aber in so etwas wie jeder anderen Tiefe kehrten sich die Vorzeichen um.
mbomb007

9

Mathematica 23 57 23 Bytes

Martin Büttners Vorschlag, der die Listbarkeit der Subtraktion ausnutzt.

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

z.B

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

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


Rest@#-Most@# führt die Subtraktion durch, die Differenzen ergibt.

Nest führt diese Operation so oft aus, wie angegeben, wobei immer die aktuellste Liste bearbeitet wird.


7

Haskell, 40 34 Bytes

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

Anwendungsbeispiel: 4 # [10,18,-12,4,8,-3,-5,67,9,14] Welche Ausgänge [-142,55,27,41,-269,397].

So funktioniert es: Berechnen Sie wiederholt die Differenz zwischen Nachbarelementen und speichern Sie die Zwischenergebnisse in einer Liste. Nehmen Sie das nth-Element aus dieser Liste.

Edit: @Zgarb hat 6 Bytes zum Speichern gefunden. Genial!


Sie können die Funktion Monade verwenden und das Lambda auf kürzen (zipWith(-)=<<tail).
Zgarb

7

JavaScript (ES6), 52 49 Bytes

Einfache rekursive Funktion mit map der das Array durchsucht und slicedas erste Element bei jedem rekursiven Aufruf abgelegt wird.

3 Bytes gespeichert bearbeiten , danke @DocMax, wirklich kluger Vorschlag

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

Test In der Firefox / FireBug-Konsole

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
Scheibe vor Karte , um effizient die Notwendigkeit zu vermeiden pund speichern 3 Zeichen: H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax

6

CJam, 15 Bytes

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

Übernimmt die Eingabe als Array im CJam-Stil und anschließend die Tiefe:

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

und druckt das Ergebnis als Array im CJam-Stil.

Teste es hier.

Erläuterung

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 Bytes

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

Beispielnutzung: http://ideone.com/ALgYez

3 Bytes dank Geobits: v)>


Sie sollten die Sekunde loswerden int und nur i=emit den anderen beauftragen.
Geobits

5

> <> 53 50 Bytes

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

Verwendung: Füllen Sie zuerst den Stapel (-v im Python-Interpreter) mit der Tiefe vor, gefolgt von den ganzen Zahlen.

Beispielsweise:

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

Kehrt zurück

2 -3 10 3

Danke an Sp3000 für die Hilfe.


1
Ist es möglich, ?!einige Komponenten zu verwenden und zu bewegen, anstatt 0=??
Sp3000,

Schöner Fang! Das hilft einem Haufen
Cirpis

5

Präludium , 95 92 79 78 Bytes

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

Eingabeformat ist

N
M
n_1
n_2
...
n_M

wo Nist die Tiefe der Unterschiede undM ist die Anzahl der ganzen Zahlen in der Eingabe. Das Hinzufügen Mwar notwendig, da es für Prelude keine Möglichkeit gibt, a 0vom Ende der Eingabe zu unterscheiden. Die Ausgabe erfolgt auch als durch Zeilenumbrüche getrennte Liste von Ganzzahlen. Ich musste die leicht angepasste Prelude-Spezifikation annehmen, die wir für diese Herausforderung entwickelt haben , da Standard-Prelude Ganzzahlen als Byte-Werte liest, was die Eingabe negativer Zahlen unmöglich macht. Dies ist im Wesentlichen der Python-Interpreter mit einem zusätzlichen NUMERIC_INPUTFlag.

Als Referenz gibt es nur 48 38 37 nicht-Leerzeichen - der Rest wurde lediglich benötigt, um den Code korrekt auszurichten.

Erläuterung

Im Prelude ist jede Zeile eine separate "Stimme", die auf einem eigenen Stapel arbeitet. Das Programm wird Spalte für Spalte ausgeführt, wobei die einzelnen Stimmen "parallel" arbeiten. Alle Befehle sind einzelne Zeichen, und Klammern sind Brainfuck-ähnliche Schleifen (die eingegeben und wiederholt werden, wenn der Anfang des Stapels nicht Null ist). Beachten Sie, dass die vertikale Position der schließenden Klammer irrelevant ist. Wenn Sie eine andere Stimme verwenden, wird dies weiterhin als Übereinstimmung mit der letzten öffnenden Klammer gewertet, und der Stapel, der auf die Loop-Bedingung überprüft wird, ist immer die Stimme, bei der die (aufgetreten ist. Nun zu diesem Programm ...

Das Programm kann grundsätzlich in zwei Teile unterteilt werden. Die unteren beiden Zeilen werden lediglich für die meisten Schleifen im Programm verwendet (mit Ausnahme der Hauptschleife N) und 1s werden vor und zurück durchlaufen . Die beiden oberen Zeilen enthalten die Hauptschleife und die tatsächliche Differenzierung. Die folgende Anmerkung hat den Code transponiert, so dass ich die einzelnen Spalten mit Anmerkungen versehen kann:

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

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

Nicht-Golf-Version, bevor ich rekursiv wurde:

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 Bytes

Rekursion!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • x ist die Anzahl der durchzuführenden Iterationen und y ist ein Vektor von ganzen Zahlen.
  • if(x) ist wahr, solange x>0 .
  • Recall ruft die aktuelle Funktion mit neuen Argumenten auf.
  • Diff gibt die Unterschiede zwischen aufeinanderfolgenden Listen- / Vektorelementen aus.

Vorherige Versionen:

#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

Gibt es eine bessere Möglichkeit, die Diff-Funktion x-mal zu wiederholen? Die Verwendung einer for-Schleife fühlt sich übermäßig an.
Freekvd

Es gibt Reduzieren, aber es würde mehr Zeichen kosten, denke ich.
MickyT

Es gibt ein kleines Problem. Bei einem Aufruf mit 0 depth wird depth 2 zurückgegeben
MickyT

Ging für einen anderen Ansatz, Problem gelöst, musste aber 7 Zeichen hinzufügen.
Freekvd

2
Gute Verwendung von Recall().
Alex A.

3

Python, 92 87 86 Bytes

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)

Dies ist mein erster Python Golf. Anregungen werden geschätzt :)

5 6 Bytes dank Sp3000: D


Ich würde ein Listenverständnis empfehlen.
mbomb007

Sie können das appendin machen d+=f-e,. Im Allgemeinen müssen Sie Code-Golf deshalb nie verwenden L.append.
Sp3000,

3

c, 68 Bytes

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

Dies kann zu geringfügigen Einschränkungen der Eingabespezifikation führen. Ein int-Array ist so aufgebaut, dass Element 0 die Tiefe und Elemente 1 bis (n + 1) die Eingabelistenelemente 0 bis n sind. Dann wird die Adresse von Element 1 an die Funktion übergeben.

Das Array muss mit Null abgeschlossen sein. Das Array wird an Ort und Stelle bearbeitet.

Z.B:

#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


Warum hast du ein Leerzeichen hinterlassen int *l?
Jonathan Frech

2

Powershell 115 111 Bytes

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

Als solches ausführen:

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

Ausgabe:

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

Wenn Sie eine geschweifte Klammer an eine andere Stelle verschieben, wird jeder Schritt der Antwort angezeigt.

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 Bytes

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

Erwartet die Eingabe als Ganzzahl, die die Tiefe darstellt, gefolgt von einer durch Leerzeichen getrennten Liste von Ganzzahlen, die beide über die Standardeingabeaufforderung angegeben werden. Die Ausgabe ist eine durch Zeilenumbrüche getrennte Liste von ganzen Zahlen.

Zuerst konvertiert es die Liste der Ganzzahlen (die es als 1 langen String ansieht) in eine Liste der lokalen Variablen, deren Namen 1,2,3 sind Der Wert der y + 1-ten lokalen Variablen minus dem Wert der y-ten lokalen Variablen (dh 18-10 = 8), die vorhandene Werte erst nach der Verwendung überschreibt. Es macht dies $ a (Wert der globalen Variablen a) mal. Anschließend wird der Wert jeder lokalen Variablen angezeigt (jeweils 1).


+1 zur Erklärung. Dies ist eine äußerst komplizierte Art, Listen zu verarbeiten.
Zgarb,

@Zgarb, ich kenne keine Möglichkeit für STATA, Eingaben als Array / Liste zu übernehmen, außer über eine Datei (was hier aufgrund der anderen Eingaben nicht funktioniert). Deshalb muss es so funktionieren.
bmarks

2

T-SQL, zu viele :)

Als ich dieses Problem zum ersten Mal sah, fragte ich mich, ob es eine Möglichkeit gab, dies in einer Abfrage zu tun. Während es für die meisten Sprachen trivial ist, ist es nicht so sehr für SQL-Abfragen.

Die Eingabe erfolgt in die Variablen @ (für die Tiefe) und @L für die Ganzzahlliste. @L ist ein benutzerdefinierter Tabellentyp

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

Eingangs-Setup

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

Die Abfrage mit einigen Kommentaren

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

Ergebnis

-142
55
27
41
-269
397


0

SmileBASIC, 76 Bytes

Endlich ein Grund zu nutzen 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 Bytes

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

Eine einfache Rekursion auf anonyme Funktion. Sie sparen 1 Byte, wenn die Reihenfolge der Argumente vertauscht wird, da sie jetzt %2häufiger auftritt als %.



Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.