Закрийте нулі у списку


41

Натхненний цим питанням SO

В якості введення вам буде надано не порожній список цілих чисел, де перше значення гарантовано буде не нульовим. Щоб побудувати вихід, перейдіть від початку списку, виводячи по шляху кожне ненульове значення. Коли ви стикаєтесь з нулем, замість цього повторіть значення, яке ви нещодавно додали до виводу.

Ви можете написати програму або функцію, а введення / вихід приймати будь-який зручний формат, який не кодує додаткову інформацію, доки все ще є впорядкована послідовність цілих чисел. Якщо виходить з програми, ви можете надрукувати зворотний новий рядок. За винятком цього нового рядка, ваш результат повинен бути прийнятним для подання вами.

Виграє найкоротший код у байтах.

Випробування

[1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9] -> [1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9]
[1, 0, 0, 0, 0, 0] -> [1, 1, 1, 1, 1, 1]
[-1, 0, 5, 0, 0, -7] -> [-1, -1, 5, 5, 5, -7]
[23, 0, 0, -42, 0, 0, 0] -> [23, 23, 23, -42, -42, -42, -42]
[1, 2, 3, 4] -> [1, 2, 3, 4]
[-1234] -> [-1234]

21
Трохи дрібниць: Назва цієї операції у світі статистики - імпутація LOCF (останнє спостереження, проведене вперед).
Олексій А.

Що станеться, якщо вхід був [0,0]?
Kritixi Lithos

4
@ KριτικσιΛίθος "... де перше значення гарантується не нульовим"
Sp3000

Що робити, якщо вхід є [1,01]? Використовуючи, відповідь Pyth's, порівняйте це та це .
Арктур

@Eridan 01не є дійсним цілим числом на вході Pyth, тому isaac не повинен це враховувати. Інші відповіді можуть приймати подібний вклад, якщо вони хочуть, до тих пір, поки вони будуть послідовними (наприклад, як відповідь isaac ніколи не видасть цей список як вихід)
FryAmTheEggman

Відповіді:


19

Pyth, 6 байт

mJ|dJQ

Демонстрація

m ... Qозначає, що це відображає функцію над входом. Функція, яка відображається, є J|dJ. Це означає J = d or Jв Python, оскільки Jімпліцитність присвоюється наступному значенню при першому використанні. На відміну від Python, вирази присвоєння повертають значення, призначене в Pyth, тому карта повертає кожне наступне значення J, як бажано.


23

Желе , не конкуруючий

3 байти Ця відповідь не є конкурентоспроможною, оскільки вона використовує функції, які відкладають завдання.

o@\

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

Як це працює

o      Take the logical OR of its arguments.
 @     Reverse the argument order of the link to the left.
  \    Do a cumulative reduce, using the link to the left.

6
Мій мозок не може зрозуміти ... Денніс нарешті знайшов спосіб назавжди пограти в гольф. Наче він цього ще не робив. ಠ_ಠ
Addison Crump

1
Пояснення більше не узгоджується з програмою
Кінтопія

18

Рубін, 25 байт

->a{a.map{|x|x==0?a:a=x}}

Це насправді справді зло.

Зокрема, фрагмент x==0 ? a : (a=x).

Якби я використовував будь-яке інше ім'я змінної для a(попереднє ненульове значення) - скажімоlet, - yя повинен був би оголосити його поза межами map(тому y=xщо мав би сферу застосування всередині однієї mapітерації). Це використовувало б чотири символи більше ( y=0;).

Але якщо я використовую ім'я змінної a... так, ви здогадалися. Я фактично переосмислюю аргумент, який ми отримали як вхідний (вихідний масив).

mapбайдуже, оскільки воно дбає лише про первісну цінність речі, про яку вона викликається, тому це насправді працює.


17

Haskell, 21 байт

a%0=a
a%b=b
scanl1(%)

Функція (анонім), яку ми робимо, знаходиться в останньому рядку. Перші два рядки визначають функцію помічника.

scanl1(%) [1,0,2,0,7,7,7,0,5,0,0,0,9]
[1,1,2,2,7,7,7,7,5,5,5,5,9]

Двійкова функція %виводить другий аргумент, якщо тільки він не є 0, в цьому випадку він виводить перший аргумент замість цього. scanl1повторює цю функцію над списком вхідних даних, видаючи результат на кожному кроці.


13

J, 8 байт

{:@-.&0\

Це одинарна функція, яку викликають наступним чином.

   f =: {:@-.&0\
   f 2 0 0 4 0 _1 0
2 2 2 4 4 _1 _1

Пояснення

{:@-.&0\
       \  Map over non-empty prefixes:
   -.      remove all occurrences
     &0    of the number 0 and
{:@        take the last element.

Чи можете ви повторити за абсолютним значенням, а не видаляти 0?
ліртосіаст

@ThomasKwa Це була моя перша спроба. Так {:@(#~|)\, так на один байт довше.
Згарб

13

Сід, 8

/^0$/g
h
  • /^0$/відповідає нулю в рядку - якщо так, gкопіюється простір утримування в простір шаблону
  • h копіює простір шаблону в простір утримування

Цілі лінійки розділені новою лінією. наприклад:

$ printf -- "-1\n0\n5\n0\n0\n7\n" | sed -f zerocover.sed
-1
-1
5
5
5
7
$ 

11

Javascript ES6, 19 байт

s=>s.map(i=>p=i||p)

Просте рішення, проведіть цикл через введення, призначте pпоточному елементу iабо, pякщо iє, 0і виведіть його.

Приклад запуску (призначення анонімної функції f):

>> f([1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9])
<< Array [1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9]

Щоразу, коли я запускаю це, я отримую помилку із
записом

@Downgoat Це тому, що перекладач є лише перекладачем суворого режиму. Якщо ви не запускаєте цей код у суворому режимі, він повинен працювати.
wizzwizz4

@ Wizzwizz4 ооо, г добре
Downgoat

1
@ wizzwizz4 Суворий режим - дурний.
SuperJedi224

1
@ SuperJedi224 Це не дурно. Це дуже корисно; він гарантує, що ваш код не є неоднозначним, і він буде працювати навіть з основним оновленням, не використовує невизначене поведінку і т. д. Але те, що нерозумно, дозволяє це за замовчуванням, оскільки жорсткий режим не визначає спосіб вимкнути себе , і якщо ви не ставите рядок строгого режиму на початку, ви цього не хочете і / або займаєтеся кодом.
wizzwizz4


7

Діалог APL, 12 10 9 байт

(⊃0~⍨,⍨)\

Натхненний J відповіді @ Zgarb.

(⊃0~⍨,⍨)\      Monadic function:
        \      Cumulative reduce by
(⊃0~⍨,⍨)       the dyadic function:
     ,⍨           Arguments concatenated in reverse order
  0~⍨             With zeroes removed
 ⊃                Take the first element

Спробуйте тут .


6

Pyth, 8 байт

t.u|YNQ0

Використання .u(кумулятивне зменшення) від |(Python's or), з базовим випадком 0.


@isaacg Здається, .uце довше, навіть якщо їх Jі Kзав'язали. Це завжди оптимально?
lirtosiast

Це було (принаймні , AFAIK) тут . Зазвичай це допомагає, коли ви хочете отримати всі результати з якихось причин.
FryAmTheEggman

5

Python 2, 29 байт

while 1:x=input()or x;print x

Приймає введення як числа, задані по одному на рядок, і виводить у тому ж форматі. Припиняється з помилкою після фінішної обробки.

Використовуючи характер короткого замикання or, змінна xоновлюється на вхід, за винятком випадків, коли цей вхід дорівнює 0 (що є Falsey), і в цьому випадку воно залишається його поточним значенням. Потім, xдрукується. Зауважте, що оскільки значення першого списку є ненульовим, xвоно не оцінюється в правій частині перед його призначенням.


Це 6 байт у Pyth, і пригнічує помилку:#\nJ|EJ
isaacg

5

Mathematica 38 байт

Узгодження шаблону повторно замінюється ...a,0,...на...a,a...

#//.{b___,a_/;a!=0,0,e___}:>{b,a,a,e}&

5

Матлаб, 41 46 байт

Це надихає мою оригінальну відповідь із такими відмінностями:

  1. Використовуйте логічну індексацію замість nonzeros.
  2. Подвійне логічне заперечення замість порівняння з 0.
  3. Транспонування можна зняти, оскільки вихідний формат є гнучким
  4. Видалення проміжної змінної.

Дякую Тому Карпентеру за пункт 4 та за його пропозицію використовувати програму замість функції; разом це дозволило скоротити 5 байт.

x=input('');u=x(~~x);disp(u(cumsum(~~x)))

Приклад:

>> x=input('');u=x(~~x);disp(u(cumsum(~~x)))
[4 0 3 2 0 5 6 0]
     4     4     3     2     2     5     6     6

Ви можете зберегти один байт, перетворивши його в програму - використовуйте x=input('')замість декларації функції, а disp(u(t)не y=біт. Крім того, ви можете зберегти ще чотири байти, позбувшись tзмінної, поступившись x=input('');u=x(~~x);disp(u(cumsum(~~x)))41.
Том Карпентер

@TomCarpenter Дякую велике! Відредаговано
Луїс Мендо

У мене немає Матлаба, але @(x)x(~~x)(cumsum(~~x))працює в Октаві.
алефальфа

@alephalpha Matlab не дозволяє повторити індексацію.
AlexR


5

Japt, 8 7 байт

N£U=XªU

Досить просто. Бере введення, розділене комами. Спробуйте в Інтернеті!

Необурені і пояснення

N£    U=Xª U
NmXYZ{U=X||U

        // Implicit: N = input, U = first item
NmXYZ{  // Map each item X to:
U=Z||U  //  Set U to (X || U) and return.
        //  If X is non-zero, this sets U to X.
        //  Otherwise, this leaves U as the last non-zero we've encountered.
        // Implicit: output last expression

Неконкурентна 4-байтна версія: ( åкоманда та !-auto-функція додані після виклику)

Nå!ª

Пояснення:

Nå!ª
Nå!||
NåXY{Y||X}

        // Implicit: N = input, U = first item
NåXY{   // Cumulatively reduce N; take each item Y and prev value X,
Y||X}   //  and return Y if it is non-zero; return X otherwise.
        // Implicit: output last expression

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


Зачекайте, ªАБО, а не º? Є ºІ випадково?
caird coinheringaahing

@cairdcoinheringaahing Ні, ºє ((. Їм було призначено значення Unicode, оскільки я виявив потребу в них: P- ªй і ºr - геніальний, однак я можу використовувати це для Japt 2.0 ...
ETHproductions

5

Ява, 78

int[]f(int[]a){for(int i=-1,b=i;++i<a.length;a[i]=b=a[i]==0?b:a[i]);return a;}

Тут ми просто відслідковуємо останній ненульовий показник і заносимо його туди, де це доречно. Здається, це очевидний спосіб зробити це.


5

Пролог (SWI) , 54 байти

[X,0|T]+[X,X|Y]:-[X|T]+[X|Y].
[X|T]+[X|Y]:-T+Y.
[]+[].

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

Пояснення

Я дуже задоволений цією відповіддю.

Спочатку ми кажемо, що порожній список є рішенням порожнього списку:

[]+[].

Тоді ми говоримо, що [X,X|Y]це рішення [X,0|T], якщо видалити другий запис кожного з рішень, що залишилися.

[X,0|T]+[X,X|Y]:-[X|T]+[X|Y].

Нарешті, ми говоримо, що будь-яка річ, що залишилася, є дійсною, якщо вони починаються з однакового значення, а решта двох списків відповідають один одному.

Якщо це пояснення для вас не працює, ось код, перекладений на Haskell:

g(a:0:x)=a:g(a:x)
g(a:x)=a:g x
g x=x

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


Дуже лаконічно! Мені подобається, як деякі функціональні та логічні мови програмування дозволяють зробити такий буквальний переклад правил. Це такий природний спосіб написати це!
ThePlasmaRailgun

4

GolfScript, 10 байт

~{1$or}*]`

Ця програма приймає введення з stdin у вигляді літералу GolfScript масиву (наприклад [1 0 2 0]) і записує свій вихід у stdout у тому ж форматі (наприклад [1 1 2 2]).

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

Функція (взяття та повернення масиву GolfScript) буде на три байти довше, через необхідність загортати його в блок і призначити його символу:

{[{1$or}*]}:f

Звичайно, якщо рахувати лише тіло функції (тобто [{1$or}*]), то я фактично можу зберегти один байт порівняно з окремою програмою.


Можливо, не дивно, що нова, коротша версія вийшла дуже схожою на запис CJam Dennis . Він виграє на один байт, оскільки GolfScript зчитує введення автоматично, і тому для цього не потрібна додаткова команда.
Ільмарі Каронен

4

Minkolang 0,14 , 12 10 байт

$I?.nd?xdN

Спробуйте тут. Введення можна вказати як у запитанні, але без дужок .

Пояснення

$I      Push the length of the input on the stack.
  ?.    If this is 0, stop. Otherwise, continue.

nd        Take number from input and duplicate it.
  ?x      If this number is 0, dump the top of stack.
    dN    Duplicate the top of stack and output as number

Minkolang є тороїдальним, тому ця петля на початку і продовжує тривати, поки не вдариться .і зупиниться.


4

𝔼𝕊𝕄𝕚𝕟, 7 символів / 12 байт

ïⓜa=$⋎a

Try it here (Firefox only).

Пояснення

        // implicit: ï = input array
ïⓜ     // map over input
  a=    // set a to:
    $   // (if element is truthy (not 0)) element itself
     ⋎a // else whatever a was set to before
        // implicit output

4

O , 31 байт

[[I',T%T/]{n#}d]{n.{:V}{;V}?}d]

Це потребує введення, розділеного на ,та виведення того ж списку в [].

7,0,3,0,0,2,-50,0,0 => [7,7,3,3,3,2,-50,-50,-50]

Пояснення:

[] Помістіть результат у масив
 [I ', T% T /] {n #} d] Відформатуйте вхід у масив чисел
                {n. {: V} {; V}?} d Заповніть нулі (див. нижче, як це працює)


17 байт

I~]{n.{:V}{;V}?}d

Приймає введення як список чисел, розділених пробілами, використовуючи позначення постфікса і може обробляти лише одноцифрові шістнадцяткові числа. Негативні знаки мають постфікс _.

5 4 0 0 1 0 0 => 5 4 4 4 1 1 1
A 3 0 0 1 B 0 => 10 3 3 3 1 11 11
67* 0 0 78* 0 => 42 42 42 56 56
67*_ 4 3_ 0 0 => -42 4 -3 -3 -3

Пояснення:

I ~] Вводить вхід у цілий масив
   {} d Для кожного числа вхідних даних
    п. {; V} {: V}? Якщо число 0, натисніть V
                  Якщо ні, встановіть V число

Ви можете зберегти два байти за допомогою I~]{n.{:V}{;V}?}d. Цікаво, чи dварто просто поставити значення на стек замість n...
kirbyfan64sos

Ви впевнені, що O може це впоратися? Я не можу знайти спосіб його передачі -42, що задовольняє вимогу "ваш вихід повинен бути прийнятним вкладом для вашого подання".
манатура

@manatwork У мене є краща версія, яка зараз працює -42, але вона додає дужки навколо виводу.
фаза

4

R, 39 37 33 байт

function(x)zoo::na.locf(x*(x|NA))

Це неназвана функція, яка приймає вектор і повертає вектор. Він вимагає встановлення zooпакета. Зауважте, що його не потрібно zooприєднувати до простору імен, оскільки ми посилаємось на нього безпосередньо.

Назва цієї операції у світі статистики - це імпутація LOCF, де LOCF - останній час спостереження, перенесений вперед. Щоб виконати це в R, ми можемо використовувати na.locfз zooпакету, який замінює NAзначення останнім відомим не NAзначенням. Треба просто замінити нулі на вході NAспочатку s.

Для цього ми використовуємо x|NA, що буде TRUEколи x != 0і в NAіншому випадку. Якщо ми помножимо це на x, TRUEелементи замінюються відповідними елементами xі NAзалишаються NA, тим самим замінюючи всі нулі. Потім це передається, zoo::na.locfщо дає нам саме те, що ми хочемо.

Збережено 4 байти завдяки флоделю!


4

Іржа, 100 байт

fn f(i:&[i64])->Vec<i64>{let(mut o,mut l)=(i.to_vec(),0);
for x in&mut o{if *x==0{*x=l}else{l=*x}};o}

Натрапивши на цей виклик, подумав, що спробую його на своїй улюбленій мові. Спробував використовувати [T]::windows_mut()спочатку, перш ніж з’ясувати, що його не існує . І це насправді може бути довше цього. У будь-якому разі виявляється, що гольф Руст дуже некрасивий і дуже не конкурентоспроможний (особливо з усіма цими гозозданими езотериками!) 1

Новий рядок не включається до облікового запису; це лише там, тому вам не доведеться прокручуватися набік. Це не змінює значення коду.

Безголовки:

fn cover_zeroes(input: &[i64]) -> Vec<i64> {
    let mut output = input.to_vec();
    let mut last_nonzero = 0;
    for item in &mut output {
        if *item == 0 {
            *item = last_nonzero;
        }
        else {
            last_nonzero = *item;
        }
    }
    output
}

[1] Принаймні, це не так погано, як Java.


7
" Принаймні, це не так погано, як Java "? Ахем ... ;)
Геобіц

1
@Geobits О, так. Я розраховував на те, що тобі потрібна public static void mainкотлованна плита ...
Blacklight Shining

3

Чумацький Шлях 1.2.1 , 33 байти

:y;=<:&{~<?{0b_^;:3≤_;}1-}^<Ω!

Це передбачає, що список цілих чисел знаходиться виключно у стеці.


Пояснення

:    : :           :              # duplicate the TOS
 y                                # push the length of the TOS
  ;               ;    ;          # swap the TOS and STOS
   =                              # dump a list to the stack
    < <    <                 <    # rotate the stack leftward
        &{~                }      # while loop
            ?{  _     _ }         # if-else statements
              0     3    1        # push an integer
               b                  # == on the TOS and STOS
                 ^          ^     # pop the TOS without output
                     ≤            # rotate the top N stack elements leftward
                          -       # subtract the TOS from the STOS
                              Ω   # push a list made of the top N stack elements
                               !  # output the TOS

Я майже впевнений, що TOS і STOS означають Top of Stack і Second-to-Top of Stack, це правильно?
Аддісон Кримп

Yep @FlagAsSpam
Zach Gates

3

Джулія, 33 байти

g(x,a=0)=[(i!=0&&(a=i);a)for i=x]

Це функція, gяка приймає масив і повертає масив. Ми починаємо тимчасову змінну aв 0. Для кожного елемента iвходу, якщо iНЕ 0 , то ми відносимо aдо i. Якщо i0, aне змінюється на цій ітерації. Ми використовуємо aяк значення в цьому положенні у вихідному масиві.


3

Perl 6 , 21 байт

*.map: {$_=($^a||$_)}

використання:

# store the Whatever lambda as a subroutine
# just so that we don't have to repeat it
my &code = *.map: {$_=($^a||$_)}

say code [1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9];
# (1 1 2 2 7 7 7 7 5 5 5 5 9)

say [-1, 0, 5, 0, 0, -7].&code;
# (-1 -1 5 5 5 -7)

say ([1, 0, 0, 0, 0, 0],[-1, 0, 5, 0, 0, -7]).map: &code;
# ((1 1 1 1 1 1) (-1 -1 5 5 5 -7))

3

R, 36 байт

function(x)x[cummax(seq(a=x)*(!!x))]

Подивимося, як це працює за допомогою x=

c(1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9)

як приклад. Тут !!xз'явиться логічний (Істинний / Хибний) вектор:

c(T, F, T, F, T, T, T, F, T, F, F, F, T)

Також seq(a=x)дає вектор індексів до тих пір, як x:

c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)

Множимо обидва, даючи:

c(1, 0, 3, 0, 5, 6, 7, 0, 9, 0, 0, 0, 13)

Ми приймаємо сукупний максимум:

c(1, 1, 3, 3, 5, 6, 7, 7, 9, 9, 9, 9, 13)

Нарешті, ми використовуємо цей останній вектор як індекси для отримання x:

c(1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9)


3

Powershell, 32 байти

param($x)$x|%{($t=($_,$t)[!$_])}

$x|%{...}блокує сценарій для кожного елемента в $x. ($_,$t)є масивом поточного елемента $t, і [!$_]означає, що ми використовуємо !$_для індексації в масив. Індекс буде 0(false) для ненульових елементів і 1(true), коли поточний елемент дорівнює нулю, таким $tбуде або поточний елемент, або $t. Круглі дужки оточують вираз призначення, так що його значення випромінюється. Без парантезів було б просто "тихе" завдання $t.


@TimmyD, ти прав, звичайно. Я додав, param($x)що перетворює це на програму. Вихід - це сукупність цілих чисел, які ви можете подати як параметр програмі, наприклад, $a = .\program.ps1 1,2,3,4,0,0,5а потім .\program.ps1 $aпрацює, як очікувалося.
Данько Дурбич

$args|%{($p=($_,$p)[!$_])}- 26 байт за допомогою аргументів $.
TesselilingHeckler

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