Sort and Re-apply Deltas of an Array

11

1

It seems that any Simple Modification of deltas using a consistent function can almost always be done some other shorter way, Dennis. Thus, the only solution I can imagine to make this harder, is to introduce some sort of inconsistent function.

Sorting.

Your task is to take an array of integers, sort their deltas, and recompile that to give the new array of integers.

EG.

For the input:

1  5 -3  2  9

Get the following Deltas:

  4 -8  5  7

Then, sort these Deltas, Yielding:

 -8  4  5  7

And reapply them, which gives:

1 -7 -3  2  9

Input/Output

You will be given a list/array/table/tuple/stack/etc. of signed integers as input through any standard input method.

You must output the modified data once again in any acceptable form, following the above delta sorting method.

You will receive N inputs where 0 < N < 10 where each number falls within the range -1000 < X < 1000

Test Cases

1 5 -3 2 9   -> 1 -7 -3 2 9
-5 -1 -6 5 8 -> -5 -10 -7 -3 8
-8 1 -7 1 1  -> -8 -16 -16 -8 1
8 -9 3 0 -2  -> 8 -9 -12 -14 -2
-5 -2 -5 5 0 -> -5 -10 -13 -10 0
-1 9 -1 -7 9 -> -1 -11 -17 -7 9

Notes

  • As stated in above, you will always receive at least 1 input, and no more than 9.
  • The first and last number of your output, will always match that of the input.
  • Only Standard Input Output is accepted
  • Standard loopholes apply
  • This is , so the lowest byte-count wins!
  • Have fun!

ATaco

Posted 2017-03-28T23:41:31.007

Reputation: 7 898

2IMO you should remove the second header (the one in the body of the post itself). It's kinda ugly and just takes up space, and it's a copy of the title (which is like 20 px above it). – Rɪᴋᴇʀ – 2017-03-29T00:10:58.473

Answers

4

Jelly, 7 bytes

IṢ;@Ḣ+\

Try it online!

How it works

IṢ;@Ḣ+\  Main link. Argument: A (array)

I        Increments; compute the deltas.
 Ṣ       Sort them.
    Ḣ    Head; pop and yield the first element of A.
  ;@     Concatenate with swapped arguments.
     +\  Take the cumulative sum.

Dennis

Posted 2017-03-28T23:41:31.007

Reputation: 196 637

5

MATL, 8 bytes

1)GdShYs

Try it online!

1)   % Implicit input. Get its first entry
G    % Push input again
d    % Differences
S    % Sort
h    % Concatenate
Ys   % Cumulative sum. Implicit display

Luis Mendo

Posted 2017-03-28T23:41:31.007

Reputation: 87 464

3

Mathematica, 40 bytes

FoldList[Plus,#&@@#,Sort@Differences@#]&

Pure function taking a list of (anythings) as input and returning a list. FoldList[Plus starts with a number (in this case, #&@@#, the first element of the input) and repeatedly adds elements of the self-explanatory list Sort@Differences@#. This mimics the behavior of the built-in Accumulate, but the first number would need to be prepended to the list of differences by hand, which makes the byte-count higher (as far as I can tell).

Greg Martin

Posted 2017-03-28T23:41:31.007

Reputation: 13 940

3

05AB1E, 9 bytes

-4 thanks to Emigna

¬=s¥{vy+=

Try it online!

¬         # Get the head
 =        # Print
  s¥{     # Get sorted Deltas
     vy   # For each
       += # Add to the previous value and print

Riley

Posted 2017-03-28T23:41:31.007

Reputation: 11 345

You could save 4 bytes with ¬=s¥{vy+= – Emigna – 2017-03-29T07:05:51.783

2

Haskell, 59 Bytes

import Data.List
f l@(a:b)=scanl1(+)$a:(sort$zipWith(-)b l)

Breakdown:

f l@(a:b) =           --we create a function f that takes as input a list l with head a and tail b
zipWith(-)b l        --we make a new list with the deltas
sort$                    --sort it
a:                          --prepend a to the list
scanl1(+)$          --create a new list starting with a and adding the deltas to it cumulatively

Generic Display Name

Posted 2017-03-28T23:41:31.007

Reputation: 365

2scanl(+)a$sort... – nimi – 2017-03-29T05:05:25.823

2

Python 2, 92 bytes

l=input();p=0;d=[]
r=l[0],
for e in l:d+=e-p,;p=e
for e in sorted(d[1:]):r+=r[-1]+e,
print r

orlp

Posted 2017-03-28T23:41:31.007

Reputation: 37 067

2

Python 2,

90 bytes

x=input()
print[sum(sorted(map(int.__sub__,x[1:],x[:-1]))[:i])+x[0]for i in range(len(x))]

84 bytes

Saved 6 bytes on using lambda. Thanks to ovs!

lambda x:[sum(sorted(map(int.__sub__,x[1:],x[:-1]))[:i])+x[0]for i in range(len(x))]

Try it online!

Breaking down the code,

>>> x
[1, 5, -3, 2, 9]
>>> map(int.__sub__,x[1:],x[:-1]) #delta
[4, -8, 5, 7]
>>> sorted(map(int.__sub__,x[1:],x[:-1])) #sorted result
[-8, 4, 5, 7]
>>> [sorted(map(int.__sub__,x[1:],x[:-1]))[:i]for i in range(len(x))]
[[], [-8], [-8, 4], [-8, 4, 5], [-8, 4, 5, 7]]
>>> [sum(sorted(map(int.__sub__,x[1:],x[:-1]))[:i])+x[0]for i in range(len(x))]
[1, -7, -3, 2, 9]

Happy Coding!

Keerthana Prabhakaran

Posted 2017-03-28T23:41:31.007

Reputation: 759

i was trying to find a way to do it like that! – quintopia – 2017-03-29T08:01:34.183

1You can save some bytes by converting this into a function: lambda x:[sum(sorted(map(int.__sub__,x[1:],x[:-1]))[:i])+x[0]for i in range(len(x))] – ovs – 2017-03-29T09:31:55.187

2

JavaScript (ES6), 68 bytes

([p,...a])=>[s=p,...a.map(e=>p-(p=e)).sort((a,b)=>b-a).map(e=>s-=e)]

In JavaScript it turns out to be golfier to compute the Inverse Deltas of an Array. These are then sorted in descending order and cumulatively subtracted from the first element.

Neil

Posted 2017-03-28T23:41:31.007

Reputation: 95 035

1

Python 2, 97 bytes

p=input()
d=[p[i+1]-p[i] for i in range(len(p)-1)]
o=p[:1]
for n in sorted(d):o+=o[-1]+n,
print o

Try it online!

user67482

Posted 2017-03-28T23:41:31.007

Reputation:

You can delete a space in the list comprehension for 96 bytes: [p[i+1]-p[i]for i in range(len(p)-1)] – sagiksp – 2017-03-30T07:05:22.133

1

JavaScript (ES6), 93 bytes

(p,M=[p[0]])=>p.map((a,b)=>p[b+1]-a).sort((a,b)=>a-b).map((a,b)=>M=[...M,M[b]+a])[p.length-2]

R. Kap

Posted 2017-03-28T23:41:31.007

Reputation: 4 730

1

Pyth, 11 bytes

.u+NYS.+QhQ

This just does the obvious thing described in the statement.

Try It Online

      .+Q    Take the deltas of the input
     S       sort it
.u           Cumulative reduce
  +NY        using addition
         hQ  starting with the first element of the input

Suggestions for further golfing welcome.

quintopia

Posted 2017-03-28T23:41:31.007

Reputation: 3 899

1

Julia 0.5, 30 bytes

!x=[x[];x|>diff|>sort]|>cumsum

Try it online!

Dennis

Posted 2017-03-28T23:41:31.007

Reputation: 196 637

1

Python 2 with numpy, 67 56 bytes

from numpy import*
lambda l:cumsum(l[:1]+sorted(diff(l)))

Let numpy compute the deltas, sort them, prepend the first element, and let numpy compute the cumulative sums. Pretty cheap?

quintopia

Posted 2017-03-28T23:41:31.007

Reputation: 3 899

1Save 3 bytes by changing the import to from numpy import* and n.cumsum to cumsum and n.diff to diff – ovs – 2017-03-29T09:37:15.207

Thanks. You can tell its been a while since I golfed python, forgetting all the standard tricks. – quintopia – 2017-03-29T17:22:38.677

1

PHP, 89 bytes

for($a=$argv;n|$i=$a[++$x+1];)$d[]=$i-$a[$x];for(sort($d);$x-$y++;)echo$a[1]+=$d[$y-2],_;

Run like this:

php -nr 'for($a=$argv;n|$i=$a[++$x+1];)$d[]=$i-$a[$x];for(sort($d);$x-$y++;)echo$a[1]+=$d[$y-2],",";' 1  5 -3  2  9;echo
> 1_-7_-3_2_9_

Explanation

for(
  $a=$argv;          # Set input to $a.
  n | $i=$a[++$x+1]; # Iterate over input.
)
  $d[] = $i-$a[$x];  # Add an item to array $d, with the difference between
                       the current and previous item.

for(
  sort($d);          # Sort the delta array.
  $x-$y++;           # Loop as many times as the previous loop.
)
  echo
    $a[1]+=$d[$y-2], # Print the first input item with the delta applied
                     # cumulatively. First iteration takes $d[-1], which
                     # is unset, so results in 0.
    _;               # Print underscore as separator.

aross

Posted 2017-03-28T23:41:31.007

Reputation: 1 583

0

Perl 6, 31 bytes

{[\+] @_[0],|sort @_[1..*]Z-@_}

Try it

Expanded:

{
  [\+]            # triangle produce values using &infix<+>
    @_[0],        # starting with the first argument
    |             # slip the following into this list
      sort        # sort the following

         # generate the list of deltas

         @_[1..*] # the arguments starting with the second one
         Z[-]     # zipped using &infix:<->
         @_       # the arguments
}

Brad Gilbert b2gills

Posted 2017-03-28T23:41:31.007

Reputation: 12 713

0

Batch, 197 bytes

@set n=%1
@set s=
:l
@set/ad=5000+%2-%1
@set s=%s% %d%
@shift
@if not "%2"=="" goto l
@echo %n%
@for /f %%a in ('"(for %%b in (%s%)do @echo %%b)|sort"') do @set/an+=%%a-5000&call echo %%n%%

sort doesn't sort numerically, so I bias all the differences by 5000.

Neil

Posted 2017-03-28T23:41:31.007

Reputation: 95 035

0

bash + sort, 102 bytes

echo $1
n=$1
shift
for e in $*
do
echo $((e-n))
n=$e
done|sort -n|while read e
do
echo $((n+=e))
done

sh + sort + expr, 106 bytes

echo $1
n=$1
shift
for e in $*
do
expr $e - $n
n=$e
done|sort -n|while read e
do
n="$n + $e"
expr $n
done

Neil

Posted 2017-03-28T23:41:31.007

Reputation: 95 035

0

Clojure, 46 bytes

#(reductions +(first %)(sort(map -(rest %)%)))

One day I'm going to make Cljr language which has shorter function names than Clojure.

NikoNyrh

Posted 2017-03-28T23:41:31.007

Reputation: 2 361