가능한 한 많은 숫자로 증가하는 순서를 채우십시오


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입니다.

이 예에서는 6 개의 고유 양수를 삽입하고 목록을 줄이지 않고 유지할 수 있습니다.
몇 가지 가능한 방법은 다음과 같습니다.

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은 양의 정수가 아니며 삽입해서는 안됩니다.

대신에 ?양의 정수가 아닌 임의의 일관된 값과 같은 사용할 수 있습니다 당신 0, -1, null, False, 또는 "".

바이트 단위의 가장 짧은 코드가 이깁니다.

더 많은 예

[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 최대 값 미만이라고 가정 할 수 있습니다. 알고리즘이 작동하는 방식이라면 끝에 큰 정수를 삽입하는 것이 좋습니다.
Calvin 's Hobbies

답변:


11

하스켈 , 41 바이트

f목록을 가져 와서 0을 나타내는 목록을 반환합니다 ?.

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

기본적으로 첫 번째 스캔 목록은 왼쪽에서 0을 이전 요소보다 하나 이상 (또는 시작시 0)으로 바꿉니다. 그런 다음 오른쪽에서 너무 큰 요소를 축소하여 오른쪽에서 스캔합니다.

온라인으로 사용해보십시오! ( ?s 를 변환하는 래퍼 포함 )


4

수학, 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}).

Ørjan Johansen의 Haskell 답변 과 동일한 알고리즘을 사용하고 있음을 알 수 있습니다 . 먼저 Null왼쪽의 숫자 ( //.{a___,b_,,c___}:>{a,b,b+1,c}) 보다 하나 더 많은 숫자 로 바꾸고 너무 큰 숫자는 오른쪽의 숫자 ( //.{a___,b_,c_,d___}/;b>c:>{a,c,c,d})로 바꿉니다. Null목록의 시작 부분에서 가능한을 처리하기 위해 0( {0,##}&@@#) 를 앞에 추가 하고 알고리즘을 수행 한 다음 초기 0( Rest) 를 삭제하여 시작 합니다.

예, 문자 그대로 1 바이트 (또는 쉼표 사이에있는 바이트)를 저장하기 위해 Null대신 X또는 이와 비슷한 것을 선택했습니다 b_,,c___.


흠, 당신이 말하는 1 앞에? 와 같은 이유로 0을 사용했습니다 ?, 2. 나는 당신이 2, 2올바른 대신에 생산할 것이라고 생각합니다 1, 2.
Ørjan Johansen 2016 년

훌륭한 포인트! 다행히 수정이 쉽습니다.
Greg Martin

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

05AB1E , 31 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이 누락되었습니다.
Fatalize

나는 그것이 오래되었다는 것을 알고 있으며, 아마도 더 많은 골프를 쳤을 수도 있지만, 쉬운 골프 를 사용하면 -3 바이트를 }}가질 수 있습니다 . 둘 다 ]2 바이트를 절약 할 수 있습니다 . 그리고 õ-)R될 수 )˜R추가 바이트를 저장합니다.
Kevin Cruijssen

2
@KevinCruijssen : 실제로 가능 :)
Emigna

1
여전히 할 수 있습니다! 도 16 , 15 , 13 .
그리미

@ 그림 : 와우, 고마워! 그 접미사 속임수는 정말 똑똑했습니다!
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 바이트 절약

빈 자리를 표시하는 데 사용되는 0

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+=1i = 1로 시작할 때 마지막 줄 옆에 있을 수 있습니다 .
wythagoras

@wythagoras 감사합니다, 좋은 조언. 나는 이것을 코드에 추가했다
Dead Possum

좋지만 163 바이트입니다.
wythagoras

@ wythagoras 아, 나는 바이트 수를 업데이트하는 것을 잊었다
죽은 Possum

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

펄 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

@ msh210 거의 모든 변수가 사라지거나 더 긴 이름을 갖습니다. 여전히 존재하고 동일한 목적을 가진 유일한 것입니다 $!. ( $/존재하지만 $1$/[1]$<a>→에 사용됨 $/{ qw< a > })
Brad Gilbert b2gills

1

자바 스크립트 (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]]}

본질적으로 Ørjan Johansen의 Haskell answer 와 동일한 알고리즘 입니다.

  • 가정? = 0
  • ?의 경우 배열 시작 부분에 0을 삽입합니다. 시작할 때.
  • 0을 1+ 이전 요소로 대체하여 배열을 스캔합니다.
  • 배열을 되돌리고 다시 스캔하여 이전 요소보다 큰 요소를 이전 요소로 바꿉니다.
  • 첫 번째 요소를 반전시켜 잘라냅니다 (처음부터 0을 더함).

배열의 내림차순으로 마지막 요소가 최소 요소라고 가정 할 수 있기 때문에 min vs last를 사용하여 1 바이트를 저장했습니다.


멋진 답변, 사이트에 오신 것을 환영합니다! :)
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

TI-Basic에 대한 Ørjan Johansen의 Haskell 의 간단한 포트 . 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

Java 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

자바 스크립트 (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 코어) 182 바이트

Ørjan Johansen과 동일한 전략을 사용합니다.

입력 목록에서 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+" ");};

온라인으로 사용해보십시오!


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.