Trier une liste de différences

22

La liste des différences d'une liste d'entiers est la liste des différences des membres consécutifs.

Par exemple, la liste des différences de

1, 3, 2 ,4

est

2, -1, 2

Votre tâche consiste à prendre en entrée une liste de différences et à afficher à quoi ressemblerait la liste de différences si la liste d'origine était triée.

Par exemple la liste des différences

2, 1, -2, -1

Pourrait représenter une liste

2 4 5 3 2

Qui, une fois trié, est

2 2 3 4 5

Qui a une liste de différences de

0 1 1 1

Il s'agit de donc les réponses seront notées en octets avec moins d'octets meilleurs.

Assistant de blé
la source
Les solutions sont-elles garanties d'être uniques?
H.PWiz
@ H.PWiz Oui, ils le sont.
Wheat Wizard
En relation.
2017 totalement humain
1
@ H.PWiz Preuve rapide: une liste est parfaitement reconstructible à partir d'une liste de différences (DL) combinée avec une première valeur d'élément, il y a donc une conversion un à un de L en (FV, DL). Augmenter le FV d'un montant équivaut à ajouter ce montant à chaque élément du L et, par conséquent, il ne peut pas modifier le tri du L si cette comparaison est convenablement monotone. (En d'autres termes, cela n'affecte pas le tri, sauf si le nombre que vous ajoutez provoque un débordement d'entier).
CR Drost
1
Pourriez-vous ajouter quelques cas de test supplémentaires? Je remarque par exemple certaines solutions donnant des sorties différentes [-2, 100, -2, -1].
Shaggy

Réponses:

16

05AB1E , 4 octets

.¥{¥

Essayez-le en ligne!

Explication

.¥{¥
.¥   # Undelta the input list
  {  # Sort it
   ¥ # And get the deltas
Datboi
la source
Undelta05AB1E possède le plus de niches intégrées. o0
totallyhuman
2
Ahh merde, bat-moi dessus. J'ai toujours voulu utiliser undelta.
Urne de poulpe magique
16
Undeltaಠ ___ ಠ
Business Cat
1
"Undelta" est simplement une somme cumulative, non?
Zgarb
2
@Zgarb Undelta ajoute un 0 comme premier élément de la liste, puis exactement comme vous l'avez dit, somme cumulée ou delta inverse.
Urne de poulpe magique
9

Python 3 avec Numpy , 56 54 53 octets

2 octets de moins grâce à @Artyer (Numpy au sortlieu du standard sorted). 1 octet off grâce à @notjagan (déplacement 0en cumsum)

lambda x:diff(sort(cumsum([0]+x)))
from numpy import*

Le code définit une fonction anonyme qui entre une liste ou un tableau Numpy et sort un tableau Numpy.

Essayez-le en ligne!

Luis Mendo
la source
1
Woah, tu m'as appris quelque chose de nouveau aujourd'hui. Mon approche avec numpyétait beaucoup plus longue. Je reviendrai demain pour voter, parce que je vous vois déjà plafonné. Très agréable!
M. Xcoder
@ Mr.Xcoder Merci! Je ne suis pas un expert en Numpy, je viens de suivre ce que j'aurais fait en Matlab: diff(sort([0 cumsum(x)]))(en Matlab, [ ]c'est la concaténation)
Luis Mendo
Obligation remplie!
M. Xcoder
-1 octet en déplaçant le 0dans le cumsum.
notjagan
5

Mathematica, 40 octets

Differences@Sort@Accumulate@Join[{1},#]&
J42161217
la source
Differences@Sort@FoldList[+##&,1,#]&
alephalpha
4

Husk , 4 octets

Ẋ-O∫

Essayez-le en ligne!

Explication

      -- implicit input, e.g                               [2,1,-2,-1]
   ∫  -- cumulative sum                                    [0,2,3,1,0]
  O   -- sort                                              [0,0,1,2,3]
Ẋ     -- apply function to all adjacent pairs in the list  [(0,0),(0,1),(1,2),(2,3)]
 -    --   subtract                                        [0,1,1,1]
H.PWiz
la source
Une autre langue qui a undelta? Ou quelque encastré plus sophistiqué?
M. Xcoder
@M. Xcoder Il arrive que cumsum soit le même que undelta
H.PWiz
@ H.PWiz En fait, ce n'est pas ce que nous appelons cumsum ... à moins que vous ne teniez compte du préfixe vide.
Erik the Outgolfer
@EriktheOutgolfer Oui, c'est ce que fait la balle, comme c'est le cas scanl(+)0à Haskell.
H.PWiz
4

Pyth , 9 octets

-1 octet grâce à @EriktheOutgolfer .

.+S+0sM._

Suite de tests.

Pyth , 10 octets

.+S.u+YNQ0

Essayez-le en ligne! ou Essayez d'autres cas de test .

M. Xcoder
la source
Comme dans ma réponse (supprimée), vous pouvez utiliser +0sM._au lieu de .u+YNQ0pour -1.
Erik the Outgolfer
@EriktheOutgolfer Pourquoi l'avez-vous supprimé?
M. Xcoder
Je pensais que l'idée centrale était trop similaire à la vôtre.
Erik the Outgolfer
@EriktheOutgolfer Ok, merci alors
M. Xcoder
m=+Zest une variante de même longueur sM._, mais malheureusement, il ne semble pas qu'elle puisse être plus courte.
FryAmTheEggman
4

JavaScript (ES6), 57 56 octets

1 octet enregistré grâce à @ETHproductions

a=>a.map(n=>t-=n,p=t=0).sort((a,b)=>b-a).map(n=>p-(p=n))

Démo

Arnauld
la source
.sort((a,b)=>a-b)C'est comme ça qu'on obtient des deltas? En triant avec soustraction? : P
totalement humain
@totallyhuman Le premier map()donne les deltas. Ce code les trie. La 2ème carte reconstruit les nouveaux deltas. sort()Par défaut, la méthode JS utilise l'ordre lexicographique. Nous avons donc besoin de ce rappel spécialisé pour les numéros> 9 (malheureusement).
Arnauld
Cela fait -p+(p=n)
grincer des dents
que diable, je n'ai pas
appuyé
@ETHproductions Merci :-)
Arnauld
3

Java 8, 123 octets

La solution standard: somme cumulée saisie, tri, puis diff. Aucune astuce de mise en œuvre substantielle non plus.

l->{int s=l.length,d[]=new int[s+1],i=0;while(i<s)d[i+1]=d[i]+l[i++];for(java.util.Arrays.sort(d);i-->0;)l[i]=d[i+1]-d[i];}

Cast to Consumer<int[]>. La sortie est une entrée mutée.

Essayez-le en ligne

Lambda non golfé

l -> {
    int
        s = l.length,
        d[] = new int[s + 1],
        i = 0
    ;
    while (i < s)
        d[i + 1] = d[i] + l[i++];
    for (java.util.Arrays.sort(d); i-- > 0; )
        l[i] = d[i + 1] - d[i];
}

Remerciements

  • -3 octets grâce à Olivier Grégoire , maître de l'auto-incrémentation impie
  • -1 octet grâce à Nevay
Jakob
la source
1
Vous pouvez jouer au golf 3 octets en réorganisant les positions où vous effectuez vos incréments et vos calculs globaux: l->{int s=l.length,d[]=new int[s+1],i=0;for(;i<s;)d[i+1]=d[i]+l[i++];java.util.Arrays.sort(d);for(i=0;i<s;)l[i]=-d[i]+d[++i];}(méfiez-vous des caractères invisibles de SE lors du copier / coller)
Olivier Grégoire
1
Merci pour mon nouveau titre;) Voici plus de décrément impie à célébrer for(;i>0;)l[i-1]=d[i]-d[--i];(dernière boucle)
Olivier Grégoire
Je venais de retravailler cette boucle moi-même, en arrivant à for(;i-->0;)l[i]=d[i+1]-d[i];la même longueur. Mise à jour à venir.
Jakob
2
Vous pouvez enregistrer 1 octet en utilisant l->{int s=l.length,d[]=new int[s+1],i=0;while(i<s)d[i+1]=d[i]+l[i++];for(java.util.Arrays.sort(d);i-->0;l[i]=d[i+1]-d[i]);}.
Nevay
Ah oui, bien sûr. Merci!
Jakob
2

R , 31 32 octets

-4 octets grâce à @ user2390246 pour diffinv

+5 octets de Jarko pour cat

cat(diff(sort(diffinv(scan()))))

Lit depuis stdin, écrit vers stdout. diffinvest l'inverse de diffpour une valeur de départ donnée (0 par défaut). Puisqu'il est à diffnouveau édité, peu importe quelle est cette valeur.

Comme l'a souligné Jarko Dubbeldam, j'avais besoin de produire correctement le résultat, au prix de cinq octets. Hélas.

Essayez-le en ligne!

Giuseppe
la source
C'est ce que j'avais également en tête. Doit cependant gérer l'impression, car en exécutant cela en tant que programme complet (via source), cela ne produit rien.
JAD
1
Si vous utilisez diffinvplutôt que cumsumvous n'avez pas besoin d'ajouter le zéro.
user2390246
@ user2390246 wow, très sympa! TIL sur diffinv.
Giuseppe
Moi aussi! J'étais juste en train de faire une recherche rapide pour voir s'il y avait des réponses précédentes auxquelles j'aurais pu l'appliquer.
user2390246
1

Python 2 , 83 octets

l,r=input(),[1]
for i in l:r+=[r[-1]+i]
r.sort()
print[b-a for a,b in zip(r,r[1:])]

Essayez-le en ligne!

Solution horrible .

totalement humain
la source
Ce n'est pas si terrible, en fait
M. Xcoder
L' +=opérateur de Python sur les listes fonctionne avec n'importe quel itérable, vous pouvez donc utiliser à la r+=r[-1]+i,place r+=[r[-1]+i]et enregistrer un octet.
Jonathan Frech
1

Perl 6 , 46 octets

{[\+](0,|@_).sort.rotor(2=>-1).flat.map(*R-*)}

Essayez-le

Étendu:

{  # bare block lambda with implicit signature :(*@_)

  [\+](         # triangle reduce using &infix:«+»
    0,          # start with 0
    |@_         # Slip in the arguments from the outer block
  )             #                  (0, 2, 3, 1, 0)

  .sort         # sort the results (0,0,1,2,3)
  .rotor(2=>-1) # group in twos    ((0,0),(0,1),(1,2),(2,3))
  .flat         # flatten          (0,0,0,1,1,2,2,3)
  .map(*R-*)    # grab 2 values at a time, and subtract first from second
                # (0, 1, 1, 1)
}
Brad Gilbert b2gills
la source
1

Haskell , 74 octets

import Data.List
g=sort.scanl(+)0
h l|k<-g l=map(\(x,y)->x-y)$zip(tail$k)k

Essayez-le en ligne!

Simple.

jferard
la source
3
=<<de la fonction monade est très pratique: (zipWith(-)=<<tail).sort.scanl(+)0
nimi
@nimi Très sympa. Je ne suis pas expert en monades, mais j'aurais dû y penser zipWith.
jferard
1

TI-Basic (TI-84 Plus CE), 23 octets

Prompt X
augment({0},cumSum(LX→X
SortA(LX
ΔList(LX

Invite l'utilisateur à entrer. La liste doit être entrée avec un début {, avec des nombres séparés par ,et avec une fin facultative }.

TI-Basic est un langage à jetons ; ΔList(et cumSum(sont des jetons de deux octets, tous les autres jetons utilisés sont d'un octet chacun.

Exemple d'exécution (avec NAMEcomme nom de programme et {4,-2,7,-4,0}comme entrée):

prgmNAME
X=?{4,-2,7,-4,0}
               {2 2 1 0 4}

Explication:

Prompt X                  # 3 bytes, get list input, store in LX
augment({0},cumSum(LX→X   # 12 bytes, 
          # store the list ({0} prepended to the cumulative sum of LX) to LX
SortA(LX                  # 4 bytes, sort LX ascending
ΔList(LX                  # 4 bytes, implicitly print the difference list of LX
pizzapants184
la source
Avez-vous besoin du L?
Zacharý
@ Zacharý vous pouvez les omettre lors du stockage d'une liste, mais les omettre lors du référencement ferait référence à la variable numérique X au lieu de la liste
pizzapants184
1

C ++ (gcc) , 136 octets

En tant que lambda générique sans nom, en supposant que l'entrée est similaire std::listet en retournant via le paramètre de référence.

[](auto&L){auto r=L.begin(),l=L.insert(r,0);while(r!=L.end())*r+++=*l++;for(L.sort(),l=r=--L.end();--l!=L.begin();*r---=*l);L.erase(l);}

Essayez-le en ligne!

Non golfé:

[](auto&L){
 auto r=L.begin(),
      l=L.insert(r,0); //adds a zero right in front
 while(r!=L.end())
   *r++ += *l++;       //sum left to right
 for(
  L.sort(),            //sorting invalidates the iterators
  l=r=--L.end();       //so, reinit
  --l!=L.begin();      //decrement l beforehand 
  *r-- -= *l           //diff right to left
 );
 L.erase(l);           //l==L.begin(), so this removes the temporary 0
}
Karl Napf
la source
1

Pyth, 8 octets

.+S+M.uP

Manifestation

.+S+M.uP
.+S+M.uPNQ    Implicit variables
     .u  Q    Apply the following function to the input repeatedly until it
              stops changing, then output the list of values, including the
              starting value.
       PN     Remove the last element. No-op if the list is empty.
   +M         Sum each list. This gives the cumulative sums in reverse order,
              including a 0 at the end for the empty list.
  S           Sort
.+            Deltas
isaacg
la source
+1 Il s'agit d'une solution de contournement soignée avec un point fixe cumulatif. Personnellement, je n'y ai même pas pensé.
M. Xcoder du
1

TI-Basic, 20 octets

cumSum(augment({0},Ans->L1
SortA(L1
ΔList(L1
Timtech
la source
1

Perl 5 , 87 + 1 (-a) = 88 octets

$a[0]=1;push@a,$a[-1]+$_ for@F;@a=sort{$a<=>$b}@a;print$a[0]-$_,$"while($_=shift@a)&&@a

Essayez-le en ligne!

Xcali
la source
1

VB.NET (.NET 4.5), 109 octets

Sub A(n)
Dim c=n.count-1
For i=1To c
n(i)+=n(i-1)
Next
n.Sort()
For i=c To 1 Step-1
n(i)-=n(i-1)
Next
End Sub

Une fonction qui attend une liste en entrée et la modifie directement. Le paramètre d'origine peut ensuite être utilisé pour la sortie

  1. Recrée une liste originale en ajoutant vers l'avant à travers la liste (suppose un 0 implicite comme premier élément)
  2. Trie la liste d'origine
  3. Obtient les différences en reculant (donc je n'ai pas besoin de garder une trace d'une liste différente) (le premier élément implicite de 0 signifie que la première différence est la même que le plus petit élément)

Essayez-le en ligne!

Brian J
la source
Pourriez-vous mettre à jour le lien TIO?
Taylor Scott
@TaylorScott Update de quelle manière?
Brian J
Votre lien TIO affiche un code complètement différent de celui de votre réponse
Taylor Scott
1
@TaylorScott Ahh .... Je vois. J'ai dû faire quelques ajustements car TIO utilise Mono, mais j'utilisais le compilateur .NET 4.5
Brian J
1

APL (Dyalog) , 15 14 octets

-1 octet grâce à ngn .

2-/⍋⊃¨⊂)0,+\

+\ somme cumulée

0, ajouter un zéro

() Appliquer la fonction tacite suivante à cela:

 joindre (afin que nous puissions choisir plusieurs articles)

⍋⊃¨ laissez chacun des indices qui trierait l'argument choisir

¯2-/ différence par paire inversée

Essayez-le en ligne!


Solution originale trouvée par les participants du Code Golf Hackathon lors de la réunion des utilisateurs de Dyalog '17 :

¯2-/l[⍋l←+\0,⎕]

Essayez-le en ligne!

 demande de saisie

0, ajouter un zéro

+\ somme cumulée

l← stocker sous l

 trouver les indices qui trieront l

l[] Utilisez-le pour indexerl

¯2-/ différence par paire inversée

Adám
la source
1
Je ne sais pas si cela a été autorisé au hackathon mais si vous le réécrivez dans un style sans point, vous pouvez enregistrer un caractère: (¯2- / ⍋⊃¨⊂) 0, + \
ngn
@ngn Cette partie de l'atelier tentait de faire démarrer les participants avec PPCG, donc les règles ici étaient celles de PPCG. Merci.
Adám
1

MATL , 6 octets

0hYsSd

Essayez-le en ligne!

0       # push 0
 h      # horizontal concatenate with implicit input
  Ys    # cumulative sum
    S   # sort
     d  # diff (implicit output)
Giuseppe
la source
0

Gaia , 7 octets

1¤++⊣ȯọ

Essayez-le en ligne!

Explication

1¤+      Prepend 1
   +⊣    Cumulative sums
     ȯ   Sort
      ọ  Deltas
Chat d'affaires
la source
0

Röda , 42 octets

{i=0{[0];[i]if i+=_}|sort|slide 2|[_2-_1]}

Essayez-le en ligne!

Ceci est similaire à la réponse Perl 6 . .sortest |sort, .rotor(2=>-1).flatest |slide 2 et .map(*R-*)est |[_2-_1].

Explication:

{
  i=0 /* initialize variable i */
  /* the following block recreates the original list from differences: */
  {
    [0];       /* push 0 to the stream */
    [i]if i+=_ /* add every number in the stream to i and push i back */
  }|
  sort|    /* sort the numbers */
  slide 2| /* for values i1, i2, i3, ... in the stream
              push pairs i1, i2, i2, i3, ... */
  [_2-_1]  /* calculate difference of numbers in each pair in the stream */
}

La déclaration [i]if i+=_équivaut à

for sfv do
  if i += sfv do
    push(i)
  done
done

L' +=opérateur ne pousse pas de valeurs dans le flux, c'est donc vrai. J'aurais également pu utiliser une sorte de bloc (par exemple. {|j|i+=j;[i]}_) Pour lier l'addition et pousser les instructions ensemble, mais ifc'est plus court.

fergusq
la source
0

Julia 0.6.0 (34 octets)

À peu près une copie de ce qui a été fait dans R et Python 3

x->diff(sort(cumsum(vcat([0],x))))

Goysa
la source
0

J, 10 octets

/:~&.(+/\)

explication

"sort under scan sum": In J, the Under conjunction &. applies the transformation to its right to the input, then applies the verb to its left (in this case sort /:~) and then does the reverse transformation. That is, J understands how to invert a scan sum, which is exactly what's needed here: the successive differences are the input that, when scan-summed, will produce that scan-sum.

Try it online!

Jonah
la source