维修范围


30

给定输入的正整数列表,其中一些被替换为0,输出列表,其中包含已更改为0替换的缺失数字。

输入列表的特征:

  • 列表的长度始终至少为2。

  • 让我们将输入列表定义为a,将“原始列表”(即数字替换为0s 之前的列表)定义为b。对于任何一个na[n]b[n]0

  • 对于任何一个nb[n]b[n-1] + 1b[n-1] - 1。也就是说,每个索引中的数字b始终会1从其前一个索引开始改变。当然,第一个要素是免除此规则。

  • 对于in中的每一次零运行a(即用替换连续的元素 0),x代表运行开始的索引并y 代表结束,a[x-1]to a[y+1]总是单独增加或单独减少。因此,只有一种可能的方法来填充零。

    • 这也意味着数组的第一个或最后一个元素都不能为零。

用更简单的术语来说,要填充零位,只需将其替换为从前一个数字到后一个数字的范围即可。例如,输入

1 2 0 0 0 6 7

必须输出

1 2 3 4 5 6 7

因为这是,所以以字节为单位的最短代码将获胜。

测试用例:

In                      Out
-----------------------------------------------------
1 0 0 0 5 6 0 4 0 0 1 | 1 2 3 4 5 6 5 4 3 2 1
7 6 0 0 3 0 0 0 7 0 5 | 7 6 5 4 3 4 5 6 7 6 5
1 0 3 0 5 0 3 0 5 0 7 | 1 2 3 4 5 4 3 4 5 6 7
14 0 0 0 0 0 0 0 0 23 | 14 15 16 17 18 19 20 21 22 23

而不是0我们的程序可以采用另一个值,例如null吗?
Downgoat '16

@Downgoat不,缺少的数字必须以给出0
Doorknob

Answers:


15

JavaScript(ES6),72 66 64 54 53字节

@Neil节省了12个字节!

@IsmaelMiguel节省了1个字节

a=>a.map((l,i)=>l?b=l:b+=a.find((q,r)=>r>i&&q)>b||-1)

非常适合JavaScript。


在线尝试(所有浏览器都可以使用)

说明

a=>  // Function with arg `a`
  a.map((l,i)=>  // Loop through input
    l?             // If nonzero
      b=l          // Set `b` to current number
    :a.find((q,r)=>r>i&q) // Otherwise look for the next nonzero number
     >b?           // If it's increased since nonzero last number   
       ++b:--b)    // Increasing? increase `b` (the previous nonzero number)
                   // otherwise decrease `b`

1
我认为这a.find((q,r)=>r>i&&q)>b?++b:--bb+=a.find((q,r)=>r>i&&q)>b||-1
Ismael Miguel

@IsmaelMiguel太聪明了,谢谢!
Downgoat '16

别客气。我很高兴为您解决。
Ismael Miguel

我认为您可以用&替换&&(只是注意到您在解释中有一个&,在回答中有两个)
Charlie Wynn

7

MATL,11 12字节

fGXzGn:3$Yn

与该语言/编译器的当前版本(13.0.0)一起使用。

在线尝试!

f        % implicitly input array. Indices of nonzero elements (*)
GXz      % push input and get its nonzero elements (**)
Gn:      % vector [1,2,...,n], where n is input length (***)
3$Yn     % interpolate at positions (***) from data (**) defined at positions (*)

7

Haskell,68 61 58字节

g(a:b:r)=[a..b-1]++[a,a-1..b+1]++g(b:r)
g x=x
g.filter(>0)

用法示例:g.filter(>0) $ [7,6,0,0,3,0,0,0,7,0,5]-> [7,6,5,4,3,4,5,6,7,6,5]

工作原理:从输入中删除零,然后调用g。我们a是第一个和b其余的名单,然后第二个元素。将列表a从上到下(b-1a下到b+1上)连接在一起(其中一个将为空),并递归调用a

编辑:@Zgarb保存3个字节。谢谢!


6

Mathematica,59个字节

#//.{a___,x_,0..,y_,b___}:>{a,##&@@Range[x,y,Sign[y-x]],b}&

测试用例

%[{1,0,3,0,5,0,3,0,5,0,7}]
(* {1,2,3,4,5,4,3,4,5,6,7} *)

4

Perl,47 45 44 39 37字节

包括+1的 -p

s%\S+%$p+=/\G(0 )+/?$'<=>$p:$&-$p%eg

期望在stdin上列出。示例:echo 1 0 3 0 1 | perl -p file.pl


我看到一些粘贴在这里的副本.. ;-)顺便说一句。
肯尼

3

果冻12 11字节

ḢWW;ḟ0Ṫr¥\F

在线尝试!

备用版本,8字节(非竞争)

不幸的是,pop在此挑战之前的最新版本中,Jelly's 并没有迭代。此问题已得到修复,以下内容在当前版本中适用。

ḟ0Ṫr¥\FḊ

在线尝试!

怎么运行的

ḢWW;ḟ0Ṫr¥\F  Main link. Input: A (list)

Ḣ            Pop the first element of A. Let's call it a.
 WW          Yield [[a]].
   ;         Concatenate with the popped A.
             This wraps the first element of A in an array.
    ḟ0       Filter; remove all zeroes.
        ¥    Create a dyadic chain:
      Ṫ        Pop the last element of the left argument.
       r       Call range on the popped element and the right argument.
         \   Reduce the modified A by this chain.
          F  Flatten the resulting list of ranges.

在备用版本中,ḢWW;则不必要。但是,由于第一个元素在弹出之前被强制转换为可迭代,因此实际上并未对其进行修改。最终将删除第一个元素的重复项。


3

视网膜,39 34 31字节

@Martin节省了3个字节。

+`1(1*) (?= +((1)\1)?)
$0$1$3$3

接受输入并给出一元输出。

该代码使用迭代填充每个空白位置(0)previous_number - 1 + 2 * if_next_nonzero_number_biggerprevious_number - 1$1并且if_next_nonzero_number_bigger$3

使用十进制I / O时,代码为51字节长,您可以在在线解释器中看到所有测试用例


您可以通过1在前瞻中省略第一个字节来保存另一个字节。
Martin Ender

@MartinBüttner对,已编辑。
randomra

2

GNU Sed(exec使用bash扩展名),61

得分包括+1,可供-r选择。

:
s/( 0)+ /../
s/\w+..\w+/{&}/
s/.*/bash -c 'echo &'/e
/ 0/b
  • 查找的运行0并替换它们..
  • 将括号括在端点编号周围,以创建bash括号扩展,例如{1..4}本地端点。bash括号扩展好处在于,无论起始或结束都较大,生成的序列将始终在正确的方向上运行。
  • 使用命令的e选项来s调出bash来评估该大括号扩展
  • 如果0找到更多,请跳回开始。

Ideone。


2

Python 2,195111字节(感谢Alex!)

t=input()
z=0
for i,e in enumerate(t):
 if e:
  while z:t[i-z]=e+z if l>e else e-z;z-=1
  l=e
 else:z+=1
print t

输入:必须[list]为ints
输出:必须[list]为ints


对于那个很抱歉!固定。感谢您的注意。
vageli

别担心。不错的解决方案。:)您可以使用this将其压缩到112个字节,这与您的方法相同,只是打了一点球。在这里,我们还提供了一些有关使用Python打高尔夫球的技巧。
Alex A.

1

Perl,85 82字节

包括+1 -p

s/(\d+)(( 0)+) (\d+)/$s=$1;$e=$4;$_=$2;$c=$s;s!0!$c+=$e<=>$s!eg;"$s$_ $e"/e&&redo

期望在stdin上列出。范例:echo 1 0 3 0 1 | perl -p file.pl

这使用了嵌套的正则表达式。有点可读:

s/(\d+)(( 0)+) (\d+)                  # match number, sequence of 0, number
 /
    $s=$1;                            # start number
    $e=$4;                            # end number
    $_=$2;                            # sequence of ' 0'
    $c=$s;                            # initialize counter with start number
    s!0! $c += $s <=> $e !eg          # replace all 0 with (in|de)cremented counter
    "$s$_ $e"                         # return replacement
 /e
&& redo                               # repeat until no more changes.

1

Python 2,92 88字节

(已删除中间变量)

t=filter(bool,input())
print sum([range(o,p,cmp(p,o))for o,p in zip(t,t[1:])],[])+t[-1:]

1

Pyth,17个字节

u+G+treGHHfTtQ[hQ

工作方式:

u                 reduce
              [hQ     seed: the first element of input, in a list
                      iterable:
          tQ              all except the first element of input
        fT                remove if 0
                      lambda: G is the list to be returned, H is the current item
 +G                       append to return list
    reGH                  a range from the last element of the return list and the current item
   +                      concatenated with
        H                 the last item (this step forms a bidirectional inclusive list)

换句话说:从输入中删除所有零,然后在每个元素之间插入一个互斥范围。对于仅相隔一个的元素,此范围为零长度。



1

Vim:231个按键命令

请注意,字符前面的任何^表示您应在键入该字符时保持控制

mbomayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0wmbyiwo@f @d^V^[@z ^["fc0"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0dd`bAe^[0@e 

步骤,以便您也可以运行它!

  1. 将行复制到Vim
  2. 类型 :s/\^V/<Ctrl-V><Ctrl-V>/g并按回车键(两个字母应该给您一个蓝色的^ V)
  3. 类型 :s/\^R/<Ctrl-V><Ctrl-R>/g并按Enter键(你应该可以看到蓝色的^现在卢比)
  4. 类型 :s/\^X/<Ctrl-V><Ctrl-X>/g并按Enter键(你应该可以看到蓝色的^两个X现在)
  5. 类型 :s/\^O/<Ctrl-V><Ctrl-O>/g,然后按Enter
  6. 类型 :s/\^A/<Ctrl-V><Ctrl-A>/g,然后按Enter
  7. 类型 :s/\^\[/<Ctrl-V><Ctrl-[>/g并按Enter键(此命令是略有不同,因为我需要逃避[)
  8. 类型 0"yy$。该命令现在存储在y寄存器中
  9. 在一行上设置输入,然后运行 @y

如果有人知道共享命令的更好方法,请告诉我。我知道这很冗长,但这是我能想到的最好的方法。

输入输出

输入字符串应在文件的任何行上单独存在。1 0 0 4 3 0 0 0 7

输出将简单地覆盖输入字符串1 2 3 4 3 4 5 6 7

说明

算法

  1. 从非零数字开始,请确保它不是最后一个数字
  2. 查找下一个非零数字
  3. 采取他们的区别。如果答案是否定的,则应递减以修复范围,否则,请递减以修复范围。
  4. 返回第一个字符,并通过递增/递减前一个数字来替换每个零。
  5. 重复直到找到最后一个字符

使用的宏

@e-检查结束。最后一个数字将附加一个e。如果光标下方的数字以e结尾,请删除e并停止执行。否则,使用@b开始插补循环。

mbyiwo^R"Exe@b^[0fel"ty2ldd`b@t

@b-开始插补循环。将数字保存在光标下以进行减法运算(@s),然后找到下一个非零项(@f​​)

mayiwo^R"^V^X ^["sy0dd`a@f

@s-存储要在@d中使用的减法命令。它只是插值步骤开始时的数字在(val)^X哪里(val)。这是通过@b命令设置的。

@f-查找下一个非零项。将当前值写入未命名的寄存器,然后@f @d在下一行写入,然后运行@z。如果数字为零,则将重复此命令,否则为@d。

wmbyiwo@f @d^[@z

@z-如果未命名的寄存器为0,则有条件执行。该命令期望在格式为的新行上有两个命令command1 command2。如果未命名的寄存器为0,command1则执行,否则command2执行。请注意,两个命令都不能有任何空格。

 IB0 B^R" ^OWB0 ^OA B0^[0*w"tyiWdd`b@t`

@t-临时命令寄存器。在执行之前,将各种命令存储一小段时间。主要用于if语句中。

@d-确定插补方向。从光标下方的数字中减去序列中的第一个数字(使用@s)。如果结果为负,则插值必须递减,以便将^ X保存到@a。否则,我们应该增加,以便^ A保存到@a。保存后,返回到该插补循环的开始并运行@i进行实际插补

yiwo^V^X^R"^[0l@sa^V^A-^[0f-"ayhdd`a@i

@a-存储^A^X在插值步骤中递增或递减。这是通过@d命令设置的。

@i-内插。将当前位置的号码复制到@x,然后移至下一个号码。如果该数字为零,则将其替换为@x并运行@a以正确地上下修改它,然后重复此命令。如果数字不为零,则说明插值周期已结束。应该以该数字作为开头来开始一个新的,所以运行@e以检查结束并再次运行。

"xyiwwmbyiwocw^V^Rx^V^[@a@i @e^[@z

@x-临时存储寄存器。在插值命令(@i)中使用

击键

mbo :Set b mark to current position and open a new line below to write macros
mayiwo^V^R"^V^V^V^X ^V^["sy0dd`a@f ^["bc0 :Write to @b and reset line

yiwo^V^V^V^X^V^R"^V^[0l@sa^V^V^V^A-^V^[0f-"ayhdd`a@i ^["dc0 :Write to @d and reset line

mbyiwo^V^R"Exe@b^V^[0fel"ty2ldd`b@t ^["ec0 :Write to @e and reset line

wmbyiwo@f @d^V^[@z ^["fc0 :Write to @f and reset line

"xyiwwmbyiwocw^V^V^V^Rx^V^V^V^[@a@i @e^V^[@z ^["ic0 :Write to @i and reset line

IB0 B^V^R" ^V^OWB0 ^V^OA B0^V^[0*w"tyiWdd`b@t ^["zd0 :Write to @z and reset line

dd`b :Delete this line and move cursor back to original line

Ae^[ :Append an e to the last number

0@e  :Move to the beginning of the line and run

0

Python 3.5,159个字节

递归解决方案

def f(s):
 h=s[0]
 g=lambda s,h,v:h*(h[-1]==s[0])if len(s)==1else(g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v))*(s[0]==0 or h[-1]==s[0])
 return g(s,[h],1)

不打高尔夫球

def f(s):
    h=s[0]
    def g(s,h,v):
        if len(s)==1:
            if h[-1]!=s[0]:
                r=[]
            else:
                r=h
        else:
            if s[0]==0:
                r=g(s[1:],h+[h[-1]+v],v)
            elif h[-1]!=s[0]:
                r=[]
            else:
                r=g(s[1:],h+[h[-1]-v],-v)+g(s[1:],h+[h[-1]+v],+v)
        return r
return g(s,[h],1)

在golfed的解决方案,我用事实更换条件h*True=hh*False=[]

结果

>>> f([7, 6, 0, 0, 3, 0, 0, 0, 7, 0, 5])
[7, 6, 5, 4, 3, 4, 5, 6, 7, 6, 5]

0

Perl 6、54个字节

{$_=$^a;1 while s/:s(\d+) 0 + (\d+)/{+~$0...+~$1}/;$_}

0

MATLAB,39 38 37字节

@(a)interp1(find(a),a(a>0),find(a/0))

线性插值的匿名函数afind(a)是中的非零元素索引的数组,a并且a(a>0)是正值。由于朋友的>而不是的建议,节省了1个字节~=

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.