Заповніть послідовність, що збільшується, якомога більше цифр


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, -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, як зазвичай. Я мав на увазі лише те, що нормально вставляти в кінці дуже великі цілі числа, якщо так працює ваш алгоритм.
Захоплення Кальвіна

Відповіді:


11

Haskell , 41 байт

fбере список і повертає список, причому 0 представляють ?s.

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

Виявляється, я використовую той самий алгоритм, що і у відповіді Haskell Ørjan Johansen : спочатку замініть кожне Nullна більше, ніж число зліва ( //.{a___,b_,,c___}:>{a,b,b+1,c}), а потім замініть будь-яке занадто велике число на число праворуч ( //.{a___,b_,c_,d___}/;b>c:>{a,c,c,d}). Щоб розібратися з можливими Nulls на початку списку, ми почнемо, попередньо передбачивши a 0( {0,##}&@@#), зробивши алгоритм, потім видаливши початковий 0( Rest).

Так, я вибрав Nullзамість того Xчи іншого подібного, щоб зберегти буквально один байт у коді (той, який інакше знаходитиметься між комами b_,,c___).


Гм, попередньо 1 ти кажеш? Я використовував 0, через такі речі ?, 2. Я підозрюю, що ви б тоді створили 2, 2замість правильного 1, 2.
Ørjan Johansen

Відмінна точка! На щастя, виправити це легко.
Грег Мартін

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 байт

Збережено 10 байт завдяки Grimy

ε®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: Дійсно це могло :)
Емінья

1
Це ще може! 16 , 15 , 13 .
Гріммі

@Grimy: Нічого, дякую! Цей суфікс-трюк був справді розумним!
Емінья

2

Піп , 25 23 21 байт

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

Вводить дані як кілька аргументів командного рядка, розділених простором. Виводить список результатів по одному номеру на рядок. Спробуйте в Інтернеті! (Я роздував кілька аргументів командного рядка, тому що додати 25 аргументів на TIO було б боляче, але він також працює так, як рекламується.)

Пояснення

Проходимо в два проходи. По-перше, ми замінюємо кожен запуск ?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

Python 2 з NumPy, 163 байти

Збережено 8 байт завдяки @wythagoras

Нулі використовуються для позначення порожніх плям

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 Дякую, добрі поради. Я додав це до коду
Dead Possum

Приємно, але це лише 163 байти.
wythagoras

@wythagoras О, я забув оновити кількість байтів
Dead 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

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

@ msh210 Майже всі ці змінні або зникла, або мають довші назви. Про єдине, що все ще існує і має ту саму мету $!. ( $/існує, але використовується для $1$/[1]та $<a>$/{ qw< a > })
Бред Гілберт 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]]}

По суті той же алгоритм, що і у відповіді Хаскеля Шріяна Йохансена .

  • Припускає? = 0.
  • Вставляє 0 на початку масиву у випадку? на старті.
  • Сканує масив, замінюючи 0 на 1 + попередній елемент.
  • Повертає масив і сканує знову, замінюючи елементи, більші за попередній, попереднім.
  • Перевертає та вирізає перший елемент (доданий 0 з початку).

Для збереження одного байту було використано min або last, оскільки можна припустити, що останнім елементом буде елемент min з урахуванням низхідного роду масиву.


Класна відповідь, ласкаво просимо на сайт! :)
DJMcMayhem

1

TI-Basic (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

Простий порт відповіді Ескена Йохансена 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

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

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 байти

Використовуючи ту саму стратегію, що і Ørjan Johansen.

Використовує 0 у вхідному списку для позначення невідомого var.

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

Спробуйте в Інтернеті!


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.