整数列表的差异列表是连续成员的列表差异。
例如,差异列表
1, 3, 2 ,4
是
2, -1, 2
您的任务是将差异列表作为输入,并输出对原始列表进行排序后的差异列表的外观。
例如差异列表
2, 1, -2, -1
可能代表清单
2 4 5 3 2
排序时是
2 2 3 4 5
其中有一个差异列表
0 1 1 1
这是代码高尔夫球,因此答案将以字节计分,而字节数越少越好。
[-2, 100, -2, -1]
。
整数列表的差异列表是连续成员的列表差异。
例如,差异列表
1, 3, 2 ,4
是
2, -1, 2
您的任务是将差异列表作为输入,并输出对原始列表进行排序后的差异列表的外观。
例如差异列表
2, 1, -2, -1
可能代表清单
2 4 5 3 2
排序时是
2 2 3 4 5
其中有一个差异列表
0 1 1 1
这是代码高尔夫球,因此答案将以字节计分,而字节数越少越好。
[-2, 100, -2, -1]
。
Answers:
Undelta
05AB1E具有最多的内置细分市场。o0
Undelta
ಠ___ಠ
多亏@Artyer(用Numpy sort
代替standard sorted
),可节省 2个字节。@notjagan节省了 1个字节(移动0
到cumsum
)
lambda x:diff(sort(cumsum([0]+x)))
from numpy import*
该代码定义了一个匿名函数,该匿名函数输入一个列表或一个Numpy数组并输出一个Numpy数组。
numpy
要长得多。我明天会回来支持这个,因为我看到你已经被封顶了。非常好!
diff(sort([0 cumsum(x)]))
在Matlab中[ ]
是串联的)
Differences@Sort@Accumulate@Join[{1},#]&
Differences@Sort@FoldList[+##&,1,#]&
Ẋ-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]
scanl(+)0
在Haskell中一样。
+0sM._
代替.u+YNQ0
-1。
m=+Z
是的相同长度变体sM._
,但可悲的是它似乎不能更短。
@ETHproductions节省了1个字节
a=>a.map(n=>t-=n,p=t=0).sort((a,b)=>b-a).map(n=>p-(p=n))
.sort((a,b)=>a-b)
那就是获得增量的方式吗?通过减法排序?:P
map()
给出增量。此代码对它们进行排序。第二张地图重建新的三角洲。JS sort()
方法默认情况下使用字典顺序。因此,我们需要针对数字> 9(严重)的此专用回调。
-p+(p=n)
我
标准解决方案:累加总和输入,排序然后比较。也没有实质性的实现技巧。
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];}
投放到Consumer<int[]>
。输出是变异输入。
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];
}
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)
for(;i>0;)l[i-1]=d[i]-d[--i];
(last loop)
for(;i-->0;)l[i]=d[i+1]-d[i];
of the same length. Update to come.
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]);}
.
-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 diff
ed 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.
source
) this doesn't output anything.
diffinv
rather than cumsum
you don't need to prepend zero.
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:])]
Horrible solution.
+=
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.
{[\+](0,|@_).sort.rotor(2=>-1).flat.map(*R-*)}
{ # 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)
}
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
L
's?
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);}
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
}
.+S+M.uP
.+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
$a[0]=1;push@a,$a[-1]+$_ for@F;@a=sort{$a<=>$b}@a;print$a[0]-$_,$"while($_=shift@a)&&@a
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 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
Original solution found by the Code Golf Hackathon participants at the Dyalog '17 User Meeting:
¯2-/l[⍋l←+\0,⎕]
⎕
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
0hYsSd
0 # push 0
h # horizontal concatenate with implicit input
Ys # cumulative sum
S # sort
d # diff (implicit output)
1_-':{x@<x}@+\0,
0, /prepend a 0
+\ /cumulative sum
{x@<x}@ /sort
1_-': /differences list
{i=0{[0];[i]if i+=_}|sort|slide 2|[_2-_1]}
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.
/:~&.(+/\)
"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.