防溢出缓冲器


23

背景

如今,程序员似乎无法保持其缓冲水平!错误的常见来源是尝试使用对于缓冲区而言太大的数组索引。您的任务是实现一个缓冲区,将大索引减小到缓冲区可以处理的大小。因为我确定了最适合每个人的最佳方法,所以您将根据我的精确规范实施此缓冲区。

总览

您有一个仅插入的缓冲区,该缓冲区的大小会随着向其添加元素而增加。缓冲区是零索引的,并且也以其当前大小为索引。此挑战的特殊规则是:

  • 在索引i处插入项目意味着要计算jj = i % buffer.length()并将新项目插入列表中第j个项目之后。

唯一的特殊情况是缓冲区为空,因为算术模零不起作用。因此,如果缓冲区当前为空,则新项将为索引0

如果缓冲区只有一个项目,那么您总是在第0个项目之后插入。这只是一般情况的一种情况。

如果缓冲区包含6个项目:[4, 9, 14, 8, 5, 2]并且被告知要10在索引15处插入新项目,则会找到15 % 6 == 3,然后108at索引3之后插入新项,从而得到结果缓冲区为 [4, 9, 14, 8, 10, 5, 2]

问题

编写一个函数或程序,该函数或程序接受正整数的有序列表以及要插入它们的正整数索引。

从空缓冲区开始,然后将指定的整数添加到缓冲区的相应索引处。

完成所有指定的插入之后,输出缓冲区中整数的有序列表。

这是一个代码挑战,所以最短的代码胜出。

输入准则

您可以选择输入列表,但您认为合适。例子:

  • 配对列表: [ [1,1], [2,4], [3,9], [4,16], [5,25]...]
  • 项目列表和索引列表: [1, 2, 3, 4, 5...], [1, 4, 9, 16, 25]
  • 展平: [1, 1, 2, 4, 3, 9, 4, 16, 5, 25 ...]
  • 等等

您可以假设输入始终包含至少一项和相应的索引。

测试用例

从上面看方格:

[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49), (8, 64)] -> [1, 2, 8, 7, 6, 5, 4, 3]

我随机生成了这些:

[(11, 9), (13, 14)] -> [11, 13]
[(1, 18), (11, 7), (3, 35), (16, 22)] -> [1, 11, 16, 3]
[(3, 16), (16, 37), (0, 28), (18, 24)] -> [3, 18, 0, 16]
[(7, 26), (8, 20), (11, 39), (1, 23), (17, 27)] -> [7, 8, 11, 1, 17]
[(15, 35), (17, 7), (16, 15), (1, 13), (2, 6), (11, 34)] -> [15, 17, 1, 2, 16, 11]
[(2, 13), (1, 20), (16, 25), (8, 21), (5, 2), (16, 37), (3, 0)] -> [2, 3, 8, 1, 16, 5, 16]
[(6, 20), (15, 15), (12, 26), (10, 27), (17, 13), (7, 18), (4, 16)] -> [6, 10, 17, 12, 7, 4, 15]
[(18, 9), (5, 34), (15, 4), (12, 29), (2, 5), (7, 0), (7, 10), (16, 38)] -> [18, 7, 15, 2, 16, 5, 7, 12]
[(0, 12), (12, 0), (4, 16), (15, 12), (6, 28), (8, 10), (11, 24), (0, 25)] -> [0, 11, 8, 6, 15, 0, 4, 12]
[(6, 12), (14, 13), (10, 33), (11, 35), (1, 3), (0, 28), (15, 27), (8, 10), (1, 2)] -> [6, 14, 10, 1, 11, 8, 15, 0, 1]
[(2, 29), (19, 30), (18, 17), (13, 3), (0, 21), (19, 19), (11, 13), (12, 31), (3, 25)] -> [2, 13, 3, 11, 0, 12, 19, 18, 19]

Python3参考实现

def f(inputs):
    # `inputs` is a list of pairs
    buff = []
    for item, index in inputs:
        if len(buff) == 0:
            buff.insert(0, item)
        else:
            insert_after = index % len(buff)
            buff.insert(insert_after+1, item)
    return buff

输入可以反接吗?
FlipTack

是的,我认为您可以根据需要灵活地输入信息。
turbulencetoo

Answers:


4

MATL24 22字节

"N?@2)yn\Q:&)@1)wv}@1)

输入是一个矩阵(带有;行分隔符),其中包含第一行中的值和第二行中的索引。

输出是一个列数组,显示为以换行符分隔的数字。

在线尝试!验证所有测试用例,并将每个结果显示在一行上。

说明

"          % Input matrix (implicit). For each column 
  N        %   Number of elements in the stack
  ?        %   If nonzero (true for all iterations but the first)
    @2)    %     Push second element of current column: new index
    yn     %     Duplicate current buffer; push its number of elements
    \      %     Modulo
    Q      %     Add 1
    :&)    %     Split buffer at that point. This gives two pieces, one
           %     of which may be empty
    @1)    %     Push first element of current column: new value
    wv     %     Swap; concatenate all stack. This places the new value
           %     between the two pieces of the buffer
  }        %   Else (this is executed only in the first iteration)
    @1)    %     Push first element of current column: new value
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

8

Perl,37个字节

35个字节的代码+ 2个字节的-lp标志。

splice@F,1+<>%(@F||1),0,$_}{$_="@F"

在线尝试!

实现非常简单,在索引处splice插入数组(请注意处理数组为空的情况)。@F1+<>%(@F||1)@F||1

关于(看似)无与伦比的花括号,只说几句话}{(因为我对此发表了评论,对于不了解Perl的人来说,这很奇怪),这在Perl打高尔夫球中是一个很常见的窍门:
-p标记围绕代码与(大致)while(<>){ CODE } continue { print },(continue在每次迭代后执行)。因此,对于那些无与伦比的程序 }{,我将代码更改为while(<>) { CODE}{ } continue { print }。因此,它会在我的代码之后立即创建一个空块(但这不是问题),并且continuewhile(即已读取所有输入之后)仅执行一次。


3
那真}{让我发疯……
ETHproductions

@ETHproductions我已经习惯了,但是我喜欢向其他人展示它,他们总是认为出问题了!:)(缺点是使我的emacs缩进一团糟。)
Dada

1
}{让我想起了这种错觉
路易斯·门多

是的,我做到了。:-)
丹尼斯

5

ES6(JavaScript), 585753,50字节

打高尔夫球

a=>a.map((e,i)=>b.splice(1+e[1]%i,0,e[0]),b=[])&&b

将一组索引值对作为输入。

编辑

  • 使用&&的返回值,-1字节
  • 已删除|0(因为拼接显然可以很好地处理NaN),-2个字节
  • 制造b=[]第二个“说法”,以地图(),-2字节(THX @ETHproductions!)
  • 将b.length替换为map()索引(i),-3个字节(Thx @Patrick Roberts!)

测试

F=a=>a.map((e,i)=>b.splice(1+e[1]%i,0,e[0]),b=[])&&b

F([[11, 9], [13, 14]])
[ 11, 13 ]

F([[2, 29], [19, 30], [18, 17], [13, 3], [0, 21], [19, 19], [11, 13], [12, 31], [3, 25]])
[ 2, 13, 3, 11, 0, 12, 19, 18, 19 ]

1
很好,我应该尝试非递归方法。我认为您可以做到a=>a.map(e=>...,b=[])&&b
ETHproductions'Jan

2
您可以通过更改e=>(e,i)=>并使用i代替来减去3个字节b.length
Patrick Roberts

@PatrickRoberts这是一个好主意!谢谢 !
Zeppelin

5

Haskell70 69字节

b!(x,i)|b==[]=[x]|j<-1+i`mod`length b=take j b++x:drop j b
foldl(!)[]

在线尝试!用法:foldl(!)[] [(1,5),(2,4),(3,7)]。感谢@nimi,节省了一个字节!

说明:

b!(x,i)                         -- b!(x,i) inserts x into list b at position i+1
 | b==[] = [x]                  -- if b is empty return the list with element x
 | j <- 1 + i `mod` length b    -- otherwise compute the overflow-save insertion index j
     = take j b ++ x : drop j b -- and return the first j elements of b + x + the rest of b
foldl(!)[]                      -- given a list [(1,2),(3,5),...], insert each element with function ! into the initially empty buffer

不计算模数的解决方案:(90字节)

f h t(x,-1)=h++x:t
f h[]p=f[]h p
f h(c:t)(x,i)=f(h++[c])t(x,i-1)
g((x,_):r)=foldl(f[])[x]r

在线尝试!


j<-1+i`mod`length b保存一个字节。
nimi

4

Python 2中64个 62 58 56字节

x=[]
for n,i in input():x[i%(len(x)or 1)+1:0]=n,
print x

感谢@xnor打高尔夫球2个字节!

在线尝试!


您可以(len(x)or 1)代替初始化长度吗?
xnor

寻找更短的方法。无论len(x or[0])-~len(x[1:])领带。
xnor

4

Python 2中62 60个字节

将输入作为成对列表,打印结果。编辑:丹尼斯超越

b=[]
for x,y in input():b.insert(1+y%(len(b)or 1),x)
print b

在线尝试!

这非常简单-遍历输入,将项目插入正确的位置,然后打印结果。决定要插入哪个索引1+y%(len(b)or 1)。这是进行模块化索引的标准方法,or 1用于处理空列表的边缘情况。


3

JavaScript(ES6),60个字节

f=([[q,r],...a],z=[])=>z.splice(r%z.length+1,0,q)+a?f(a,z):z

测试片段


2

V38 40 35字节

这个答案弯曲名单的定义,而不是通常你会使用列表操作语言,但我想用[count]/{regex}我最近加入到V的输入取像[index] [num] [index] [num] ...并喜欢返回[num] [num] [num]

Í ¨ä«© ½/¯ÜdÜ+òhea ±^
Hdd2xdG@"
X

在线尝试!

十六进制转储的2个隐藏字符:

00000000: cd20 a8e4 aba9 20bd 2faf dc64 dc2b f268  . .... ./..d.+.h
00000010: 6561 20b1 161b 5e0a 4864 6432 7864 4740  ea ...^.Hdd2xdG@
00000020: 220a 58                                  ".X

说明

最多dG@"格式化所有\d+ \d+对的代码,以使列表1 2 3 4 5 6最终像

a 2^[^3/\d\+
hea 4^[^5/\d\+
hea 6^[^

然后将dG@"所有代码作为V代码执行,如下所示:

a 2^[                 | insert " 2" and return to command mode
     ^                | LOOP: go to the first number
      3/\d\+          | find the 3rd number (0 indexed)
h                     | move one character left
 e                    | go to the end of the next word
  a 4^[               | append " 4" and return to command mode
       ^5/\d\+        | basically the same as LOOP on, just with different numbers

只是说,非竞争状态仅适用于比挑战更新的语言或语言功能
Kritixi Lithos

啊,谢谢你不知道。我要使其符合标准
nmjcman101

2

PHP,72 92字节

for($b=[];++$i<$argc;)array_splice($b,$b?$argv[$i]%count($b)+1:0,0,$argv[++$i]);print_r($b);

接受从命令行参数展平的输入。用运行-nr


我相当确定这个答案是无效的:我得到了Fatal error: Uncaught DivisionByZeroError: Modulo by zero,修复了该问题,然后尝试1 1 1 2 1 3将其[1=>null]作为输出而不是[1,3,2]
user59178

它仍然会覆盖j+1而不是在后面插入j,不是吗?18 1 7 11 35 3 22 16=> [1,11,16]而不是[1,11,16,3]
user59178'1

@ user59178:哦,我错过了insert关键字。谢谢; 固定。
泰特斯

2

Java 7,125 124字节

import java.util.*;List z(int[]a){List r=new Stack();for(int i=0,q=a.length/2;i<q;)r.add(i<1?0:a[i+q]%i+1,a[i++]);return r;}

接受值的平面列表,后跟索引。对于方格测试用例,输入为new int[] {1, 2, 3, 4, 5, 6, 7, 8, 1, 4, 9, 16, 25, 36, 49, 64}

在线尝试!


1

Mathematica,62个字节

Fold[Insert[#,#2[[1]],Mod[Last@#2,Tr[1^#]]+2/.0/0->-1]&,{},#]&

具有第一个参数的纯函数#应为成对列表。从空列表开始{}Fold使输入列表#具有以下功能:

Insert[                                            Insert
       #,                                          into the first argument
         #2[[1]],                                  the first element of the second argument
                 Mod[                              at the position given by the modulus of
                     Last@#2,                      the second element of the second argument
                             Tr[1^#]               with respect to the length of the first argument
                                    ]+2            plus 2 (plus 1 to account for 1-indexing, plus 1 because we are inserting after that position)
                                       /.          then replace
                                         0/0       Indeterminate
                                            ->     with
                                              -1   negative 1
                                                ]& End of function

1

Perl 6,51个字节

{my @a;.map:{splice @a,(@a??$^b%@a+1!!0),0,$^a};@a}

取平整的输入。


1

Clojure,87个字节

#(reduce(fn[r[v i]](let[[b e](split-at(+(mod i(max(count r)1))1)r)](concat b[v]e)))[]%)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.