尽可能多地填写递增顺序


29

数字列表被称为单调递增(或不递减),因为每个元素都大于或等于它之前的元素。

例如, 1, 1, 2, 4, 5, 5, 5, 8, 10, 11, 14, 14单调增加。

给定正整数的单调递增列表,该整数具有任意数量的空白点,表示为 ?,用正整数填充空点,以使列表中存在尽可能多的唯一整数,但它保持单调递增。

可能有多种方法可以实现此目的。任何有效。

输出结果列表。

例如,如果输入是

?, 1, ?, 1, 2, ?, 4, 5, 5, 5, ?, ?, ?, ?, 8, 10, 11, ?, 14, 14, ?, ?

确保没有空白点的列表将单调增加

1, 1, 2, 4, 5, 5, 5, 8, 10, 11, 14, 14

您的任务是为每个整数分配正整数 ?以使列表中不同整数的数量最大化,同时保持其不变。

一项无效的作业

1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 8, 10, 11, 14, 14, 14, 14, 14

因为,尽管它不减量,但只比输入多一个唯一的整数,即 3

在此示例中,可以插入六个唯一的正整数并保持列表不变。
几种可能的方法是:

1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 8, 8, 10, 11, 12, 14, 14, 15, 16

1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 5, 6, 6, 7, 8, 10, 11, 13, 14, 14, 20, 200

这些(以及许多其他)中的任何一个都是有效的输出。

所有空白点都必须填写。

可以插入的整数没有上限。如果以科学计数法打印非常大的整数也可以。

零不是正整数,切勿插入。

在地方?,你可以使用任何一致的值不是一个正整数,如0-1nullFalse,或""

以字节为单位的最短代码获胜。

更多例子

[input]
[one possible output] (a "*" means it is the only possible output)

2, 4, 10
2, 4, 10 *

1, ?, 3
1, 2, 3 *

1, ?, 4
1, 2, 4

{empty list}
{empty list} *

8
8 *

?
42

?, ?, ?
271, 828, 1729

?, 1
1, 1 *

?, 2
1, 2 *

?, 3
1, 3

45, ?
45, 314159265359

1, ?, ?, ?, 1
1, 1, 1, 1, 1 *

3, ?, ?, ?, ?, 30
3, 7, 10, 23, 29, 30 

1, ?, 2, ?, 3, ?, 4
1, 1, 2, 3, 3, 3, 4

1, ?, 3, ?, 5, ?, 7
1, 2, 3, 4, 5, 6, 7 *

1, ?, 3, ?, 5, ?, ?, 7
1, 2, 3, 4, 5, 6, 7, 7

1, ?, ?, ?, ?, 2, ?, ?, ?, ?, 4, ?, 4, ?, ?, 6
1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 4, 4, 4, 5, 6, 6

98, ?, ?, ?, 102, ?, 104
98, 99, 100, 101, 102, 103, 104 *

解决具有严格的输入,输出对以进行验证的问题的一种更好的方式可能是“序列中最大可能的不重复数是多少”。这样,所有答案将输出相同的数字,并使评估测试用例更加容易
Cruncher

@StewieGriffin您可以像往常一样假定列表值和长度低于int最大值。我的意思是,如果这是算法的工作方式,则可以在末尾插入非常大的整数。
加尔文的业余爱好

Answers:


11

Haskell,41个字节

f获取一个列表并返回一个列表,其中0表示?s。

f=scanr1 min.tail.scanl(#)0
m#0=m+1
_#n=n

基本上,是从左开始的第一个扫描列表,将0替换为前一个元素(或开始的0);然后从右边扫描,减少太大的元素,使其等于右边的元素。

在线尝试!(使用包装器转换?s。)


4

Mathematica,84个字节

Rest[{0,##}&@@#//.{a___,b_,,c___}:>{a,b,b+1,c}//.{a___,b_,c_,d___}/;b>c:>{a,c,c,d}]&

以列表为参数的纯函数,其中空点用表示Null(如{1, Null, Null, 2, Null})或完全删除(如{1, , , 2, }),然后返回合适的列表(在这种情况下为{1, 2, 2, 2, 3})。

事实证明,我使用的是与ØrjanJohansen的Haskell答案相同的算法:首先用Null左数(//.{a___,b_,,c___}:>{a,b,b+1,c})替换每个数字,然后用右数()替换任何太大的数字//.{a___,b_,c_,d___}/;b>c:>{a,c,c,d}。为了Null在列表的开头处理可能的s,我们首先添加一个0{0,##}&@@#),然后执行算法,然后删除初始的0Rest)。

是的,我选择了Null而不是X或类似的方法在代码中按原样保存一个字节(否则将在的逗号之间b_,,c___)。


嗯,您说的是1?我之所以用0,是因为?, 2。我怀疑你会产生2, 2而不是正确的1, 2
与Orjan约翰森

好点!幸运的是,修复很容易。
格雷格·马丁

3

C 160

这将永远不会赢,但:

#define p(x)printf("%d ",x);
i=1,l=0,m=0,n;main(c,v)char**v;{for(;i<c;i++)if(*v[i]==63)m++;else{for(n=atoi(v[i]);m>0;m--)p(l<n?++l:n)p(l=n)}for(;m>0;m--)p(++l)}

它从命令行参数获取列表。



3

05AB1E31 23 13字节

多亏了Grimy,节省了10个字节

ε®X:D>U].sR€ß

在线尝试!

说明

ε      ]       # apply to each number in input
 ®X:           # replace -1 with X (initially 1)
    D>U        # store current_number+1 in X
        .s     # get a list of suffixes
          R    # reverse
           ۧ  # take the minimum of each

为什么这只打印输出的一部分?在您的TIO示例中,前1个丢失。
致命

我知道已经有一段时间了,可能还可以打更多的高尔夫球,但是-3个字节又可以轻松打些高尔夫球:两个}}都可以]节省2个字节。并且õ-)R可以)˜R节省一个额外的字节。
凯文·克鲁伊森

2
@KevinCruijssen:的确可以:)
Emigna '18

1
它仍然可以!161513
Grimmy

@Grimy:哇,谢谢!这个后缀把戏真的很聪明!
Emigna

2

25 23 21字节

Y{Y+a|y+1}MgW PMNyPOy

将输入作为多个以空格分隔的命令行参数。输出结果列表,每行一个数字。在线尝试!(我对多个命令行参数有所误解,因为在TIO上添加25个参数会很麻烦,但它确实也可以像宣传的那样工作。)

说明

我们分两步进行。首先,我们使用?从列表中的前一个数字开始并每次增加一个的序列替换输入中的每一次s:

? 1 ? 1 2 ? 4 5 5 5 ? ? ? ? 8 10 11 ?  14 14 ?  ?
1 1 2 1 2 3 4 5 5 5 6 7 8 9 8 10 11 12 14 14 15 16

然后我们再次循环;对于每个数字,我们将打印最小的数字及其右边的所有数字。这会使太高的数字下降以保持单调性。

                      y is initially "", which is 0 in numeric contexts
                      Stage 1:
 {       }Mg           Map this function to list of cmdline args g:
   +a                  Convert item to number: 0 (falsey) if ?, else nonzero (truthy)
     |                 Logical OR
      y+1              Previous number +1
  Y                    Yank that value into y (it is also returned for the map operation)
Y                      After the map operation, yank the whole result list into y
                      Stage 2:
            W          While loop, with the condition:
               MNy      min(y)
              P         printed (when y is empty, MN returns nil, which produces no output)
                  POy  Inside the loop, pop the leftmost item from y

2

带有NumPy的Python 2,163个字节

@wythagoras节省了8个字节

零用来标记空白点

import numpy
l=[1]+input()
z=numpy.nonzero(l)[0]
def f(a,b):
 while b-a-1:a+=1;l[a]=l[a-1]+1;l[a]=min(l[a],l[b])
i=1
while len(z)-i:f(z[i-1],z[i]);i+=1
print l[1:]

注释更易读:

import numpy
l=[1]+input()           # add 1 to the begining of list to handle leading zeros
z=numpy.nonzero(l)[0]   # get indices of all non-zero values
def f(a,b):             # function to fill gap, between indices a and b
    while b-a-1:
        a+=1
        l[a]=l[a-1]+1   # set each element value 1 larger than previous element
        l[a]=min(l[a],l[b])   # caps it by value at index b
i=1
while len(z)-i:       
    f(z[i-1],z[i])      # call function for every gap
    i+=1
print l[1:]             # print result, excluding first element, added at the begining

1
一些改进: if l[a]>l[b]:l[a]=l[b]可以l[a]=min(l[a],l[b]),然后可以在此之前。此外,这意味着可以将整行放在。之后while。而且我认为l=input()并且l=[1]+l可以是l=[1]+input()(通常,如果使用两个级别的缩进,则可以在Python 2中使用空格和制表符代替空格和两个空格(请参见codegolf.stackexchange.com/a/58) )
wythagoras

1
此外,len(z)-i:f(z[i-1],z[i]);i+=1从i = 1开始时,最后一行的旁边可能是。
wythagoras

@wythagoras谢谢你,好的建议。我已将此添加到代码
死负鼠

不错,但是只有163个字节。
wythagoras

@wythagoras哦,我忘了更新字节数
死负鼠

1

PHP,95 77 71 69 68字节

for($p=1;$n=$argv[++$i];)echo$p=$n>0?$n:++$p-in_array($p,$argv)," ";

从命令行参数获取输入,打印以空格分隔的列表。用运行-nr

分解

for($p=1;$n=$argv[++$i];)   # loop through arguments
    echo$p=                     # print and copy to $p:
    $n>0                            # if positive number
        ?$n                             # then argument
        :++$p                           # else $p+1 ...
            -in_array($p,$argv)         # ... -1 if $p+1 is in input values
    ," ";                       # print space

$n除了空字符串和以外,任何字符串都是真实的"0"
$n>0对于正数和包含它们的字符串是真实的。


1

Perl 6、97字节

{my $p;~S:g/(\d+' ')?<(('?')+%%' ')>(\d*)/{flat(+($0||$p)^..(+$2||*),(+$2 xx*,($p=$2)))[^+@1]} /}

输入是值列表或空格分隔的字符串,?用于代替要替换的值。

输出是一个由空格分隔的字符串,后跟空格。

试试吧

展开:

{                       # bare block lambda with implicit parameter 「$_」

    my $p;              # holds the previous value of 「$2」 in cases where
                        # a number is sandwiched between two replacements

    ~                   # stringify (may not be necessary)
    S                   # replace
    :global
    /
        ( \d+ ' ' )?    # a number followed by a space optionally ($0)

        <(              # start of replacement

          ( '?' )+      # a list of question marks
          %%            # separated by (with optional trailing)
          ' '           # a space

        )>              # end of replacement

        (\d*)           # an optional number ($2)

    /{                  # replace with the result of:

        flat(

          +( $0 || $p ) # previous value or 0
          ^..           # a range that excludes the first value
          ( +$2 || * ), # the next value, or a Whatever star

          (
            +$2 xx *,   # the next value repeated endlessly

            ( $p = $2 ) # store the next value in 「$p」
          )

        )[ ^ +@1 ]      # get as many values as there are replacement chars
    } /                 # add a space afterwards
}

我不了解Perl 6,但是在Perl 5中,您可以使用$"而不是' '剃一个字节。在这里行吗?
msh210 '17

@ msh210几乎所有这些变量都消失了,或者具有更长的名称。关于唯一仍然存在并具有相同目的的是$!。($/存在,但用于$1$/[1]$<a>$/{ qw< a > }
Brad Gilbert b2gills

1

JavaScript(ES6),65个字节

a=>a.map(e=>a=e||-~a).reduceRight((r,l)=>[r[0]<l?r[0]:l,...r],[])

因为我想用reduceRight。说明:map用每个伪造的值替换前一个伪造的值,然后reduceRight从头开始进行工作,以确保没有任何值超过下一个值。


1

Q,63字节

{1_(|){if[y>min x;y-:1];x,y}/[(|){if[y=0;y:1+-1#x];x,y}/[0,x]]}

本质上与ØrjanJohansen的Haskell答案相同的算法。

  • 假设?= 0。
  • 如果是?,则在数组的开头插入0。一开始。
  • 扫描将0替换为1 + previous元素的数组。
  • 反转数组并再次扫描,将大于先前元素的元素替换为先前元素。
  • 反转并切出第一个元素(从开头添加的0)。

使用min vs last用于节省一个字节,因为可以假定数组的降序排列,最后一个元素将是min元素。


很酷的答案,欢迎光临本站!:)
DJMcMayhem

1

TI基本(TI-84 Plus CE),81字节

not(L1(1))+L1(1→L1(1
For(X,2,dim(L1
If not(L1(X
1+L1(X-1→L1(X
End
For(X,dim(L1)-1,1,-1
If L1(X)>L1(X+1
L1(X+1→L1(X
End
L1

ØrjanJohansen的Haskell对TI-Basic的简单回答。使用0作为空值。从L 1接受输入。

说明:

not(L1(1))+L1(1→L1(1 # if it starts with 0, change it to a 1
For(X,2,dim(L1     # starting at element 2:
If not(L1(X              # if the element is zero
1+L1(X-1→L1(X            # change the element to one plus the previous element
End
For(X,dim(L1)-1,1,-1 # starting at the second-last element and working backwards
If L1(X)>L1(X+1           # if the element is greater than the next
L1(X+1→L1(X               # set it equal to the next
End
L1                   # implicitly return

1

爪哇8,199个 164字节

a->{for(int l=a.length,n,j,x,i=0;i<l;)if(a[i++]<1){for(n=j=i;j<l;j++)if(a[j]>0){n=j;j=l;}for(j=i-3;++j<n-1;)if(j<l)a[j+1]=j<0?1:a[j]+(l==n||a[n]>a[j]|a[n]<1?1:0);}}

修改输入数组,而不是返回一个新的数组以节省字节。
0代替?

在线尝试。

说明:

a->{                      // Method with integer-array parameter and no return-type
  for(int l=a.length,     //  Length of the input-array
      n,j,x,              //  Temp integers
      i=0;i<l;)           //  Loop `i` over the input-array, in the range [0, length):
    if(a[i++]<1){         //   If the `i`'th number of the array is 0:
                          //   (And increase `i` to the next cell with `i++`)
      for(n=j=i;          //    Set both `n` and `j` to (the new) `i`
          j<l;j++)        //    Loop `j` in the range [`i`, length):
        if(a[j]>0){       //     If the `j`'th number of the array is not 0:
          n=j;            //      Set `n` to `j`
          j=l;}           //      And set `j` to the length to stop the loop
                          //    (`n` is now set to the index of the first non-0 number 
                          //     after the `i-1`'th number 0)
      for(j=i-3;++j<n-1;) //    Loop `j` in the range (`i`-3, `n-1`):
        if(j<l)           //     If `j` is still within bounds (smaller than the length)
          a[j+1]=         //      Set the `j+1`'th position to:
            j<0?          //       If `j` is a 'position' before the first number
             1            //        Set the first cell of the array to 1
            :             //       Else:
             a[j]+        //        Set it to the `j`'th number, plus:
              (l==n       //        If `n` is out of bounds bounds (length or larger)
               ||a[n]>a[j]//        Or the `n`'th number is larger than the `j`'th number
               |a[n]<1?   //        Or the `n`'th number is a 0
                1         //         Add 1
               :          //        Else:
                0);}}     //         Leave it unchanged by adding 0

0

Python 2中144个 124 119字节

l=input()
for n in range(len(l)):a=max(l[:n]+[0]);b=filter(abs,l[n:]);b=len(b)and b[0]or-~a;l[n]=l[n]or a+(b>a)
print l

在线尝试!


0代替?


b=filter(abs,l[n:])等于b=l[n:]
死负鼠

@DeadPossum filter(abs ...过滤掉所有0
ovs

哦,那去除了零,我明白了
死负鼠

0

JavaScript(ES6),59

以整数数组作为输入的函数。空点标有0

a=>a.map((v,i)=>v?w=v:(a.slice(i).find(x=>x)<=w?w:++w),w=0)

测试

var F=
a=>a.map((v,i)=>v?w=v:(a.slice(i).find(x=>x)<=w?w:++w),w=0)

;[[2, 4, 10]
,[1, 0, 3]
,[1, 0, 4]
,[]
,[8]
,[0]
,[0, 0, 0]
,[0, 1]
,[0, 2]
,[0, 3]
,[45, 0]
,[1, 0, 0, 0, 1]
,[3, 0, 0, 0, 0, 30]
,[1, 0, 2, 0, 3, 0, 4]
,[1, 0, 3, 0, 5, 0, 7]
,[1, 0, 3, 0, 5, 0, 0, 7]
,[1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 4, 0, 0, 6]
,[98, 0, 0, 0, 102, 0, 104]]
.forEach(a=>{
  console.log(a+'\n'+F(a))
})


0

C#(.NET Core),182字节

使用与ØrjanJohansen相同的策略。

在输入列表中使用0标记未知变量。

l=>{if(l[0]<1)l[0]=1;int j;for(j=0;j<l.Length;j++)l[j]=l[j]==0?l[j-1]+1:l[j];for(j=l.Length-2;j>=0;j--)l[j]=l[j]>l[j+1]?l[j+1]:l[j];foreach(var m in l) System.Console.Write(m+" ");};

在线尝试!


0

Perl -p 5,99个字节

s,(\d+ )?\K((\? )+)(?=(\d+)),$d=$1;$l=$4;$2=~s/\?/$d<$l?++$d:$l/rge,ge;($d)=/.*( \d+)/;s/\?/++$d/ge

在线尝试!

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.