Classificar uma lista de diferenças


22

A lista de diferenças de uma lista de números inteiros é a diferença de lista de membros consecutivos.

Por exemplo, a lista de diferenças de

1, 3, 2 ,4

é

2, -1, 2

Sua tarefa é tomar como entrada uma lista de diferenças e exibir como seria a lista de diferenças se a lista original fosse classificada.

Por exemplo, a lista de diferenças

2, 1, -2, -1

Pode representar uma lista

2 4 5 3 2

Que quando classificado é

2 2 3 4 5

Que tem uma lista diferente de

0 1 1 1

Isso é então as respostas serão pontuadas em bytes, com menos bytes sendo melhores.


As soluções são garantidas como únicas?
H.PWiz

@ H.PWiz Sim, eles são.
Assistente de trigo


1
@ H.PWiz Prova rápida: uma lista é perfeitamente reconstrutível a partir de uma lista de diferenças (DL) combinada com um valor do primeiro elemento, para que haja uma conversão individual de L para (FV, DL). Aumentar o VF em qualquer quantidade é o mesmo que adicionar essa quantidade a todos os elementos do L e, portanto, não pode alterar a classificação do L se essa comparação for adequadamente monotônica. (Em outras palavras, isso não afeta a classificação, a menos que o número que você está adicionando cause excesso de número inteiro).
CR Drost

1
Você poderia adicionar mais alguns casos de teste? Percebo algumas soluções que fornecem resultados diferentes [-2, 100, -2, -1], por exemplo.
Shaggy

Respostas:


16

05AB1E , 4 bytes

.¥{¥

Experimente online!

Explicação

.¥{¥
.¥   # Undelta the input list
  {  # Sort it
   ¥ # And get the deltas

Undelta05AB1E possui os mais embutidos nichos. o0
totallyhuman

2
Ahh merda, me derrote. Eu sempre quis usar undelta.
Magic Octopus Urn

16
Undeltaಠ ___ ಠ
Business Cat

1
"Undelta" é simplesmente soma acumulada, certo?
Zgarb

2
O @Zgarb Undelta está adicionando um 0 como o primeiro elemento da lista e, exatamente como você disse, soma acumulada ou delta reverso.
Magic Octopus Urn

9

Python 3 com Numpy , 56 54 53 bytes

2 bytes de desconto graças a @Artyer (Numpy em sortvez de padrão sorted). 1 byte off graças a @notjagan (mudança 0para cumsum)

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

O código define uma função anônima que insere uma lista ou uma matriz Numpy e gera uma matriz Numpy.

Experimente online!


1
Woah, você me ensinou algo novo hoje. Minha abordagem com numpyfoi muito mais longa. Volto amanhã para votar novamente, porque já vejo você no limite. Muito agradável!
Mr. Xcoder

@ Mr.Xcoder Obrigado! Não sou especialista em Numpy, eu apenas segui o que eu teria feito em Matlab: diff(sort([0 cumsum(x)]))(em Matlab, [ ]é concatenação)
Luis Mendo

Dever cumprido!
Mr. Xcoder

-1 byte movendo o 0para o cumsum.
precisa saber é o seguinte



4

Casca , 4 bytes

Ẋ-O∫

Experimente online!

Explicação

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

Outra língua que tem undelta? Ou algum extravagante embutido?
Mr. Xcoder

@Sr. Xcoder Acontece que cumSum é o mesmo que undelta
H.PWiz

@ H.PWiz Na verdade, não é isso que chamamos de cumsum ... a menos que você leve em consideração o prefixo vazio.
Erik the Outgolfer

@EriktheOutgolfer Sim, é isso que a casca faz, como é scanl(+)0em Haskell.
precisa saber é o seguinte

4

Pitão , 9 bytes

-1 byte graças a @EriktheOutgolfer .

.+S+0sM._

Suíte de teste.

Pitão , 10 bytes

.+S.u+YNQ0

Experimente online! ou Tente mais casos de teste .


Como na minha resposta (excluída), você pode usar em +0sM._vez de .u+YNQ0para -1.
Erik the Outgolfer

@EriktheOutgolfer Por que você a excluiu?
Mr. Xcoder

Achei que a ideia principal era muito semelhante à sua.
Erik the Outgolfer

@EriktheOutgolfer Ok, obrigado então
Sr. Xcoder 11/17

m=+Zé uma variante do mesmo comprimento sM._, mas, infelizmente, não parece que possa ser menor.
FryAmTheEggman 11/08

4

JavaScript (ES6), 57 56 bytes

Guardado 1 byte graças a @ETHproductions

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

Demo


.sort((a,b)=>a-b)Essa é a maneira de obter deltas? Classificando com subtração? : P
totallyhuman 11/08

@totallyhuman O primeiro map()fornece os deltas. Este código os classifica. O segundo mapa reconstrói os novos deltas. O sort()método JS usa ordem lexicográfica por padrão. Portanto, precisamos desse retorno de chamada especializado para números> 9 (infelizmente).
Arnauld

Que -p+(p=n)mói meu artes, mas, infelizmente, não há nenhuma maneira melhor ... a menos que ...
ETHproductions

o que o Parreira, eu não pressionar o botão enviar> _ <Mas de qualquer maneira, eu acho que você pode salvar um byte com que editar ...
ETHproductions

@ETHproductions Thanks :-)
Arnauld

3

Java 8, 123 bytes

A solução padrão: entrada de soma acumulada, classificação e, em seguida, diff. Também não há truques substanciais de implementação.

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

Transmitir para Consumer<int[]>. Saída com entrada mutada.

Experimente Online

Lambda ungolfed

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

Agradecimentos

  • -3 bytes graças a Olivier Grégoire , mestre em autoincrementação profana
  • -1 byte graças a Nevay

1
Você pode golfe 3 bytes por reorganizar as posições onde você faz seus incrementos e seus cálculos gerais: 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];}(cuidado com caracteres invisíveis da SE, quando copiar / colar)
Olivier Grégoire

1
Agradecimentos para o meu novo título;) Aqui está impiedade mais decrement para celebrar for(;i>0;)l[i-1]=d[i]-d[--i];(último ciclo)
Olivier Grégoire

Eu mesmo havia retrabalhado esse laço, chegando ao for(;i-->0;)l[i]=d[i+1]-d[i];mesmo comprimento. Atualize para vir.
Jakob

2
Você pode salvar 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 sim, claro. Obrigado!
21417 Jakob


2

R , 31 32 bytes

-4 bytes graças a @ user2390246 por diffinv

+5 bytes do Jarko para cat

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

Lê de stdin, escreve para stdout. diffinvé um inverso diffpara um determinado valor inicial (0 por padrão). Como é diffeditado novamente, não importa qual é esse valor.

Conforme apontado por Jarko Dubbeldam, eu precisava produzir corretamente o resultado, ao custo de cinco bytes. Alas.

Experimente online!


Isso é o que eu tinha em mente também. No entanto, é necessário lidar com a impressão, pois executar isso como um programa completo (através source) não gera nada.
JAD

1
Se você usar em diffinvvez de cumsumnão precisar acrescentar zero.
user2390246

@ user2390246 uau, muito bom! TIL sobre diffinv.
Giuseppe

Eu também! Eu estava apenas fazendo uma pesquisa rápida para ver se havia respostas anteriores às quais eu poderia ter 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:])]

Experimente online!

Horrible solution.


It's not that terrible, in fact
Mr. Xcoder

Python's += operator on lists works with any iterable, so you can use r+=r[-1]+i, instead of r+=[r[-1]+i] and save one byte.
Jonathan Frech

1

Perl 6, 46 bytes

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

Try it

Expanded:

{  # 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)
}

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

Try it online!

Straightforward.


3
=<< from the function monad comes in handy: (zipWith(-)=<<tail).sort.scanl(+)0
nimi

@nimi Very nice. I'm not expert in monads, but I should have thought of zipWith.
jferard

1

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

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

Prompts for user input. The list must be input with a leading {, with numbers separated by ,, and with an optional trailing }.

TI-Basic is a tokenized language; ΔList( and cumSum( are two-byte tokens, all other tokens used are one byte each.

Example run (with NAME as the program name and {4,-2,7,-4,0} as the input):

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

Explanation:

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

Do you need the L's?
Zacharý

@Zacharý you can omit them when storing a list, but omitting them when referencing would refer to the numerical variable X instead of the list
pizzapants184

1

C++ (gcc), 136 bytes

As unnamed generic lambda, assuming input to be like std::list and returning via reference parameter.

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

Try it online!

Ungolfed:

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

1

Pyth, 8 bytes

.+S+M.uP

Demonstration

.+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

+1 This is a neat workaround with cumulative fixed point. I personally didn't even think of this.
Mr. Xcoder

1

TI-Basic, 20 bytes

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


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

A function that expects a list as input and modifies it directly. The original parameter can then be used for output

  1. Recreates an original list by adding forwards through the list (assumes an implicit 0 as the first element)
  2. Sorts the original list
  3. Gets the differences by going backwards (so I don't need to keep track of a different list) (the implicit first element of 0 means the first difference is the same as the smallest element)

Try it online!


Would you mind updating the TIO link?
Taylor Scott

@TaylorScott Update in what way?
Brian J

Your TIO link shows completely different code than in your answer
Taylor Scott

1
@TaylorScott Ahh....I see. I had to make some adjustments because TIO uses Mono, but I was using the .NET 4.5 compiler
Brian J

1

APL (Dyalog), 15 14 bytes

-1 byte thanks to ngn.

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

+\ cumulative sum

0, prepend a zero

() apply the following tacit function on that:

 enclose (so we can pick multiple items)

⍋⊃¨ let each of the indices that would sort the argument pick from that

¯2-/ reversed pairwise difference

Try it online!


Original solution found by the Code Golf Hackathon participants at the Dyalog '17 User Meeting:

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

Try it online!

 prompt for input

0, prepend a zero

+\ cumulative sum

l← store as l

 find the indices that will sort l

l[] use that to index into l

¯2-/ reversed pairwise difference


1
I don't know if this was allowed at the hackathon but if you rewrite it in point-free style you could save a char: (¯2-/⍋⊃¨⊂)0,+\
ngn

@ngn This part of the workshop was attempting to get the participants started with PPCG, so the rules here were those of PPCG. Thanks.
Adám

1

MATL, 6 bytes

0hYsSd

Try it online!

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


0

k, 16 bytes

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

Try it online!

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


0

Röda, 42 bytes

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

Try it online!

This is similar to the Perl 6 answer. .sort is |sort, .rotor(2=>-1).flat is |slide 2 and .map(*R-*) is |[_2-_1].

Explanation:

{
  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 */
}

The statement [i]if i+=_ is equivalent to

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

The += operator does not push values to the stream, so it is truthy. I could also have used some kind of block (eg. {|j|i+=j;[i]}_) to tie the addition and pushing statements together, but if is shorter.


0

Julia 0.6.0 (34 bytes)

Pretty much a copy of what has been done in R and Python 3

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


0

J, 10 bytes

/:~&.(+/\)

explanation

"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!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.