Diverso modo di procedere


23

Dato un elenco di numeri interi produce una Differenza diretta a un ordine / profondità specificati.

Per l'elenco di numeri interi:

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

Le differenze forward nei vari ordini / profondità sono:

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

Quindi con l'ingresso di

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

Restituiresti l'elenco

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

Ingresso

L'ingresso può essere tramite STDIN o parametri di funzione.

Un numero intero che specifica la profondità da restituire. Questo sarà 0 per la lunghezza della lista meno 1

Un elenco di numeri interi per cui calcolare la differenza diretta

Produzione

L'uscita può essere via STDOUT o restituita dalla funzione.

Le differenze in avanti per la profondità specificata come un elenco di numeri interi

Regole

Le funzioni integrate e di terze parti che lo fanno direttamente non sono consentite.

Si applicano le restrizioni standard sulle scappatoie .

Il codice più corto vince

Risposte:


19

J, 15 9 7 byte

Molto facile. Prende profondità ed elenco come argomenti sinistro e destro.

-~/\~&2

Come definizione esplicita senza tutti i trucchi avverbiali, questo si riduce a

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- La differenza in avanti di y.
  • x -~/\~&2 y- L' xennesima differenza in avanti di y.

Se dovessi fare una definizione seria (es. Non golfizzata) di questa funzione, probabilmente farei qualcosa del genere:

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

Il caso monadico calcola la differenza in avanti mentre il caso diadico calcola la xdifferenza in avanti.

Ancora più semplice, ma non esattamente uguale:

+/\inv

+/\produce un vettore delle somme dei prefissi dell'argomento. inv(definito come ^:_1) è una congiunzione che inverte un verbo. Funziona ovunque J sappia come invertire un verbo e, nel caso di +/\, J sappia come farlo.


3
Ciò mostra il potere di avverbi e congiunzioni come -è l'unico verbo in questa funzione.
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

Qui eseguiamo la sottrazione comprimendo tutto tranne l'ultimo dell'elenco con tutti tranne il primo dell'elenco. zip(L[1:],L)è equivalente a zip(L[1:],L[:-1])causa della zipnatura di prendere la lunghezza minima dei due elenchi:

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

Un'alternativa altrettanto lunga (solo Python 2):

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

Sfortunatamente Python 2 non ha tagliato la fine della lista, quindi non posso farlo map(int.__sub__,L,L[1:]). Python 3 fa seccamente , ma mapnon restituisce più un elenco, quindi finisce per essere un byte in più (60 byte):

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

Tuttavia, se permettiamo che l'ingresso sia la profondità seguita dalla lista come f(3, 2, 5, 6, 7, 5, 10, 25)(cioè profondità 3 e lista [2, 5, 6, 7, 5, 10, 25]), allora questo è 56 byte :

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

Ecco un'altra alternativa che potrebbe davvero infastidire chiunque abbia visto questo nel codice di produzione (questo distrugge l'elenco originale):

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

Il tuo ultimo codice non è corretto. Avresti bisogno L[1]-L.pop(0)invece.
mbomb007,

@ mbomb007 Grazie per la cattura. E 'stato imbarazzante - ho sempre avuto gli argomenti nel modo sbagliato.
Sp3000,

Era vicino, ma qualcosa come ogni altra profondità aveva i segni invertiti.
mbomb007,

9

Mathematica 23 57 23 byte

Il suggerimento di Martin Büttner, sfruttando la possibilità di sottrazione.

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

per esempio

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

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


Rest@#-Most@# esegue la sottrazione che produce differenze.

Nest esegue detta operazione il numero di volte specificato, operando sempre nell'elenco più recente.


7

Haskell, 40 34 byte

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

Esempio di utilizzo: 4 # [10,18,-12,4,8,-3,-5,67,9,14]quali output [-142,55,27,41,-269,397].

Come funziona: calcola ripetutamente la differenza tra elementi vicini e archivia i risultati intermedi in un elenco. Prendi l' nelemento th da questo elenco.

Modifica: @Zgarb ha trovato 6 byte da salvare. Eccezionale!


Puoi usare la funzione monade e accorciare la lambda a (zipWith(-)=<<tail).
Zgarb,

7

JavaScript (ES6), 52 49 byte

Semplice funzione ricorsiva, usando mapper scansionare l'array e slicerilasciare il primo elemento ad ogni chiamata ricorsiva.

Modifica 3 byte salvati, grazie a @DocMax, suggerimento davvero intelligente

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

Test nella console di 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
Fetta prima mappa per evitare efficacemente la necessità di pe salvare 3 caratteri: H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax,

6

CJam, 15 byte

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

Accetta input come un array in stile CJam e quindi la profondità:

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

e stampa il risultato come un array in stile CJam.

Provalo qui.

Spiegazione

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

Esempio di utilizzo: http://ideone.com/ALgYez

3 byte grazie a Geobits: v)>


Dovresti sbarazzarti del secondo int e assegnarlo i=eagli altri.
Geobits il

5

> <> 53 50 byte

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

Uso: prepopolare lo stack (-v nell'interprete Python) prima con la profondità, seguito dagli interi.

Per esempio:

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

ritorna

2 -3 10 3

Grazie a Sp3000 per l'aiuto.


1
È possibile utilizzare ?!e spostare alcuni componenti piuttosto che 0=??
Sp3000,

Bella presa! Questo aiuta un sacco
cirpis

5

Preludio , 95 92 79 78 byte

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

Il formato di input è

N
M
n_1
n_2
...
n_M

dove Nè la profondità delle differenze ed Mè il numero di numeri interi nell'input. L'aggiunta Mera necessaria, perché Prelude non ha modo di distinguere un 0dalla fine dell'input. L'output è anche un elenco di numeri interi separati da una nuova riga. Ho dovuto assumere le specifiche Prelude leggermente modificate che abbiamo ideato per questa sfida , perché Prelude standard legge numeri interi come valori byte, il che rende impossibile inserire numeri negativi. In sostanza, questo è l' interprete Python con un NUMERIC_INPUTflag aggiuntivo .

Per riferimento ci sono solo 48 38 37 caratteri non spaziali - il resto era semplicemente necessario per allineare correttamente il codice.

Spiegazione

In Prelude, ogni riga è una "voce" separata che opera sul proprio stack. Il programma viene eseguito colonna per colonna, dove le voci separate vengono utilizzate per operare "in parallelo". Tutti i comandi sono singoli caratteri e le parentesi sono loop simili a Brainfuck (che vengono inseriti e ripetuti ogni volta che la parte superiore della pila è diversa da zero). Si noti che la posizione verticale della parentesi di chiusura è irrilevante: inserirla in una voce diversa conta comunque come corrispondenza con la parentesi di apertura più recente e lo stack che viene controllato per la condizione di loop è sempre la voce in cui è (apparsa. Passiamo ora a questo programma ...

Il programma può essere sostanzialmente diviso in due parti. Le due righe inferiori vengono semplicemente utilizzate per la maggior parte dei loop del programma (tranne il loop principale N), passando 1avanti e indietro. Le prime due righe contengono il ciclo principale e la differenza effettiva. La seguente annotazione ha il codice trasposto, quindi posso annotare le singole colonne:

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

Versione non golfata prima che diventassi ricorsivo:

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

Ricorsione!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • xè il numero di iterazioni da eseguire ed yè un vettore di numeri interi.
  • if(x)è vero fino a quando x>0.
  • Recall chiama la funzione corrente ma con nuovi argomenti.
  • Diff genera le differenze tra elementi consecutivi elenco / vettore.

Versione precedente:

#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'è un modo migliore per ripetere la funzione diff x volte? L'uso di un ciclo for sembra eccessivo.
freekvd,

C'è Riduzione, ma penso che costerebbe più personaggi.
MickyT

C'è un piccolo problema. Quando viene chiamato con profondità 0, restituisce profondità 2
MickyT

Sono andato per un approccio diverso, il problema è stato risolto ma ho dovuto aggiungere 7 caratteri.
freekvd,

2
Buon uso di 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)

Questo è il mio primo golf Python. Ogni suggerimento sarà apprezzato :)

5 6 byte grazie a Sp3000: D


Consiglierei una comprensione dell'elenco.
mbomb007,

Puoi trasformare il appendin d+=f-e,. In generale, per code-golf non dovrai mai usarlo L.appendper questo.
Sp3000,

3

c, 68 55 byte

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

Questo potrebbe richiedere un po 'di libertà con le specifiche di input. Un array int è costruito in modo tale che l'elemento 0 sia la profondità e gli elementi da 1 a (n + 1) siano gli elementi dell'elenco di input da 0 a n. Quindi l'indirizzo dell'elemento 1 viene passato alla funzione.

L'array deve essere terminato con zero. L'array viene modificato in posizione.

Per esempio:

#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


Perché hai lasciato uno spazio dentro 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','}

Eseguire come tale:

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

Produzione:

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

Spostare una parentesi graffa in un punto diverso consente di visualizzare ogni passaggio della risposta.

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

Prevede l'input come numero intero che rappresenta la profondità, seguito da un elenco di numeri interi separati da spazio, entrambi forniti tramite il prompt standard. L'output è un elenco separato di newline di numeri interi.

Per prima cosa converte l'elenco di numeri interi (che visualizza come 1 stringa lunga) in un elenco di variabili locali i cui nomi sono 1,2,3, ... Quindi calcola le differenze in avanti impostando il valore dell'ennesima variabile locale su il valore della variabile locale y + 1 meno il valore della variabile locale yth (ovvero 18-10 = 8), che sovrascrive i valori esistenti solo dopo l'uso. Lo fa $ a (valore della variabile globale a) volte. Quindi visualizza il valore di ogni variabile locale, 1 alla volta.


+1 per spiegazione. Questo è un modo incredibilmente contorto di elaborare elenchi.
Zgarb,

@Zgarb, non conosco un modo per STATA di accettare l'input come array / elenco se non tramite file (che non funzionerebbe qui a causa dell'altro input). Ecco perché deve funzionare in questo modo.
segna il

2

T-SQL, Troppi :)

Quando ho visto questo problema per la prima volta, mi chiedevo se ci fosse un modo per farlo in una query. Sebbene banale per la maggior parte delle lingue, non è così tanto per la query SQL.

L'input va nelle variabili @ (per la profondità) e @L per l'elenco di numeri interi. @L è un tipo di tabella definito dall'utente

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

Impostazione dell'ingresso

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

La query con alcuni commenti

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

Risultato

-142
55
27
41
-269
397


0

SmileBASIC, 76 byte

Finalmente un motivo per usare 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))))

Una semplice ricorsione su funzione anonima. Si salva 1 byte se l'ordine degli argomenti viene scambiato come ora si %2verifica più frequentemente di %.


0

Gelatina , 2 byte

Provalo online!

Spiegazione

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

Risposta molto semplice: P


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.