Fark listesini sırala


22

Bir tamsayı listesindeki fark listesi ardışık üyelerin liste farklarıdır.

Örneğin fark listesi

1, 3, 2 ,4

olduğu

2, -1, 2

Göreviniz bir fark listesi olarak almak ve orijinal listenin sıralanması halinde fark listesinin nasıl görüneceğini ortaya koymaktır.

Örneğin fark listesi

2, 1, -2, -1

Bir liste gösterebilir

2 4 5 3 2

Sıralandığında

2 2 3 4 5

Hangisinin bir fark listesi vardır

0 1 1 1

Bu olduğundan, cevaplar daha az byte'ın daha iyi olmasıyla byte olarak puanlanacak.


Çözümlerin benzersiz olması garanti ediliyor mu?
H.PWiz

@ H.PWiz Evet onlar.
Buğday Sihirbazı,


1
@ H.PWiz Hızlı kanıt: bir liste, birinci eleman değeri ile birleştirilmiş bir fark listesinden (DL) mükemmel bir şekilde yeniden yapılandırılabilir, bu yüzden L'den (FV, DL )'e bire bir dönüşüm var. FV'yi herhangi bir miktarda arttırmak, bu miktarın L'nin her elemanına eklenmesiyle aynıdır ve bu nedenle eğer bu karşılaştırma uygun şekilde monotonik ise L'nin sıralamasını değiştiremez. (Başka bir deyişle, eklediğiniz numara tamsayı taşmasına neden olmadıkça sıralamayı etkilemez).
CR Drost

1
Birkaç test davası daha ekler misin? [-2, 100, -2, -1]Örneğin, farklı çıktılar veren bazı çözümler dikkatimi çekti .
Shaggy,

Yanıtlar:


16

05AB1E , 4 bayt

.¥{¥

Çevrimiçi deneyin!

açıklama

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

Undelta05AB1E en niş yapılara sahiptir. o0
totallyhuman

2
Kahretsin, beni döv. Her zaman undelta kullanmak istemişimdir.
Magic Octopus Urn

16
Undeltaಠ ___ ಠ
Business Cat

1
"Undelta" basitçe toplamtır, değil mi?
Zgarb

2
@Zgarb Undelta, listenin ilk öğesi olarak bir 0 ekliyor, ardından tam olarak söylediğiniz gibi, toplam veya ters delta.
Magic Octopus Urn

9

Numpy ile Python 3 , 56 54 53 bayt

@Artyer sayesinde 2 bayt kapalı sort(standart yerine Numpy's sorted). Sayesinde kapalı 1 byte @notjagan (hareketli 0içine cumsum)

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

Kod, bir liste veya bir Numpy dizisi giren ve bir Numpy dizisi çıkaran anonim bir işlevi tanımlar.

Çevrimiçi deneyin!


1
Woah, bugün bana yeni bir şey öğrettin. Benim yaklaşımım numpyçok daha uzundu. Bunu telafi etmek için yarın geleceğim, çünkü seni çoktan kapattığını gördüm. Çok hoş!
Bay Xcoder

@ Mr.Xcoder Teşekkürler! Numpy konusunda uzman değilim, sadece Matlab'da ne yaptığımı takip ettim: diff(sort([0 cumsum(x)]))(Matlab'da [ ]bitiştirme)
Luis Mendo

Görev yerine getirildi!
Bay Xcoder

0İçine hareket ettirerek -1 baytcumsum .
notjagan,



4

Kabuğu , 4 bayt

Ẋ-O∫

Çevrimiçi deneyin!

Açıklama

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

Geri almayan başka bir dil? Ya da bazı meraklısı yerleşik?
Bay Xcoder

@Bay. Xcoder Bu cumsum unelta ile aynı olur
H.PWiz

@ H.PWiz Aslında boş öneki hesaba katmazsanız, cumsum dediğimiz şey değil.
Outgolfer Erik,

@EriktheOutgolfer Evet, kabuğu böyle scanl(+)0Haskell'deki gibi.
H.PWiz

4

Pyth , 9 bayt

@EriktheOutgolfer sayesinde -1 bayt .

.+S+0sM._

Test odası.

Pyth , 10 bayt

.+S.u+YNQ0

Çevrimiçi deneyin! veya Daha fazla test senaryosu deneyin .


(Silinen) cevabımda olduğu gibi -1 +0sM._yerine kullanabilirsiniz .u+YNQ0.
Outgolfer Erik,

@EriktheOutgolfer Neden sildin?
Bay Xcoder

Çekirdek fikrin seninkine çok benziyordu.
Outgolfer Erik,

@EriktheOutgolfer Tamam, o zaman teşekkürler
Bay

m=+Zbunun için aynı uzunluktaki bir değişkendir sM._, fakat ne yazık ki daha kısa olabilir gibi görünmüyor.
FryAmTheEggman

4

JavaScript (ES6), 57 56 bayt

@ETHproductions sayesinde 1 bayt kaydedildi

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

gösteri


.sort((a,b)=>a-b)Delta almanın yolu bu mu? Çıkarma ile sıralama yaparak? : P
totallyhuman,

@totallyhuman İlk map()deltaları verir. Bu kod onları sıralar. 2. harita yeni deltaları yeniden inşa etti. JS sort()yöntemi, varsayılan olarak sözlük sırası kullanır. Bu nedenle,> 9 (ne yazık ki) sayılar için bu özel geri çağrıya ihtiyacımız var.
Arnauld

Bu -p+(p=n)benim
dişlerimi taşlıyor

ne halt, gönder düğmesine
basmadım

@ETHproductions Teşekkürler :-)
Arnauld

3

Java 8, 123 bayt

Standart çözüm: kümülatif toplam giriş, sıralama, sonra fark. Hiçbir önemli uygulama püf noktası yok.

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

İçin attı Consumer<int[]>. Çıkış mutasyona uğramış giriş.

Çevrimiçi Deneyin

Ungolfed lambda

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

Teşekkür

  • Kutsal bayramın otomasyonu ustası Olivier Grégoire sayesinde -3 bayt
  • Nevay sayesinde -1 bayt

1
You can golf 3 bytes by rearranging the positions where you do your increments and your overall computations: 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];} (beware SE's invisible characters when copy/pasting)
Olivier Grégoire

1
Thanks for my new title ;) Here's more decrement unholiness to celebrate for(;i>0;)l[i-1]=d[i]-d[--i]; (last loop)
Olivier Grégoire

I had just reworked that loop myself, arriving at for(;i-->0;)l[i]=d[i+1]-d[i]; of the same length. Update to come.
Jakob

2
You can save 1 byte by using 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 yes, of course. Thanks!
Jakob


2

R, 31 32 bytes

-4 bytes thanks to @user2390246 for diffinv

+5 bytes from Jarko for cat

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

Reads from stdin, writes to stdout. diffinv is an inverse of diff for a given starting value (0 by default). Since it's diffed again, it doesn't matter what that value is.

As pointed out by Jarko Dubbeldam, I needed to properly output the result, at the cost of five bytes. Alas.

Try it online!


That's what I had in mind as well. Does need to handle printing though, as running this as a full program (through source) this doesn't output anything.
JAD

1
If you use diffinv rather than cumsum you don't need to prepend zero.
user2390246

@user2390246 wow, very nice! TIL about diffinv.
Giuseppe

Me too! I was just having a quick search to see if there were any previous answers I could have applied it to.
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:])]

Try it 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

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!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.