Une voie différente


23

Étant donné une liste d'entiers, produire une différence directe à un ordre / profondeur spécifié.

Pour la liste des entiers:

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

Les différences à terme aux différents ordres / profondeurs sont:

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

Donc, avec l'entrée de

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

Vous retourneriez la liste

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

Contribution

L'entrée peut être via STDIN ou les paramètres de fonction.

Un entier spécifiant la profondeur à retourner. Ce sera 0 à la longueur de la liste moins 1

Une liste d'entiers pour calculer la différence directe pour

Sortie

La sortie peut être via STDOUT ou retournée par la fonction.

Les différences directes pour la profondeur spécifiée sous forme de liste d'entiers

Règles

Les fonctions intégrées et tierces qui le font directement ne sont pas autorisées.

Des restrictions standard contre les échappatoires s'appliquent.

Victoires de code les plus courtes

Réponses:


19

J, 15 9 7 octets

Très facile. Prend la profondeur et la liste comme arguments gauche et droit.

-~/\~&2

En tant que définition explicite sans toute la supercherie adverbiale, cela se réduit à

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- La différence en avant de y.
  • x -~/\~&2 y- La x-ième différence vers l'avant de y.

Si je devais faire une définition sérieuse (c'est-à-dire sans golf) de cette fonction, je ferais probablement quelque chose comme ceci:

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

Le cas monadique calcule la différence directe tandis que le cas dyadique calcule la x-ième différence directe.

Encore plus simple, mais pas exactement égal:

+/\inv

+/\donne un vecteur des sommes des préfixes de l'argument. inv(défini comme ^:_1) est une conjonction qui inverse un verbe. Cela fonctionne partout où J sait inverser un verbe et dans le cas de +/\, J sait comment.


3
Cela montre la puissance des adverbes et des conjonctions comme -c'est le seul verbe dans cette fonction.
randomra

14

Python, 61 59 octets

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

Ici, nous effectuons la soustraction en zippant tout sauf le dernier de la liste avec tout sauf le premier de la liste. zip(L[1:],L)équivaut zip(L[1:],L[:-1]), en raison de zipla nature de la longueur minimale des deux listes:

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

Une alternative tout aussi longue (Python 2 uniquement):

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

Malheureusement, Python 2 ne coupe pas la fin de la liste, donc je ne peux pas le faire map(int.__sub__,L,L[1:]). Chose ennuyeuse, Python 3 le fait , mais mapne renvoie plus de liste, ce qui finit par être un octet de plus (60 octets):

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

Cependant, si nous permettons à l'entrée d'être la profondeur suivie de la liste comme f(3, 2, 5, 6, 7, 5, 10, 25)(c'est-à-dire la profondeur 3 et la liste [2, 5, 6, 7, 5, 10, 25]), alors cela fait 56 octets :

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

Voici une autre alternative qui dérangerait vraiment tous ceux qui ont vu cela dans le code de production (celui-ci détruit la liste d'origine):

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

Votre dernier code est incorrect. Vous auriez besoin à la L[1]-L.pop(0)place.
mbomb007

@ mbomb007 Merci pour la capture. C'était gênant - j'ai toujours eu des arguments dans le mauvais sens.
Sp3000

C'était proche, mais quelque chose comme toutes les autres profondeurs avait inversé les signes.
mbomb007

9

Mathematica 23 57 23 octets

La suggestion de Martin Büttner, exploitant la listabilité de la soustraction.

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

par exemple

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

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


Rest@#-Most@# effectue la soustraction qui donne des différences.

Nest effectue ladite opération le nombre de fois spécifié, en opérant toujours sur la liste la plus récente.


7

Haskell, 40 34 octets

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

Exemple d'utilisation: 4 # [10,18,-12,4,8,-3,-5,67,9,14]quelles sorties [-142,55,27,41,-269,397].

Fonctionnement: calculez à plusieurs reprises la différence entre les éléments voisins et stockez les résultats intermédiaires dans une liste. Prenez le ne élément de cette liste.

Edit: @Zgarb a trouvé 6 octets à enregistrer. Impressionnant!


Vous pouvez utiliser la fonction monad et raccourcir le lambda à (zipWith(-)=<<tail).
Zgarb

7

JavaScript (ES6), 52 49 octets

Fonction récursive simple, mappermettant de scanner le tableau et slicede supprimer le premier élément à chaque appel récursif.

Modifier 3 octets enregistrés, merci @DocMax, suggestion vraiment intelligente

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

Tester dans la console 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
Tranche avant carte pour éviter efficacement la nécessité pet enregistrer 3 caractères: H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax

6

CJam, 15 octets

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

Prend l'entrée comme un tableau de style CJam, puis la profondeur:

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

et imprime le résultat sous forme de tableau de style CJam.

Testez-le ici.

Explication

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 octets

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

Exemple d'utilisation: http://ideone.com/ALgYez

3 octets grâce à Geobits: v)>


Vous devez vous débarrasser de la seconde int et vous contenter d'assigner i=eavec les autres.
Geobits

5

> <> 53 50 octets

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

Utilisation: pré-remplir la pile (-v dans l'interpréteur python) avec la profondeur en premier, suivie des entiers.

Par exemple:

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

Résultats

2 -3 10 3

Merci à Sp3000 pour l'aide.


1
Est-il possible d'utiliser ?!et de déplacer certains composants plutôt que 0=??
Sp3000

Belle prise! Cela aide un tas
cirpis

5

Prélude , 95 92 79 78 octets

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

Le format d'entrée est

N
M
n_1
n_2
...
n_M

Nest la profondeur des différences et Mle nombre d'entiers dans l'entrée. L'ajout Métait nécessaire, car Prelude n'a aucun moyen de distinguer un 0de la fin de l'entrée. La sortie est également une liste d'entiers séparés par des sauts de ligne. J'ai dû supposer la spécification Prelude légèrement ajustée que nous avons conçue pour ce défi , car le Prelude standard lit les entiers comme des valeurs d'octets, ce qui rend impossible la saisie de nombres négatifs. Il s'agit essentiellement de l' interpréteur Python avec un NUMERIC_INPUTindicateur supplémentaire .

Pour référence il n'y a que 48 38 37 caractères non-espace - le reste était simplement nécessaire pour aligner correctement le code.

Explication

Dans Prelude, chaque ligne est une "voix" distincte qui fonctionne sur sa propre pile. Le programme est exécuté colonne par colonne, où les voix séparées sont prises pour fonctionner "en parallèle". Toutes les commandes sont des caractères uniques et les parenthèses sont des boucles de type Brainfuck (qui sont entrées et répétées chaque fois que le haut de la pile n'est pas nul). Notez que la position verticale de la parenthèse fermante n'est pas pertinente - la mettre dans une voix différente compte toujours comme correspondant à la parenthèse ouvrante la plus récente, et la pile dont la condition de boucle est vérifiée est toujours la voix où la( apparaît. Passons maintenant à ce programme ...

Le programme peut être divisé en deux parties. Les deux lignes du bas ne sont utilisées que pour la plupart des boucles du programme (à l'exception de la boucle principale N), en passant 1s d'avant en arrière. Les deux premières lignes contiennent la boucle principale et la différenciation réelle. L'annotation suivante a le code transposé, donc je peux annoter les colonnes individuelles:

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

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

Version non-golfée avant de devenir récursive:

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 octets

Récursivité!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • xest le nombre d'itérations à effectuer et yest un vecteur d'entiers.
  • if(x)est vrai aussi longtemps que x>0.
  • Recall appelle la fonction actuelle mais avec de nouveaux arguments.
  • Diff renvoie les différences entre des éléments de liste / vecteur consécutifs.

Versions précédentes:

#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

Existe-t-il une meilleure façon de répéter la fonction diff x fois? L'utilisation d'une boucle for semble excessive.
freekvd

Il y a Réduire, mais ça coûterait plus de personnages je pense.
MickyT

Il y a un petit problème. Lorsqu'il est appelé avec 0 profondeur, il renvoie la profondeur 2
MickyT

Je suis allé pour une approche différente, le problème a été résolu mais a dû ajouter 7 caractères.
freekvd

2
Belle utilisation de Recall().
Alex A.

3

Python, 92 87 86 octets

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)

Ceci est mon premier golf Python. Toute suggestion sera appréciée :)

5 6 octets grâce à Sp3000: D


Je recommanderais une compréhension de la liste.
mbomb007

Vous pouvez transformer le appenden d+=f-e,. En général, pour le golf de code, vous n'aurez jamais besoin de l'utiliser à L.appendcause de cela.
Sp3000

3

c, 68 55 octets

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

Cela pourrait prendre un peu de liberté avec la spécification d'entrée. Un tableau int est construit de telle sorte que l'élément 0 est la profondeur et les éléments 1 à (n + 1) sont les éléments de la liste d'entrée 0 à n. L'adresse de l'élément 1 est ensuite transmise à la fonction.

Le tableau doit se terminer par zéro. Le tableau est édité sur place.

Par exemple:

#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


Pourquoi as-tu laissé un espace 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','}

Exécuter en tant que tel:

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

Sortie:

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

Déplacer une accolade à un endroit différent permet d'afficher chaque étape de la réponse.

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 octets

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

Attend une entrée sous la forme d'un entier représentant la profondeur, suivi d'une liste d'entiers séparés par des espaces, tous deux fournis via l'invite standard. La sortie est une liste d'entiers séparés par des sauts de ligne.

D'abord, il convertit la liste des entiers (qu'il considère comme 1 longue chaîne) en une liste de variables locales dont les noms sont 1,2,3, ... Ensuite, il calcule les différences directes en définissant la valeur de la yième variable locale comme étant la valeur de la y + 1e variable locale moins la valeur de la yième variable locale (c'est-à-dire 18-10 = 8), qui écrase les valeurs existantes uniquement après utilisation. Il fait cela $ a (valeur de la variable globale a) fois. Il affiche ensuite la valeur de chaque variable locale, 1 à la fois.


+1 pour explication. Il s'agit d'une façon très compliquée de traiter les listes.
Zgarb

@Zgarb, je ne connais pas de moyen pour STATA de prendre les entrées en tant que tableau / liste, sauf via un fichier (qui ne fonctionnerait pas ici à cause de l'autre entrée). C'est pourquoi cela doit fonctionner comme ça.
bmarks

2

T-SQL, trop nombreux :)

Lorsque j'ai vu ce problème pour la première fois, je me suis demandé s'il existait un moyen de le faire dans une requête. Bien que trivial pour la plupart des langues, ce n'est pas tellement le cas pour les requêtes SQL.

L'entrée va dans les variables @ (pour la profondeur) et @L pour la liste entière. @L est un type de table défini par l'utilisateur

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

Configuration d'entrée

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

La requête avec quelques commentaires

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

Résultat

-142
55
27
41
-269
397


0

SmileBASIC, 76 octets

Enfin une raison d'utiliser 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 octets

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

Une récursivité simple sur la fonction anonyme. Vous économisez 1 octet si l'ordre des arguments est inversé, comme cela se %2produit maintenant plus fréquemment que %.



En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.