Розширення бактерій


25

Колонії бактерій , мічені 1через 9живі на сегменті однаково віддалені один від одного клітин, причому порожні клітинки позначені0

0 0 2 0 0 0 1 2 0 0 3 3 0 0

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

t=0:  0 0 2 0 0 0 1 2 0 0 3 3 0 0
t=1:  0 2 2 2 0 1 1 2 2 3 3 3 3 0
t=2:  2 2 2 2 2 1 1 2 2 3 3 3 3 3  

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

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

Супутнє: Закрийте нулі у списку . (Колонії поширюються лише праворуч.)

Тестові приклади: вихід нижче вводу.

0 0 2 0 0 0 1 2 0 0 3 3 0 0
2 2 2 2 2 1 1 2 2 3 3 3 3 3

7 0 3 0 0 0 0 0 8 0 9 1
7 7 3 3 3 8 8 8 8 9 9 1

5 0 3 0 0 0
5 5 3 3 3 3

7 7 1
7 7 1

1 0 1
1 1 1

Відповіді:


14

JavaScript (ES6), 66 62 байт

a=>a.map(_=>a=a.map((c,i)=>c||Math.max(a[i-1]|0,a[i+1]|0)))&&a

Пояснення

a=>                 // a = input as array of numbers
  a.map(_=>         // loop for the length of a, this ensures the end is always reached
    a=a.map((c,i)=> // update a after to the result of t, for each cell c of index i
      c||           // keep the cell if it is not 0
        Math.max(   // else set the cell to the max value of:
          a[i-1]|0, //     the previous cell (or 0 if i - 1 less than 0),
          a[i+1]|0  //     or the next cell (or 0 if i + 1 greater than the length of a)
        )
    )
  )
  &&a               // return a

Тест


10

Піт, 18 байт

um|@d1eSd.:++0G03Q

Тестовий набір

Вводиться як список цілих чисел.

За суті, це використовується не застосовується до циклу збіжності u. Він застосовує оновлення шляхом формування всіх списків кожної комірки та двох комірок з обох сторін, а потім оновлення кожної нульової комірки до максимуму її сусідів.

um|@d1eSd.:++0G03Q
                      Implicit: Q = eval(input())
u                Q    Apply the following until convergence, starting with G = Q.
           ++0G0      Pad G with zeros on either side.
         .:     3     Form all 3 element substrings.
                      Now, for each element of G, we have a list of the form
                      [previous, current, next]
 m                    Map over this list
  |@d1                The current element, if it's nonzero
      eSd             Else the max of the list.

8

Математика, 77 байт

Не дуже конкурентоспроможний у порівнянні з рішенням алефальфи //., але я вважав, що проблема, що стосується повинна CellularAutomatonвідповісти:

CellularAutomaton[{If[#2<1,Max@##,#2]&@@#&,{},1},{#,0},{{{l=Length@#}},l-1}]&

Функція приймає тону параметрів ... Давайте назвемо їм кілька назв:

CellularAutomaton[{f,n,r},{i,b},{{{t}},d}]

Ось що вони роблять:

  • r- це діапазон правила, тобто він визначає, скільки сусідів вважається за оновлення. Ми хочемо одного сусіда з кожного боку, тому використовуємо 1.
  • nзазвичай це число або список кольорів (різні типи комірок), але якщо ми задаємо правило як власну функцію замість номера правила, це повинно бути {}.
  • f- це функція, що визначає правило оновлення. Він бере список з 3 комірок (якщо r = 1) і повертає новий колір для середньої комірки.
  • iє початковою умовою. Це вхід.
  • bє фоном. Якщо цього не вказано, CellularAutomatonвикористовуються періодичні межі, яких ми не хочемо. Натомість використання 0накладає мертву граничну умову.
  • t- кількість разів для імітації. Нам не потрібно більше кроків, оскільки вхід широкий, тому що після цього бактерії зійдуться, значить t = Length@#. Зазвичай CellularAutomatonповертає всі проміжні кроки. Ми можемо цього уникнути, загорнувшись tу два списки.
  • dвизначає, які комірки представлені у висновку. За замовчуванням ми отримаємо всі комірки, на які може вплинути правило (це t*rдодаткові комірки на будь-якому кінці вводу). Ми даємо це l-1, тому що це одна з небагатьох ситуацій у Mathematica, де використовується індекс на основі нуля.

6

Хаскелл, 86 83 81 79 73 71 байт

(0#r)l=max r l
(o#_)_=o
p!_=zipWith3(#)p(0:p)$tail p++[0] 
id>>=foldl(!)

Приклад використання: id>>=foldl(!) $ [7,0,3,0,0,0,0,0,8,0,9,1]-> [7,7,3,3,3,8,8,8,8,9,9,1].

Нічого багато для пояснення: якщо комірка дорівнює 0, візьміть максимум сусідніх елементів. Повторіть тривалість введення часу. Для цього я повторюю xчерез, foldlале ігнорую другий аргумент у p.

Редагувати: @Mauris знайшов 6 байтів для збереження, а @xnor ще два. Спасибі!


Ви можете замінити h pз p!_потім замінити (const.h)з , (!)щоб зберегти 6 байт.
Лінн

@Mauris: Розумний. Дуже дякую!
німі

@nimi Я думаю, що останній рядок анонімізований на id>>=foldl(!).
xnor

@xnor: так, це так! Добре помічений!
німі

4

CJam, 27 24 байт

{_,{0\0++3ew{~@e>e|}%}*}

Перевірте це тут.

Це натискає неназваний блок, який перетворює список на стеку в новий список.

Пояснення

_,       e# Duplicate the input and get its length N.
{        e# Run this block N times (convergence won't take that long)...
  0\0++  e#   Wrap the list in two zeroes.
  3ew    e#   Get all sublists of length 3.
  {      e#   Map this block onto each sublist...
    ~    e#     Dump all three elements on the stack.
    @    e#     Pull up the left neighbour.
    e>   e#     Maximum of both neighbours.
    e|   e#     Logical OR between centre cell and maximum of neighbours.
  }%
}*

Збіжність убік - це приємний трюк
Луїс Мендо

1
... яку я безсоромно позичив :-)
Луїс Мендо

4

J, 24 23 байти

(+=&0*(0,~}.)>.0,}:)^:_

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

   ((+=&0*(0,~}.)>.0,}:)^:_) 0 1 5 0 0 0 6
1 1 5 5 6 6 6

Метод подібний до рішення Мауріса .

(                  )^:_ repeat until change
               0,}:     concat 0 and tailless input
      (0,~}.)           concat headless input and 0
             >.         elementwise maximum of the former two lists
  =&0*                  multiply by input_is_0 (zeroing out the list at nonzero input positions)
 +                       add to input

Спробуйте його онлайн тут.

1 байт збережено завдяки Zgarb.


3

Математика, 77 74 66 62 байт

Збережено 12 байт завдяки Мартіну Бюттнеру.

#//.i_:>BlockMap[If[#2<1,Max@##,#2]&@@#&,Join[{0},i,{0}],3,1]&

3

J, 33 байти

3 :'y+(y=0)*>./(_1,:1)|.!.0 y'^:_

Трохи довше, ніж мені хотілося б.

3 :'                         '^:_   Repeat a "lambda" until a fixed point:
                            y         The input to this lambda.
               (_1,:1)|.!.0           Shift left and right, fill with 0.
            >./                       Maximum of both shifts.
      (y=0)*                          Don't grow into filled cells.
    y+                                Add growth to input.

Це так відрізняється від того, що я маю, я думаю, ви повинні опублікувати це як відповідь :)
Лінн

3

Python 3,5, 83 байти

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

def b(s):
 for _ in s:s=[s[n]or max((0,*s)[n:n+3])for n in range(len(s))]
 return s

З Python 3.5, PEP 448 дозволяє нам розпаковувати sв 0,*s. Більш ранні випуски потребують додаткового байту:

def b(s):
 for _ in s:s=[s[n]or max(([0]+s)[n:n+3])for n in range(len(s))]
 return s

Кредит рішення і пояснення user81655 ігрова за допомогу мені зрозуміти , що мені не потрібно , щоб тест був список припиняв змінюватися; Мені просто потрібно повторити достатньо разів, щоб бути впевненим, що всі нулі повинні бути покриті. (Максимальна кількість необхідних ітерацій на одну меншу, ніж довжина списку; це на одну ітерацію більше, ніж для цього, оскільки для цього потрібно менше коду.)


@ChrisH: Це не працює на Python 3.5, і я не думаю , що він буде працювати на більш ранніх версіях або: ніщо переміщати returnдо всередині в for _ in sциклі?
Тім Педерік

коментар видалений - у мене траплялися лише тестові випадки, які вирішуються вперше.
Кріс Н

3

Матлаб, 90 байт

Як щодо деяких згортків?

x=input('');for n=x;x=x+max(conv(x,[0 0 1],'same'),conv(x,[1 0 0],'same')).*~x;end;disp(x)

Приклад

>> x=input('');for n=x;x=x+max(conv(x,[0 0 1],'same'),conv(x,[1 0 0],'same')).*~x;end;disp(x)
[7 0 3 0 0 0 0 0 8 0 9 1]
     7     7     3     3     3     8     8     8     8     9     9     1

3

Haskell, 66 65 байт

f x=[maximum[[-j*j,a]|(j,a)<-zip[-i..]x,a>0]!!1|(i,_)<-zip[0..]x]

Це визначає функцію, що називається f.

Пояснення

Замість ітерації стільникового автомата я обчислюю кінцеві значення безпосередньо. Визначення - це розуміння єдиного списку. Значення iваріюється від 0до length x - 1, оскільки ми пов'язуємо xз натуральними числами. Для кожного індексу iми виробляємо список двоелементних списків

[-(-i)^2, x0], [-(-i+1)^2, x1], [-(-i+2)^2, x2], ..., [-(-i+n)^2, xn]

З цього списку ми обчислюємо максимальний елемент, другий координат якого не є нульовим, і беремо цей другий елемент !!1. Це дає найближче ненульове значення до індексу i, розриваючи зв'язки, приймаючи більше значення.


Вітаю вас за виграш щедрості!
xnor

2

Луа, 133 байт

Дві петлі, вкладені тернеари ... Якщо я хочу далі пограти в гольф, мені доведеться знайти інший спосіб зробити це, але я не бачу його.

function f(a)for i=1,#a do b={}for j=1,#a do c,d=a[j+1]or 0,a[j-1]b[j]=0<a[j]and a[j]or(d or 0)>c and d or c end a=b end return a end

Пояснення

function f(a)
  for i=1,#a                       -- this loop allow us to be sure the cycle is complete
  do
    b={}                           -- set a new pointer for b
    for j=1,#a                     -- loop used to iterate over all elements in a
    do
      c,d=a[j+1]or 0,a[j-1]        -- gains some bytes by attributing these expressions 
                                   -- to a variable
      b[j]=0<a[j]and a[j]or        -- explained below
            (d or 0)>c and d or c
    end
    a=b                            -- we are one cycle further, new value for a
  end                              -- which is our reference array
  return a
end

Частина

b[j]=0<a[j]and a[j]or(d or 0)>c and d or c 

буде розширено до

b[j]=0<a[j]and a[j]or(a[j-1] or 0)>(a[j+1] or 0) and a[j-1] or(a[j+1]or 0) 

який можна перекласти вкладеним ifяк

if 0<a[j]
then
    value=a[j]          -- if the cell isn't at 0, it keeps its value
elseif (a[j-1] or 0)<(a[j+1] or 0)
--[[ x or y as the following truth table :
x | y ||x or y
------||-------
0 | 0 || false
0 | 1 ||   y
1 | 0 ||   x
1 | 1 ||   x
    -- It means that when j=1 (1-based) and we try to index a[j-1]
    -- instead of failing, we will fall in the case false or true
    -- and use the value 0
    -- the same trick is used for when we try to use an index > a:len
]]--
then
    value=a[j-1]        -- the left cell propagate to the cell j
else
    value=a[j+1] or 0   -- if j=a:len, we put 0 instead of a[j+1]
                        -- this case can only be reached when we are on the right most cell
                        -- and a[j-1]==0
end

1

Піт, 17 байт

meeSe#.e,_akdbQUQ

Знімає список стилю Python зі stdin, виводить у stdout.

Пояснення

Це в основному переклад моєї відповіді Haskell. Я раніше ще не використовував Pyth, тому підказки вітаються.

                   Implicit: Q is input list
m              UQ  Map over input index d:
      .e      Q     Map over input index k and element b:
        ,_akdb       The pair [-abs(k-d), b]
    e#              Remove those where b==0
 eeS                Take the second element of the maximal pair

1

APL (Dyalog) , 18 байт

Функція анонімного негласного префікса.

(⊢+~∘××3⌈/0,,∘0)⍣≡

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

()⍣≡ Застосувати таку негласну функцію, поки результат не буде ідентичним аргументу:

 аргумент

+ плюс

  ~ НЕ  Сігнум
  
  ×

× разів

3⌈/ максимуми над кожною групою з трьох

0, нуль, за яким

  , аргумент слід
   в
  0 нулі


1

Java 8, 155 142 байти

a->{for(int b[],i,l=a.length,p,n,f=l;f>0;)for(b=a.clone(),i=0,f=l;i<l;f-=a[i-1]>0?1:0)if(a[i++]<1)a[i-1]=(p=i>1?b[i-2]:0)>(n=i<l?b[i]:0)?p:n;}

Змінює введення int[]замість повернення нового для збереження байтів.

Пояснення:

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

a->{                   // Method with integer-array parameter and no return-type
  for(int b[],         //  Copy array
          i,           //  Index integer
          l=a.length,  //  Length of the array
          p,n,         //  Temp integers (for previous and next)
          f=1;         //  Flag integer, starting at 1
      f>0;)            //  Loop (1) as long as the flag is not 0 (array contains zeroes)
    for(b=a.clone(),   //   Create a copy of the current state of the array
        i=0,           //   Reset the index to 0
        f=l;           //   Reset the flag to the length of the array `l`
        i<l;           //   Inner loop (2) over the array
        f-=a[i-1]>0?   //     After every iteration, if the current item is not a zero:
            1          //      Decrease flag `f` by 1
           :           //     Else:
            0)         //      Leave flag `f` the same
      if(a[i++]<1)     //    If the current item is a 0:
        a[i-1]=        //     Change the current item to:
         (p            //      If `p` (which is:
           =i>1?       //        If the current index is not 0:
             b[i-2]    //         `p` is the previous item
            :          //        Else:
             0)        //         `p` is 0)
         >(n           //      Is larger than `n` (which is:
            =i<l?      //        If the current index is not `l-1`:
              b[i]     //         `n` is the next item
             :         //        Else:
              0)?      //         `n` is 0):
          p            //       Set the current item to `p`
         :             //      Else:
          n;           //       Set the current item to `n`
                       //   End of inner loop (2) (implicit / single-line body)
                       //  End of loop (1) (implicit / single-line body)
}                      // End of method

0

Рубін, 81 байт

->(a){a.map{|o|a=a.map.with_index{|x,i|x!=0 ? x : a[[0,i-1].max..i+1].max}}[-1]}

Я думаю, що внутрішній mapміг би бути ще гольф.


Щойно зрозумів, моя відповідь якось ідентична відповіді @ user81655 .
Сувора Гупта

Я думаю, що ви можете видалити пробіли в трійці, тобто навколо ?і :.
Олексій А.

0

PHP - 301 291 289 288 264 Персонажі

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

$a=explode(' ',$s);$f=1;while($s){$o=1;foreach($a as&$b){
if($b==0){$u=current($a);prev($a);$d=prev($a);if(!$o&&current($a)==0){end($a);$d=prev($a);}if(!$f){$f=1;continue;}if($u>$d)$b=$u;if($u<$d){$b=$d;$f=0;}}
$o=0;}if(!in_array(0,$a))break;}$r=join(' ',$a);echo$r;

Пояснив

// Input
$s = '0 0 2 0 0 0 1 2 0 0 3 3 0 0';

// Create array
$a = explode(' ', $s);
// Set skip flag
$f = 1;
while ($s)
{
    // Set first flag
    $o = 1;
    // Foreach
    foreach ($a as &$b)
    {
        // Logic only for non zero numbers
        if ($b == 0)
        {
            // Get above and below value
            $u = current($a);
            prev($a);
            $d = prev($a);

            // Fix for last element
            if (! $o && current($a) == 0)
            {
                end($a);
                $d = prev($a);
            }

            // Skip flag to prevent upwards overrun
            if (! $f)
            {
                $f = 1;
                continue;
            }

            // Change zero value logic
            if ($u > $d)
                $b = $u;
            if ($u < $d)
            {
                $b = $d;
                $f = 0;
            }
        }

        // Turn off zero flag
        $o = 0;
    }

    // if array contains 0, start over, else end loop
    if (! in_array(0, $a))
        break;
}
// Return result
$r = join(' ', $a);
echo $r;(' ', $a);
echo $r;

1
Серйозно? Гольф - це не просто видалення пробілів у вашому коді. Окрім алгоритму, ось кілька порад: 1скоріше скористайтеся true, splitа не explode, forа не while, joinа не implodeзніміть непотрібні фігурні дужки,…
Blackhole

Я вибухнув, тому що розкол знецінюється. Крім того, я не знаю, як записати цикл часу, використовуючи для, тому я зберігав його поки що, якщо хтось тут не може поділитися своїми знаннями або поділитися посиланням. Дякую вам всім.
Гуска

0

Пітон, 71 байт

g=lambda l:l*all(l)or g([l[1]or max(l)for l in zip([0]+l,l,l[1:]+[0])])

zipСтворює всі довжини 3 подсписков елемента і його сусідів, лікування за межами кінцевих точок як 0. Центральний елемент l[1]підспису l, якщо нуль, замінюється на maxйого сусіди l[1]or max(l). У l*all(l)повертає список , lколи він не має 0«S.


0

Рубін, 74 байти

->a{(r=0...a.size).map{|n|a[r.min_by{|i|[(a[i]<1)?1:0,(i-n).abs,-a[i]]}]}}

працює, знаходячи найближче ненульове число.


0

MATL , 38 байт

Прямий переклад моєї відповіді Matlab. Використовується поточна версія мови / компілятора.

it:"tttFFTo2X5I$X+wTFFo2X5I$X+vX>w~*+]

Приклад

>> matl it:"tttFFTo2X5I$X+wTFFo2X5I$X+vX>w~*+]
> [7 0 3 0 0 0 0 0 8 0 9 1]
7 7 3 3 3 8 8 8 8 9 9 1

EDIT: Спробуйте в Інтернеті! із X+заміненими на Y+і vна &v, завдяки змінам, що відбулися в мові.

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