Điền vào một chuỗi tăng với càng nhiều số càng tốt


29

Một danh sách các số được gọi là tăng đơn điệu (hoặc không tăng) là mọi phần tử đều lớn hơn hoặc bằng phần tử trước nó.

Ví dụ, 1, 1, 2, 4, 5, 5, 5, 8, 10, 11, 14, 14đang tăng đơn điệu.

Đưa ra một danh sách các số nguyên dương tăng đơn điệu có số lượng điểm trống tùy ý biểu thị ?, điền vào các điểm trống bằng các số nguyên dương sao cho càng nhiều số nguyên duy nhất có thể có trong danh sách, nhưng nó vẫn tăng đơn điệu.

Có thể có nhiều cách để thực hiện điều này. Bất kỳ là hợp lệ.

Xuất danh sách kết quả.

Ví dụ: nếu đầu vào là

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

đảm bảo rằng không có các điểm trống, danh sách sẽ tăng đơn điệu

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

và nhiệm vụ của bạn là gán các số nguyên dương cho từng số nguyên để ?tối đa hóa số lượng các số nguyên riêng biệt trong danh sách trong khi vẫn giữ cho nó không tăng.

Một nhiệm vụ không hợp lệ

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

bởi vì, trong khi nó không tăng, nó chỉ có một số nguyên duy nhất hơn đầu vào, cụ thể là 3.

Trong ví dụ này, có thể chèn sáu số nguyên dương duy nhất và giữ cho danh sách không tăng.
Một vài cách có thể là:

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

Một trong hai (và nhiều thứ khác) sẽ là đầu ra hợp lệ.

Tất cả các điểm trống phải được điền vào.

Không có giới hạn trên cho số nguyên có thể được chèn. Sẽ ổn nếu số nguyên rất lớn được in theo ký hiệu khoa học.

Số không không phải là số nguyên dương và không bao giờ được chèn.

Ở vị trí của ?bạn có thể sử dụng bất kỳ giá trị nhất quán đó không phải là một số nguyên dương, chẳng hạn như 0, -1, null, False, hoặc "".

Mã ngắn nhất tính bằng byte thắng.

Thêm ví dụ

[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 *

Có lẽ là một cách tốt hơn để diễn đạt vấn đề có đầu vào nghiêm ngặt, cặp đầu ra để xác minh, sẽ là "Số lượng các số phân biệt cao nhất có thể có trong chuỗi là bao nhiêu". Bằng cách đó, tất cả các câu trả lời sẽ xuất ra cùng một số và làm cho việc đánh giá các trường hợp kiểm tra dễ dàng hơn nhiều
Cruncher

@StewieGriffin Bạn có thể giả sử các giá trị và độ dài danh sách dưới mức tối đa int như bình thường. Tôi chỉ có nghĩa là cuối cùng cũng có thể chèn các số nguyên rất lớn nếu đó là cách thuật toán của bạn hoạt động.
Sở thích của Calvin

Câu trả lời:


11

Haskell , 41 byte

flấy một danh sách và trả về một danh sách, với 0 đại diện cho ?s.

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

Về cơ bản, danh sách quét đầu tiên từ bên trái, thay thế 0 bằng một phần tử so với phần tử trước đó (hoặc 0 khi bắt đầu); sau đó quét từ bên phải giảm các phần tử quá lớn để bằng với phần tử bên phải của chúng.

Hãy thử trực tuyến! (với trình bao bọc để chuyển đổi ?s.)


4

Toán học, 84 byte

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

Hàm thuần túy lấy danh sách làm đối số, trong đó các điểm trống được biểu thị bởi Null(như trong {1, Null, Null, 2, Null}) hoặc bị xóa hoàn toàn (như trong {1, , , 2, }) và trả về một danh sách phù hợp (trong trường hợp này, {1, 2, 2, 2, 3}).

Hóa ra tôi đang sử dụng cùng một thuật toán như trong câu trả lời Haskell của Ørjan Johansen : trước tiên hãy thay thế từng Nullsố nhiều hơn số bên trái ( //.{a___,b_,,c___}:>{a,b,b+1,c}), sau đó thay thế bất kỳ số quá lớn nào bằng số bên phải ( //.{a___,b_,c_,d___}/;b>c:>{a,c,c,d}). Để xử lý Nullcác s có thể ở đầu danh sách, chúng tôi bắt đầu bằng cách thêm một 0( {0,##}&@@#), thực hiện thuật toán, sau đó xóa ký tự ban đầu 0( Rest).

Có, tôi đã chọn Nullthay vì Xhoặc một cái gì đó tương tự để lưu theo nghĩa đen một byte trong mã (một byte sẽ nằm giữa các dấu phẩy b_,,c___).


Hừm, trả trước 1 bạn nói? Tôi đã sử dụng 0, vì những thứ như ?, 2. Tôi nghi ngờ bạn sau đó sẽ sản xuất 2, 2thay vì chính xác 1, 2.
Ørjan Johansen

Điểm tuyệt vời! May mắn là sửa chữa dễ dàng.
Greg Martin

3

C 160

Điều này sẽ không bao giờ chiến thắng nhưng:

#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)}

Nó lấy danh sách từ các đối số dòng lệnh.



3

05AB1E , 31 23 13 byte

Đã lưu 10 byte nhờ Grimy

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

Hãy thử trực tuyến!

Giải trình

ε      ]       # 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

Tại sao điều này chỉ in một phần của đầu ra? Trong ví dụ TIO của bạn, 1 đầu tiên bị thiếu.
Gây tử vong vào

Tôi biết đã được một thời gian và có lẽ nó có thể được chơi gôn nhiều hơn, nhưng -3 byte với một số golf dễ dàng: Cả hai }}có thể ]để tiết kiệm 2 byte; và õ-)Rcó thể )˜Rđể lưu một byte bổ sung.
Kevin Cruijssen

2
@KevinCruijssen: Quả thực là có thể :)
Emigna

1
Nó vẫn có thể! 16 , 15 , 13 .
Grimmy

@Grimy: Wow, cảm ơn! Thủ thuật hậu tố đó thực sự rất thông minh!
Emigna

2

Pip , 25 23 21 byte

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

Đưa đầu vào dưới dạng nhiều đối số dòng lệnh được phân tách bằng dấu cách. Xuất ra danh sách kết quả một số trên mỗi dòng. Hãy thử trực tuyến! (Tôi đã làm mờ điều tranh luận nhiều dòng lệnh bởi vì sẽ rất khó để thêm 25 đối số trên TIO, nhưng nó cũng hoạt động như quảng cáo.)

Giải trình

Chúng tôi tiến hành trong hai lần. Đầu tiên, chúng tôi thay thế mỗi lần chạy ?s trong đầu vào bằng một chuỗi bắt đầu từ số trước đó trong danh sách và tăng thêm một lần mỗi lần:

? 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

Sau đó, chúng tôi lặp lại một lần nữa; đối với mỗi số, chúng tôi in tối thiểu số đó và tất cả các số ở bên phải. Điều này mang lại những con số quá cao để giữ sự đơn điệu.

                      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

Python 2 với NumPy, 163 byte

Đã lưu 8 byte nhờ @wythagoras

Số không được sử dụng để đánh dấu các điểm trống

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:]

Dễ đọc hơn với các bình luận:

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
Một vài cải tiến: if l[a]>l[b]:l[a]=l[b]có thể l[a]=min(l[a],l[b])và sau đó nó có thể ở dòng trước đó. Ngoài ra, điều này có nghĩa là toàn bộ dòng có thể được đặt sau while. Và tôi nghĩ l=input()l=[1]+lcó thể l=[1]+input()(Ngoài ra, nói chung: Nếu bạn sử dụng hai cấp độ thụt lề, bạn có thể sử dụng một khoảng trắng và một tab thay vì một khoảng trắng và hai khoảng trắng trong Python 2 (xem codegolf.stackexchange.com/a/58 ) )
wythagoras 18/03/2017

1
Ngoài ra, bên cạnh dòng cuối cùng có thể là len(z)-i:f(z[i-1],z[i]);i+=1khi bắt đầu với i = 1.
wythagoras 18/03/2017

@wythagoras Cảm ơn bạn, lời khuyên tốt. Tôi đã thêm mã này vào mã
Dead Possum

Đẹp, nhưng nó chỉ có 163 byte.
wythagoras

@wythagoras Ồ, tôi quên cập nhật số byte
Dead Possum

1

PHP, 95 77 71 69 68 byte

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

lấy đầu vào từ các đối số dòng lệnh, in danh sách được phân tách không gian. Chạy với -nr.

phá vỡ

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

$nlà trung thực cho bất kỳ chuỗi nhưng chuỗi trống và "0".
$n>0là trung thực cho các số dương - và chuỗi chứa chúng.


1

Perl 6 , 97 byte

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

Đầu vào là một danh sách các giá trị hoặc một chuỗi được phân tách bằng dấu cách, ?được sử dụng để thay thế cho các giá trị được thay thế.

Đầu ra là một chuỗi phân tách không gian với một khoảng trắng ở cuối.

Thử nó

Mở rộng:

{                       # 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
}

Tôi không biết Perl 6, nhưng trong Perl 5, bạn có thể sử dụng $"thay vì ' 'cạo một byte. Nó có hoạt động ở đây không?
msh210

@ msh210 Hầu như tất cả các biến đó đều biến mất hoặc có tên dài hơn. Về người duy nhất vẫn còn tồn tại và có cùng mục đích là $!. ( $/tồn tại nhưng được sử dụng cho $1$/[1]$<a>$/{ qw< a > })
Brad Gilbert b2gills

1

JavaScript (ES6), 65 byte

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

Bởi vì tôi muốn sử dụng reduceRight. Giải thích: Việc mapthay thế mỗi giá trị giả bằng một giá trị nhiều hơn giá trị trước đó, sau đó reduceRightcông việc trở lại từ cuối đảm bảo rằng không có giá trị nào vượt quá giá trị sau.


1

Q, 63 byte

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

Về cơ bản thuật toán tương tự như câu trả lời Haskell của Ørjan Johansen .

  • Giả sử? = 0.
  • Chèn 0 vào đầu mảng trong trường hợp? khi bắt đầu
  • Quét mảng thay thế 0 bằng 1 + phần tử trước đó.
  • Đảo ngược mảng và quét lại, thay thế các phần tử lớn hơn phần tử trước bằng phần tử trước.
  • Đảo ngược và cắt phần tử đầu tiên ra (thêm 0 từ đầu).

Việc sử dụng min so với lần cuối được sử dụng để lưu một byte, vì có thể giả sử phần tử cuối cùng sẽ là phần tử min được sắp xếp theo thứ tự giảm dần của mảng.


Câu trả lời tuyệt vời, chào mừng đến với trang web! :)
DJMcMayhem

1

TI-Basic (TI-84 Plus CE), 81 byte

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

Một cổng đơn giản của câu trả lời Haskell của Ørjan Johansen cho TI-Basic. Sử dụng 0 là giá trị null. Lấy đầu vào từ L 1 .

Giải trình:

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 byte

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);}}

Sửa đổi mảng đầu vào thay vì trả về một mảng mới để lưu byte.
Sử dụng 0thay vì ?.

Hãy thử trực tuyến.

Giải trình:

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

JavaScript (ES6), 59

Một hàm với một mảng số nguyên là đầu vào. Các điểm trống được đánh dấu bằng0

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

Kiểm tra

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 # (Lõi .NET) , 182 byte

Sử dụng chiến lược tương tự như Ørjan Johansen.

Sử dụng 0 trong danh sách đầu vào để đánh dấu var chưa biết.

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+" ");};

Hãy thử trực tuyến!


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.