Depremlerin Analizi


17

Arka fon

Rastgele Domino Otomat hücresel otomat esinlenerek depremler için bir oyuncak modelidir. Bu meydan okumada, göreviniz bu modelin basitleştirilmiş bir versiyonunu simüle etmek ve modelden veri toplamaktır.

Otomat bir dizi tanımlanır Ave kdeprem meydana gelebileceği bir kırık hattı temsil bit. Dizi sınırlarında sarar. Koşul A[i] = 0pozisyonu demek olduğunu iedilmektedir rahat ve A[i] = 1araçlar o oluyor o heyecan , ya da enerji depolanır içerir. Her bir zaman adımında, dizinin bir pozisyonu rastgele olarak eşit olarak seçilir. Bu pozisyon rahatlarsa, heyecanlanır (sisteme potansiyel enerji eklenir). Bu pozisyon zaten heyecanlıysa, bir depremi tetikler ve seçilen konum ve ona bağlı tüm heyecanlı konumlar tekrar rahatlar. Gevşeyen heyecanlı pozisyonların sayısı büyüklüktür depremin .

Misal

Diziyi düşünün

100101110111

Rastgele işlem soldan ikinci biti seçerse, dizi şu şekilde güncellenir:

110101110111
 ^

seçilen bit (işaretli ^) olduğundan beri 0. Daha sonra soldan dördüncü biti seçersek, bu izole edilmişse 1, 1 büyüklüğünde bir deprem tetiklenir ve bit 0tekrar olarak ayarlanır :

110001110111
   ^

Sonra, sağdan ikinci biti seçebiliriz, bu da 5 büyüklüğünde bir deprem tetikler:

000001110000
          ^

Tüm bunların 1 seçilmiş kişi ile aynı "küme" s depremin parçasıydı ve dizi sınırda sarar.

Görev

İki pozitif tamsayı girdi olarak alacaksınız kve tgöreviniz, tüm s'nin tbaşlangıç ​​uzunluk kdizisinden başlayarak zaman adımları için rasgele domino otomatlarını simüle etmektir 0. Çıktınız (1 tabanlı indeksleme ile) büyüklükte deprem sayısını içeren bir tamsayı listesi olmalıdır L.kL[i]i simülasyon sırasında meydana geldi. Çıktıdan sondaki sıfırları bırakmanıza izin verilir.

Girişler k = 15ve t = 1000bazı temsili çıkışlar için

[117, 97, 45, 26, 10, 5, 3, 1, 3, 0, 0, 0, 0, 0, 0]
[135, 91, 58, 21, 8, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0]
[142, 63, 51, 31, 17, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0]
[106, 75, 45, 30, 16, 8, 5, 2, 2, 0, 0, 0, 0, 0, 0]
[111, 96, 61, 22, 3, 8, 3, 2, 0, 0, 0, 1, 0, 0, 0]

kurallar

Hem tam programlara hem de işlevlere izin verilir. En kısa bayt sayısı kazanır ve standart boşluklara izin verilmez.

Belirli bir uygulamayı kullanarak otomasyonu simüle etmeniz gerekmediğini, yalnızca çıkışın önemli olduğunu unutmayın.


2
Değişen bitin altına bir düzeltme işareti ^ ekleyebilirsiniz? Örneği görselleştirmek daha kolay olabilir
DeadChex

1
@DeadChex İyi fikir, güncellendi.
Zgarb

Yanıtlar:


2

Pyth, 48 bayt

Km0QJsM.u?<+vM.sjkZ\1KQe=Z.>NOQ+PZ1vwKm/-VJtJhdQ

@ Dennis'in açıklamasından biraz ilham aldım. Dün benzer düşünceler vardı, ama onları gerçekten takip etmedi.

Çevrimiçi deneyin: Gösteri

Açıklama:

      implicit: Q is the first input number
 m0Q  create a list with Q zeros
K     store the list in K


       .u                      vwK   apply the following expression eval(input) times, 
                                     start with N = K:
                      .>NOQ            shift N by a random integer of [0, ..., Q-1]
                    =Z                 store the result in Z
     ?             e Z                 if the last digit == 1:
            jkZ                          convert Z to string
          .s   \1                        remove "1"s from the start and end
        vM                               convert to list of integers
       +         K                       add K (adds a bunch of zeros)
      <           Q                      correct size (take the first Q elements)
                                         implicitly update N with this result
                                       else:
                           PZ            all but last of Z
                          +  1           append 1
                                         implicitly update N with this result

   .u                                gives all the intermediate states
 sM                                  sum each list
J                                    store in J


m/-VJtJhdQ
m        Q   map each d in [0, 1, ..., Q-1] to:
  -VJtJ        vectorized minus between J and J[1:]
 /     hd      count d+1 in ^
             implicitly print

5

CJam, 57 55 bayt

{:K,K0a*@[{Kmrm<){_{_0#>W%K0e]}2*_)}1?+}*;]1fb2/::-fe=}

Bu, yığından k ve t'yi ( t'nin üstünde k) açan ve karşılığında istenen diziyi bırakan anonim bir işlevdir .

CJam yorumlayıcısında çevrimiçi deneyin .

Nasıl çalışır

:K         e# Save the topmost integer (k) in K.
,          e# Push I := [0 ... K-1].
K0a*       e# Push J := [0 ... 0] (K elements).
@          e# Rotate the other integer (t) on top of the stack.
[{         e# Do t times:
  Kmr      e#   Pseudo-randomly select an integer between 0 and t-1.
  m<       e#   Rotate the array J than many units to the left.
  )        e#   Pop out the last element.
  {        e#   If it is 1:
    _      e#     Copy J.
    {      e#     Do 2 times:
      _0#  e#       Push the first index of 0 in J.
      >    e#       Discard the preceding elements.
      W%   e#       Reverse the array.
      K0e] e#       Pad it with zeroes to length K.
    }2*    e#
    _)     e#     Copy J and pop out the last element.
  }        e#
  1?       e#   Else: Push 1.
  +        e#   Push the integer on the stack on J.
}*         e#
;          e# Discard the last value of J.
]          e# Collect the intermediate values of J in an array.
1fb        e# Replace each array by the sum of its elements (number of ones).
2/         e# Split the array into chunks of length 2.
::-        e# Replace each chunk by the difference of its elements.
fe=        e# Count the occurrences of each integer in I.

4

Python 2, 153 bayt

from random import*
k,t=input()
E=[0]*k
L=E+[0]
def g(i,x=0):y=E[i];E[i]=y&x^x;return y and-~g(i-1)+g(-~i%k)
exec"L[g(randrange(k),1)]+=1;"*t
print L[1:]

I dışarı Dönüşler hemen hemen aynı çözümü vardı Fry , ama biraz daha işe yaramaz ısırdı.


Vay canına gerçekten bakmıştım randrange, ama bunun sadece bir argümanla çalıştığını fark etmedim. İyi iş!
FryAmTheEggman

4

Java, 278 272 bayt

Java en iyi Golf dili değil ve ben en iyi golfçü değilim, ama burada yazmak çok eğlenceliydi! Hatalar ve iyileştirmeler hakkında bilgi verin! (Sadece bir işlev olarak yeniden göndermeye karar verdim.)

void e(int k, int t){int[]d=new int[k],b=d.clone();for(;t-->0;){int m=0,q=(int)(Math.random()*k),i=q,h=1,f=0;d[q]++;if(d[q]>1){for(;;){if(i<0){i=k-1;h=-1;}if(d[i%k]>0){m++;d[i%k]=0;}else{if(f>0)break;h*=-1;i=q;f=1;}i+=h;}b[m-1]++;}}System.out.println(Arrays.toString(b));}

Ve boşlukları ve yorumları olan dosya:

void e(int k, int t){
    int[]d=new int[k],b=d.clone();          //b is the record, d is the map   

    for(;t-->0;){                           //do time steps //q is the spot
      int m=0,q=(int)(Math.random()*k),i=q,h=1,f=0; 
                        //m-magnitude,i spot examining, h moving index, f change counter
      d[q]++;                               //add the energy
      if(d[q]>1){                           //double energy, quake here 
        for(;;){                            //shorthand while true
          if(i<0){                          //i has wrapped negative, need to start a left hand search from the end now
            i=k-1;                          //Start at the end
            h=-1;                           //Left handed search
          }
          if(d[i%k]>0){                     //is the spot energetic and set off
           m++;                             //add one to the mag counter
           d[i%k]=0;                        //remove energy
          } else {                          //it's a non active spot so we need to flip search direction
           if(f>0) break;                   //we've already flipped once, break
           h*=-1;                           //flip the direction now
           i=q;                             //reset the spot we look at to the epicenter
           f=1;                             //add one to the flip counter
          }
          i+=h;                             //add the search increment to the spot we look at
        }
        b[m-1]++;                           //update the mag record
      }
    }
    System.out.println(Arrays.toString(b)); //print it out
 }

2. programda yorumları biraz kaldırabiliyorsanız, bu okunabilirliğe yardımcı olabilir. Teşekkürler. ( Alt+09Notepad ++ ile kullanın veya sekme yapın)
mbomb007

d[q]+=1;bu, d[q]++;her yerde + = kullanmak yerine doğrudan dizileri arttırabilirsiniz. Bu bir grup karakteri kurtarmalıdır.
Pusula

@Compass Zaten bu değişikliği yaptınız, teşekkürler!
DeadChex

1
Ayrıca: for(;t>0;t--){ olarak değiştirilebilir for(;t-->0;){: D
Pusula

Burada ilk golfünüz için tebrikler! : D Şimdi .... sadece bildirimleri biraz yeniden düzenleyerek ve sonucu (yazdırmak yerine) döndürerek, bunu biraz aşağı alabilirsiniz. Yapılması gereken daha çok şey olabilir, ama gitmek zorundayım. İşte 244 baytlık bir sürüm: pastebin.com/TWAXvyHW
Geobits

4

Piton 2, 174 170

from random import*
k,t=input()
D=[0]*k
E=D+[0]
def U(x):b=D[x];D[x]=0;return b and-~U(x-1)+U(-~x%k)
for x in[0]*t:r=randint(0,k-1);e=U(r);E[e-1]+=1;D[r]=e<1
print E[:-1]

@Vioz'a daha kısa bir yol bulduğunuz için teşekkürler Dve notgenellikle golfçü olduğunu kanıtlayın . Ve ayrıca açıklamayı yazmak için.

Pyth'de benzer bir program yapmaya çalışmıştım, ama yapmaya çalıştığım şeyde bir kapsam sorunu var gibi görünüyor. Bu oldukça naif bir şekilde dominoları uygular ve fonksiyon Udepremleri yayar. Çıkarma yönünün Ubir moda ihtiyacı yoktur, çünkü doğal olarak sarılacaktır. Son elemanıE sayım sıranın bir sıfıra dönüştürülme sayısını sayar, böylece sonunda yazdırılmaz.

Ungolfed + Açıklama:

from random import*
k,t=input()                            # Takes input in form k,t
D = [0]*k                              # Empty array of size k is made for
                                       # performing the simulation.
E = D+[0]                              # Empty array of size k+1 is made for
                                       # storing the magnitudes.
def U(x):                              # Define a function U that takes an int x
    b = D[x]                           # Assign b to the value at x in D
    D[x] = 0                           # Clear the value at x in D
    return b and U(x-1)+1 + U((x+1)%k) # Return the sum of U(x-1)+1 and U((x+1)%k)
                                       # if b is a 1.
for x in[0]*t:                         # Perform t tests
    r=randint(0,k-1)                   # Generate a random number between 0 and k-1
    e=U(r)                             # Assign e to the value of U(r)
    E[e-1]+=1;                         # Increment the magnitude array at position
                                       # e-1
    D[r] = e<1                         # Set D[r] to be 1 if no earthquake happened.
print E[:-1]                           # Print the magnitude list

1
Değişen D[r]=not eiçin D[r]=e<12 bayt kaydeder ve E=[0]*-~kkarşı E=D+[0]başka 2 kaydeder ila 170 aşağı almak
Kade

1

ES6, 224 196 189 179 172

Kolay şeyler golf, ama yine de bazı işler yapmak. Daha sonra bir açıklama yazacağım. Ayrıca, birisi bana neden kısa new Date%kşeyin neden bu kadar iyi çalışmadığını söyleyebilse , bu şişebilir.

f=(k,t)=>{a=Array(k).fill(0);o=a.slice(0);for(;t--;){c=0;r=Math.random()*k|0;if(a[r]){for(d=r+1;d<k&a[d];c++)a[d++]--;for(d=r-1;d&a[d];c++)a[d--]--;o[c]++};a[r]^=1}return o}

Kullanımı

f(10, 1000);

Öğesini kaldırabilirsiniz new. tFor döngüsünde buna ihtiyacınız yok, Son ikisine gerek yok;
Optimizer

@Optimizer neden kahramansın
Pusula

a[r]^=1 başlangıç ​​değeri ya da 1 da veya0
Optimizer

1

Perl, 212

Daha önce takmış olduğum sürüm doğru bir şekilde sarılmamıştı ve biraz iş gerektiriyordu.

sub f{sub n{$i=($i+$d)%($#a+1)}($k,$t)=@_;@L=@a=(0)x$k;for(1..$t){$i=$x=int rand($k);if(++$a[$x]>1){$d=1;my%z;for(;;){$z{$i}=1;n;if(!$a[$i]){$d*=-1;n}last if($d>0&&$i==$x)}@z=keys %z;@a[@z]=(0)x@z;++$L[$#z]}}@L}

Bu muhtemelen bunun için doğru algoritma değil, ama şimdi düşünemiyorum. Çözülmemiş versiyon aşağıdadır.

Ungolfed:

sub f {
  # n() implements the iterator, so that each time it is called a
  # global index is incremented or decremented correctly wrapping
  # around
  sub n { $i = ($i + $d) % ($#a + 1) }
  # Receive input
  ($k, $t) = @_;
  # Initialise the array for earthquake magnitudes an the fault
  # line
  @L = @a = (0) x $k;

  for(1..$t){
    # Assign a random integer value to two control variables
    # $i is used for moving along the fault, and $x to remember
    # the initial value
    $i = $x = int rand($k);
    # The corresponding value in the fault line is incremented,
    # and earthquakes detected
    if(++$a[$x]>1){
      # Earthquake!
      # To propagate the earthquake, we move along the fault 
      # bouncing on unactivated nodes. We stop when we've covered
      # the entire activated block.

      # $d tracks the direction (initially forward);
      $d = 1;
      # %z keeps the indeces of known activated nodes
      my %z;

      for(;;){
        $z{$i} = 1;              # Read current node
        n;                       # Move head
        if (!$a[$i]) {           # If next one is deactivated
          $d *= -1;              # change direction
          n                      # and move the head (bounce!)
        }
        # If we've reached the beginning, and we're moving
        # forward we've covered the entire activated block
        last if ($d > 0 && $i == $x);
      }

      # Deactivate all consecutive activated nodes
      @z = keys %z;
      @a[@z] = (0) x @z;
      # And store the magnitude of the earthquake
      ++$L[$#z];
    }
  }
  # Return list of magnitudes
  @L
}

print join ' ', f(15, 1000), "\n";

1

CJam, 76 bayt

l~_0a*:R@{1$mr_2$={W@@[W1]{{_@0t@)\@K+_2$=}g2$+)}fK;\(_R=)R\t:R;}{1t}?}*;;Rp

Bu çok rekabetçi değil. Ama beni yeterince uzun sürdüğünden, yine de göndereceğimi düşündüm.

l~     Get input.
_0a*   Initial bit pattern, list of k zeros.
:R     Save away the list of zeros, will be used for histogram.
@{     Pull number of tries to top of stack, and start main loop.
1$mr   Generate random position in range 0 to k-1.
_2$    Duplicate current pattern and position.
=      Get current value of bit at position.
{      Start if statement. This is the block for bit value 1.
W@@    Create initial count of 1 bits in quake, and push it down the stack.
[W1]{  Start for loop over value [-1 1], the two increments for going left/right.
{      Start while loop that proceeds as long as 1 bits are found.
_@0t   Set current value of bit to 0.
@)     Get current bit counter to top of stack, and increment it.
\@     Pull list and bit position back to top of stack.
K+     Increment/decrement bit position.
_2$=   Get value at new bit position.
}g     End of while loop over 1 bits.
2$+)   Restore position to get ready to move in opposite direction.
}fK    End for loop over left/right increment.
;\(_   Pull counter of 1 bits in quake to top of stack.
R=     Get current value in histogram,
)      increment it,
R\t:R  and store it back in the histogram.
;}     End of if branch for 1 bit.
{1t}?  Else branch of if. For 0 bit, simply set it.
}*     End main loop.
;;Rp   Clean up stack and print histogram.

Çevrimiçi deneyin

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.