Bakteriyel genişleme


25

Bakteri kolonileri etiketli 1aracılığıyla 9boş hücreler tarafından gösterilen ile aynı şekilde aralıklı hücrelerin segmanlarında canlı0

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

Her saniye, her koloni bitişik boş hücrelere yayılır. İki koloni aynı anda boş bir hücreye ulaşırsa, daha büyük etiketli koloni alır.

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  

Sömürgeler sınırların ötesine yayılamazlar. Bir koloni asla başka bir koloni ile yer değiştirmez, bu yüzden tüm boş hücreler doldurulduktan sonra, hiçbir şey değişmez.

İlk durum göz önüne alındığında, son durumu çıktı veya yazdırın. Makul bir liste veya dize formatı kullanın. Herhangi bir ara durumu çıkarmamalısınız. Giriş en az bir bakteri kolonisi içerecektir.

İlgili: Bir listedeki sıfırları örtün . (Koloniler yalnızca sağa doğru yayılır.)

Test durumları: Girişin altındaki çıktı.

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

Yanıtlar:


14

JavaScript (ES6), 66 62 bayt

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

açıklama

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

Ölçek


10

Pyth, 18 bayt

um|@d1eSd.:++0G03Q

Test odası

Bir tam sayı listesi olarak girdi alır.

Temel olarak, bu yakınsama döngüsüne kadar bir uygulama kullanır u. Her hücrenin tüm listelerini ve her iki taraftaki iki hücreyi oluşturarak, ardından sıfırlanan her bir hücreyi komşularının maksimuma güncelleyerek güncelleme yapar.

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

Mathematica, 77 bayt

Halep'in çözümüyle karşılaştırıldığında çok rekabetçi değil //., ancak zorluğunun bir CellularAutomatoncevabı olması gerektiğini düşündüm :

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

Fonksiyon bir ton parametre alır ... Hadi onlara bazı isimler verelim:

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

İşte yaptıkları:

  • rkuralın menzilidir, yani güncelleme için kaç tane komşunun değerlendirileceğini belirler. Her iki tarafta bir komşu istiyoruz, bu yüzden kullanıyoruz 1.
  • nnormalde renklerin sayısı veya listesidir (farklı hücre tipleri), ancak kuralı bir kural numarası yerine özel bir işlev olarak belirlersek, bu olmalıdır {}.
  • fgüncelleme kuralını belirleyen bir fonksiyondur. 3 hücre (eğer r = 1) listesini alır ve orta hücre için yeni rengi döndürür.
  • iilk durumdur. Girdi bu.
  • barka plan Bu verilmezse, CellularAutomatonistemediğimiz periyodik sınırları kullanır. Bunun yerine kullanmak 0ölü bir sınır şartı getirir.
  • tsimüle edilecek kaç kez. Girdi genişliğinden daha fazla adıma ihtiyacımız yok, çünkü bundan sonra bakteri birleşir t = Length@#. Normalde, CellularAutomatontüm ara adımları döndürür. tİki listeye sararak bunu önleyebiliriz .
  • dHangi hücrelerin çıktıda sunulacağını belirler. Varsayılan olarak, kuraldan potansiyel olarak etkilenebilecek tüm hücreleri elde ederiz ( t*rgirişin her iki ucundaki ek hücrelerdir). Veririz l-1, çünkü bu, Mathematica'da sıfır tabanlı bir endeksin kullanıldığı birkaç durumdan biri.

6

Haskell, 86 83 81 79 73 71 bayt

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

Kullanım örneği: 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].

Açıklamak için çok fazla bir şey yok: eğer bir hücre 0 ise, komşu elementlerin maksimumunu alın. Giriş süresini tekrarlayın. Bunun için tekrar ediyorumx yoluyla foldlancak ikinci argümanı görmezden p.

Düzenleme: @Mauris kaydetmek için 6 bayt bulundu ve @ başka bir @ xnor. Teşekkürler!


6 bayt kaydetmek için ile değiştirebilirsiniz h p, p!_sonra ile değiştirin . (const.h)(!)
Lynn,

@ Mauris: Zeki. Çok teşekkürler!
nimi,

@nimi son satırın anonimleştiğini düşünüyorum id>>=foldl(!).
xnor

@ xnor: evet öyle! İyi benekli!
nimi

4

CJam, 27 24 bayt

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

Burada test et.

Bu, yığındaki bir listeyi yeni bir listeye dönüştüren adsız bir bloğu iter.

açıklama

_,       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.
  }%
}*

Sidestepping yakınsama güzel bir hiledir
Luis Mendo

1
... utanmadan ödünç aldım :-)
Luis Mendo

4

J, 24 23 bayt

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

Kullanımı:

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

Yöntem Mauris'in çözümüne benzer .

(                  )^:_ 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

Burada çevrimiçi deneyin.

Zgarb sayesinde 1 bayt kurtarıldı.


3

Mathematica, 77 74 66 62 bayt

Martin Büttner sayesinde 12 bayt kurtarıldı.

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

3

J, 33 bayt

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

İstediğimden biraz daha uzun.

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.

Bu sahip olduklarımdan çok farklı, bence bir cevap olarak göndermelisin :)
Lynn

3

Python 3.5, 83 bayt

Bu işlev bir Python tamsayı listesi alır. Golf için fazla yer kaldığından emin değilim, ama en azından başka bir dille rekabet etmeyi çok isterim!

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 itibaren PEP 448 paket açma bizi sağlar siçine 0,*s. Daha önceki sürümlerde bir bayt ekstra gerekir, bunun gibi:

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

Kredi user81655 en çözeltisi ve açıklama yardım ettiğin için liste değişen durdu olmadığını ben teste gerek olmadığını fark; Tüm sıfırların kapatıldığından emin olmak için sadece yeterince zamana ihtiyacım var. (İhtiyaç duyulan maksimum yineleme sayısı listenin uzunluğundan daha azdır; bu, bundan daha fazla kod gerektirir çünkü bundan daha fazla yineleme yapar.)


@ChrisH: Python 3.5 üzerinde çalışmaya etmez ve ben de o eski sürümlerinde çalışacak sanmıyorum: hareket etmediğini returniçin içeridefor _ in s döngü?
Tim Pederick

yorum silindi - Yalnızca ilk defa çözülen test vakalarını denedim.
Chris H,

3

Matlab, 90 bayt

Bazı kıvrımlar nasıl?

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

Örnek

>> 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 bayt

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

Bu denilen bir işlevi tanımlar. f .

açıklama

Hücresel otomatiği yinelemek yerine, son değerleri doğrudan hesaplarım. Tanım tek bir liste anlamadır. Değeri iarasında değişir 0için length x - 1biz zip, çünkü xdoğal sayılarla. Her endeks iiçin 2 elementli listelerin listesini hazırlarız.

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

Bu listeden, ikinci koordinatı sıfır olmayan maksimum öğeyi hesaplıyoruz ve bu ikinci öğeyi de alıyoruz !!1. Bu, endekse sıfır olmayan değeri verir ve idaha büyük değeri alarak bağları koparır.


Ödül kazandığın için tebrikler!
xnor

2

Lua, 133 bayt

İki döngü, iç içe üçlüler ... Eğer daha fazla golf oynamak istersem, bunu yapmanın başka bir yolunu bulmam gerekecek, ama bir tane göremiyorum.

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

açıklamalar

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

Parça

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

genişletilecek

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) 

hangi iç içe ifolarak çevrilebilir

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

Pyth, 17 bayt

meeSe#.e,_akdbQUQ

Stdin'den Python stili bir liste alır, çıktılar stdout'a çıkar.

açıklama

Bu temelde Haskell cevabımın bir çevirisidir. Pyth'i daha önce hiç kullanmamıştım, bu yüzden ipuçları açıktır.

                   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 bayt

Anonim zımni önek işlevi.

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

Çevrimiçi deneyin!

()⍣≡ Sonuç, argümanla aynı olana kadar aşağıdaki taktik işlevini uygular:

 argüman

+ artı

  ~ değil  sinyalnum
  
  ×

× zamanlar

3⌈/ üç grubun her biri için maksimum

0, sıfır, ardından

  , bağımsız değişken ile, ardından
   bir
  0 sıfır


1

Java 8, 155 142 bayt

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

Girdiyi int[]kaydetmek için yenisini döndürmek yerine girişi değiştirir .

Açıklama:

Burada dene.

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

Ruby, 81 bayt

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

Bence iç mapdaha fazla golf oynayabilirdi.


Yeni farkettim, cevabım @ user81655'in cevabı ile aynı .
Harsh Gupta,

Ben yani etrafında, üçlü içinde boşlukları kaldırın düşünüyorum ?ve :.
Alex A.

0

PHP - 301 291 289 288 264 Karakterler

Bu denemeden önce diğer cevaplarda zirveye ulaşmadı. Dili suçlama, beni suçla. Çok eğlenceli ve daha az zor değil. Tüm kod golf önerileri çok takdir edilmektedir.

$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;

Açıklaması

// 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
Ciddi anlamda? Golf oynamak sadece kodunuzdaki boşlukları kaldırmak değildir. Algoritması yanı sıra, burada bazı ipuçları: kullanım 1yerine true, splityerine explode, foryerine while, joinyerine implode, yararsız süslü parantez kaldırmak ...
Blackhole

Patlamaya devam ettim çünkü bölünme değer kaybetti. Ayrıca, bir süre döngüsü kullanarak nasıl yazacağımı bilmiyorum, bu yüzden birileri bilgilerini paylaşmadığı veya bir bağlantıyı paylaşmadığı sürece şimdilik tuttum. Hepinize teşekkür ederim.
Kaz

0

Python, 71 bayt

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

zipOlarak uç noktaları ötesine tedavi, bir elementin ve komşuları tüm uzunluğu-3 sublists yaratır 0. Merkezi eleman l[1]bir lsıfır ise, sıfır maxile komşularından birinin yerine geçer l[1]or max(l). l*all(l)Döner liste lhiçbir vardır 0's.


0

Ruby, 74 bayt

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

en yakın sıfır olmayan numarayı bularak çalışır.


0

Matl , 38 bayt

Matlab cevabımın direkt çevirisi. Dilin / derleyicinin geçerli sürümünü kullanır .

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

Örnek

>> 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: Çevrimiçi deneyin! ile X+değiştirilir Y+ve vtarafından &vdilinde yapılan değişiklikler nedeniyle,.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.