Ordenar una lista de diferencias

22

La lista de diferencias de una lista de enteros es la lista de diferencias de miembros consecutivos.

Por ejemplo, la lista de diferencias de

1, 3, 2 ,4

es

2, -1, 2

Su tarea es tomar como entrada una lista de diferencias y mostrar cómo se vería la lista de diferencias si se ordenara la lista original.

Por ejemplo la lista de diferencias

2, 1, -2, -1

Podría representar una lista

2 4 5 3 2

Que cuando se ordena es

2 2 3 4 5

Que tiene una lista de diferencias de

0 1 1 1

Este es el por lo que las respuestas se puntuarán en bytes, siendo mejores menos bytes.

Asistente de trigo
fuente
¿Se garantiza que las soluciones sean únicas?
H.PWiz
@ H.PWiz Sí, lo son.
Wheat Wizard
Relacionado.
totalmente humano
1
@ H.PWiz Prueba rápida: una lista es perfectamente reconstruible a partir de una lista de diferencias (DL) combinada con un primer valor de elemento, por lo que hay una conversión de uno a uno de L a (FV, DL). Aumentar el FV en cualquier cantidad es lo mismo que agregar esa cantidad a cada elemento de la L y, por lo tanto, no puede cambiar la clasificación de L si esa comparación es adecuadamente monotónica. (En otras palabras, no afecta la ordenación a menos que el número que está agregando provoque un desbordamiento de enteros).
CR Drost
1
¿Podría agregar algunos casos de prueba más? Noto algunas soluciones que ofrecen diferentes resultados [-2, 100, -2, -1], por ejemplo.
Shaggy

Respuestas:

16

05AB1E , 4 bytes

.¥{¥

Pruébalo en línea!

Explicación

.¥{¥
.¥   # Undelta the input list
  {  # Sort it
   ¥ # And get the deltas
Datboi
fuente
Undelta05AB1E tiene la mayoría de los empotrados integrados. o0
totalmente humano
2
Ahh mierda, venceme. Siempre quise usar Undelta.
Urna mágica del pulpo
16
Undeltaಠ ___ ಠ
Business Cat
1
"Undelta" es simplemente una suma acumulativa, ¿verdad?
Zgarb
2
@Zgarb Undelta está agregando un 0 como el primer elemento de la lista, luego exactamente como usted ha dicho, suma acumulativa o delta inversa.
Urna mágica del pulpo
9

Python 3 con Numpy , 56 54 53 bytes

2 bytes de descuento gracias a @Artyer (Numpy's en sortlugar de estándar sorted). 1 byte apagado gracias a @notjagan (mudarse 0a cumsum)

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

El código define una función anónima que ingresa una lista o una matriz Numpy y genera una matriz Numpy.

Pruébalo en línea!

Luis Mendo
fuente
1
Woah, me enseñaste algo nuevo hoy. Mi acercamiento con numpyfue mucho más largo. Volveré mañana para votar esto, porque veo que ya tienes un tope. ¡Muy agradable!
Sr. Xcoder
@ Mr.Xcoder Gracias! No soy un experto en Numpy, solo seguí lo que hubiera hecho en Matlab: diff(sort([0 cumsum(x)]))(en Matlab, [ ]es concatenación)
Luis Mendo
Deber cumplido!
Sr. Xcoder
-1 byte moviendo el 0a cumsum.
notjagan
5

Mathematica, 40 bytes

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

Casco , 4 bytes

Ẋ-O∫

Pruébalo en línea!

Explicación

      -- 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
fuente
¿Otro idioma que tiene undelta? ¿O algún más elegante incorporado?
Sr. Xcoder
@Señor. Xcoder Sucede que cumsum es lo mismo que undelta
H.PWiz
@ H.PWiz En realidad, eso no es lo que llamamos cumsum ... a menos que tenga en cuenta el prefijo vacío.
Erik the Outgolfer
@EriktheOutgolfer Sí, eso es lo que hace la cáscara, como es scanl(+)0en Haskell.
H.PWiz
4

Pyth , 9 bytes

-1 byte gracias a @EriktheOutgolfer .

.+S+0sM._

Banco de pruebas.

Pyth , 10 bytes

.+S.u+YNQ0

Pruébalo en línea! o Pruebe más casos de prueba .

Sr. Xcoder
fuente
Como en mi respuesta (eliminada), puede usar en +0sM._lugar de .u+YNQ0para -1.
Erik the Outgolfer
@EriktheOutgolfer ¿Por qué lo borraste?
Sr. Xcoder
Pensé que la idea central era demasiado similar a la tuya.
Erik the Outgolfer
@EriktheOutgolfer Ok, gracias entonces
Sr. Xcoder
m=+Zes una variante de la misma longitud sM._, pero lamentablemente no parece que pueda ser más corta.
FryAmTheEggman
4

JavaScript (ES6), 57 56 bytes

Guardado 1 byte gracias a @ETHproductions

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

Manifestación

Arnauld
fuente
.sort((a,b)=>a-b)¿Esa es la forma de obtener deltas? Al ordenar con sustracción? : P
totalmente humano
@totallyhuman El primero map()da los deltas. Este código los ordena. El segundo mapa reconstruye los nuevos deltas. El sort()método JS usa el orden lexicográfico por defecto. Por lo tanto, necesitamos esta devolución de llamada especializada para números> 9 (lamentablemente).
Arnauld
Eso -p+(p=n)muele mis engranajes, pero lamentablemente no hay mejor manera ... a menos que ...
ETHproductions
qué diablos, no presioné el botón de enviar> _ <Pero de todos modos, creo que puedes guardar un byte con esa edición ...
ETHproductions
@ETHproductions Gracias :-)
Arnauld
3

Java 8, 123 bytes

La solución estándar: entrada de suma acumulativa, ordenar, luego diff. No hay trucos sustanciales de implementación tampoco.

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

Fundido a Consumer<int[]>. La salida es entrada mutada.

Pruébalo en línea

Lambda sin 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];
}

Expresiones de gratitud

  • -3 bytes gracias a Olivier Grégoire , maestro de la autoincrementación impía
  • -1 byte gracias a Nevay
Jakob
fuente
1
Puede jugar golf 3 bytes reorganizando las posiciones donde realiza sus incrementos y sus cálculos generales: 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];}(tenga cuidado con los caracteres invisibles de SE al copiar / pegar)
Olivier Grégoire
1
Gracias por mi nuevo título;) Aquí hay más decremento de impiedad para celebrar for(;i>0;)l[i-1]=d[i]-d[--i];(último bucle)
Olivier Grégoire
Acababa de reelaborar ese ciclo yo mismo, llegando a for(;i-->0;)l[i]=d[i+1]-d[i];la misma longitud. Actualización por venir.
Jakob
2
Puede guardar 1 byte usando 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 si, por supuesto. ¡Gracias!
Jakob
2

R , 31 32 bytes

-4 bytes gracias a @ user2390246 por diffinv

+5 bytes de Jarko para cat

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

Lee desde stdin, escribe en stdout. diffinves un inverso de diffun valor inicial dado (0 por defecto). Como está diffeditado nuevamente, no importa cuál sea ese valor.

Como señaló Jarko Dubbeldam, necesitaba generar correctamente el resultado, a un costo de cinco bytes. Ay.

Pruébalo en línea!

Giuseppe
fuente
Eso es lo que tenía en mente también. Sin embargo, debe manejar la impresión, ya que ejecutar esto como un programa completo (a través source) no genera nada.
JAD
1
Si usa en diffinvlugar de cumsumno necesita anteponer cero.
user2390246
@ user2390246 wow, muy bien! TIL sobre diffinv.
Giuseppe
¡Yo también! Estaba haciendo una búsqueda rápida para ver si había respuestas anteriores a las que podría haber aplicado.
user2390246
1

Python 2 , 83 bytes

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:])]

Pruébalo en línea!

Solución horrible

totalmente humano
fuente
No es tan terrible, de hecho
Sr. Xcoder
El +=operador de Python en listas funciona con cualquier iterable, por lo que puede usar en r+=r[-1]+i,lugar de r+=[r[-1]+i]y guardar un byte.
Jonathan Frech
1

Perl 6 , 46 bytes

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

Intentalo

Expandido:

{  # 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
fuente
1

Haskell , 74 bytes

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

Pruébalo en línea!

Sencillo.

jferard
fuente
3
=<<de la función mónada es útil: (zipWith(-)=<<tail).sort.scanl(+)0
nimi
@nimi Muy bien. No soy experto en mónadas, pero debería haberlo pensado zipWith.
jferard
1

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

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

Solicita la entrada del usuario. La lista debe ser ingresada con un inicio {, con números separados por ,, y con un final opcional }.

TI-Basic es un lenguaje tokenizado ; ΔList(y cumSum(son tokens de dos bytes, todos los demás tokens utilizados son de un byte cada uno.

Ejemplo de ejecución (con NAMEel nombre del programa y {4,-2,7,-4,0}la entrada):

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

Explicación:

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
fuente
¿Necesitas los L's?
Zacharý
@ Zacharý puede omitirlos al almacenar una lista, pero omitirlos al hacer referencia se referiría a la variable numérica X en lugar de la lista
pizzapants184
1

C ++ (gcc) , 136 bytes

Como lambda genérico sin nombre, suponiendo que la entrada sea similar std::listy que regrese a través del parámetro de referencia.

[](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);}

Pruébalo en línea!

Sin 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
fuente
1

Pyth, 8 bytes

.+S+M.uP

Demostración

.+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
fuente
+1 Esta es una solución clara con un punto fijo acumulativo. Yo personalmente ni siquiera pensé en esto.
Sr. Xcoder
1

TI-Basic, 20 bytes

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

VB.NET (.NET 4.5), 109 bytes

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

Una función que espera una lista como entrada y la modifica directamente. El parámetro original se puede usar para la salida

  1. Recrea una lista original agregando reenvíos a través de la lista (supone un 0 implícito como primer elemento)
  2. Ordena la lista original
  3. Obtiene las diferencias yendo hacia atrás (por lo que no necesito hacer un seguimiento de una lista diferente) (el primer elemento implícito de 0 significa que la primera diferencia es la misma que el elemento más pequeño)

Pruébalo en línea!

Brian J
fuente
¿Te importaría actualizar el enlace TIO?
Taylor Scott
@TaylorScott Actualización de qué manera?
Brian J
Su enlace TIO muestra un código completamente diferente que en su respuesta
Taylor Scott
1
@ TaylorScott Ahh ... Ya veo. Tuve que hacer algunos ajustes porque TIO usa Mono, pero estaba usando el compilador .NET 4.5
Brian J
1

APL (Dyalog) , 15 14 bytes

-1 byte gracias a ngn .

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

+\ suma acumulativa

0, anteponer un cero

(... ) aplique la siguiente función tácita sobre eso:

 adjuntar (para que podamos elegir varios elementos)

⍋⊃¨ deje que cada uno de los índices que ordenaría el argumento elija

¯2-/ diferencia por pares invertida

Pruébalo en línea!


Solución original encontrada por los participantes de Code Golf Hackathon en la reunión de usuarios de Dyalog '17 :

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

Pruébalo en línea!

 solicitud de entrada

0, anteponer un cero

+\ suma acumulativa

l← almacenar como l

 encuentra los índices que ordenarán l

l[... ] usa eso para indexarl

¯2-/ diferencia por pares invertida

Adám
fuente
1
No sé si esto se permitió en el hackathon, pero si lo reescribe en un estilo sin puntos, podría guardar un carácter: (¯2- / ⍋⊃¨⊂) 0, + \
ngn
@ngn Esta parte del taller intentaba que los participantes comenzaran con PPCG, por lo que las reglas aquí eran las de PPCG. Gracias.
Adám
1

MATL , 6 bytes

0hYsSd

Pruébalo en línea!

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

k , 16 bytes

1_-':{x@<x}@+\0,

Pruébalo en línea!

              0, /prepend a 0
            +\   /cumulative sum
     {x@<x}@     /sort
1_-':            /differences list
zgrep
fuente
0

Röda , 42 bytes

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

Pruébalo en línea!

Esto es similar a la respuesta de Perl 6 . .sortes |sort, .rotor(2=>-1).flates |slide 2 y .map(*R-*)es |[_2-_1].

Explicación:

{
  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 declaración [i]if i+=_es equivalente a

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

El +=operador no envía valores a la secuencia, por lo que es veraz. También podría haber usado algún tipo de bloqueo (p. Ej. {|j|i+=j;[i]}_) Para unir la suma y las declaraciones, pero ifes más corto.

fergusq
fuente
0

Julia 0.6.0 (34 bytes)

Más o menos una copia de lo que se ha hecho en R y Python 3

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

Goysa
fuente
0

J, 10 bytes

/:~&.(+/\)

explicación

"ordenar bajo suma de exploración": en J, la conjunción Bajo &.aplica la transformación a su derecha a la entrada, luego aplica el verbo a su izquierda (en este caso, ordenar /:~) y luego realiza la transformación inversa. Es decir, J entiende cómo invertir una suma de exploración, que es exactamente lo que se necesita aquí: las diferencias sucesivas son la entrada que, cuando se suma la exploración, producirá esa suma de exploración.

Pruébalo en línea!

Jonás
fuente