กำลังวิเคราะห์แผ่นดินไหว


17

พื้นหลัง

สุ่ม Domino ออโตมาเป็นรูปแบบของเล่นสำหรับแผ่นดินไหวแรงบันดาลใจจากเซลล์ออโต ในความท้าทายนี้งานของคุณคือการจำลองแบบจำลองที่ง่ายขึ้นของรุ่นนี้และรวบรวมข้อมูลจากมัน

หุ่นยนต์ถูกกำหนดบนอาเรย์Aของkบิตแสดงถึงเส้นความผิดที่อาจเกิดแผ่นดินไหว อาร์เรย์ล้อมรอบที่ชายแดน เงื่อนไขA[i] = 0หมายถึงตำแหน่งiนั้นผ่อนคลายและA[i] = 1หมายความว่ามันตื่นเต้นหรือมีพลังงานสะสม ในแต่ละขั้นตอนตำแหน่งหนึ่งของอาเรย์จะถูกเลือกแบบสุ่ม ถ้าตำแหน่งนั้นผ่อนคลายมันจะกลายเป็นตื่นเต้น (พลังงานที่มีศักยภาพจะถูกเพิ่มเข้าไปในระบบ) หากตำแหน่งนั้นตื่นเต้นแล้วมันจะทำให้เกิดแผ่นดินไหวและตำแหน่งที่เลือกและตำแหน่งที่ตื่นเต้นทั้งหมดที่เชื่อมต่อกับมันจะผ่อนคลายอีกครั้ง จำนวนของตำแหน่งที่ตื่นเต้นที่ผ่อนคลายคือขนาดของแผ่นดินไหว

ตัวอย่าง

พิจารณาอาร์เรย์

100101110111

ความยาว 12. หากกระบวนการสุ่มเลือกบิตที่สองจากด้านซ้ายอาร์เรย์จะได้รับการอัพเดตเป็น

110101110111
 ^

นับตั้งแต่ได้รับการแต่งตั้งบิต (ทำเครื่องหมายด้วย^) 0เป็น หากเราเลือกบิตที่สี่จากซ้ายซึ่งถัดไปเป็นตัวแยก1จะเกิดการเกิดแผ่นดินไหวขนาด 1 ขึ้นและบิตจะถูกตั้งค่า0อีกครั้ง:

110001110111
   ^

ต่อไปเราอาจเลือกบิตที่สองจากด้านขวาซึ่งก่อให้เกิดแผ่นดินไหวขนาด 5:

000001110000
          ^

โปรดทราบว่าทั้งหมด1ใน "คลัสเตอร์" เดียวกันกับที่เลือกเป็นส่วนหนึ่งของการสั่นสะเทือนและอาร์เรย์ล้อมรอบที่ชายแดน

งาน

คุณจะต้องใช้เป็นปัจจัยการผลิตทั้งสองจำนวนเต็มบวกkและtและงานของคุณคือการจำลองหุ่นยนต์โดมิโนสุ่มสำหรับtขั้นตอนเวลาที่เริ่มต้นจาก length- เริ่มต้นkอาร์เรย์ของทุก0s ส่งออกของคุณจะเป็นรายการLของkจำนวนเต็มที่L[i](1 ตามการจัดทำดัชนี) มีตัวเลขของการเกิดแผ่นดินไหวของขนาดiที่เกิดขึ้นระหว่างการจำลอง คุณได้รับอนุญาตให้ดร็อปศูนย์ต่อท้ายจากเอาต์พุต

สำหรับอินพุตk = 15และt = 1000เอาต์พุตที่เป็นตัวแทนบางส่วนนั้น

[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]

กฎระเบียบ

อนุญาตให้ใช้ทั้งโปรแกรมและฟังก์ชั่นเต็มรูปแบบ การนับไบต์ที่สั้นที่สุดชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต

โปรดทราบว่าคุณไม่จำเป็นต้องจำลองหุ่นยนต์โดยใช้การใช้งานเฉพาะด้าน


2
เป็นไปได้ไหมที่คุณสามารถเพิ่มเครื่องหมายรูปหมวก ^ ภายใต้การเปลี่ยนแปลงเล็กน้อย? มันอาจทำให้ง่ายขึ้นที่จะเห็นภาพตัวอย่าง
DeadChex

1
@DeadChex ความคิดที่ดีได้รับการปรับปรุง
Zgarb

คำตอบ:


2

Pyth, 48 ไบต์

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

รับแรงบันดาลใจเล็กน้อยจากคำอธิบายของ @ Dennis มีความคิดคล้าย ๆ กันเมื่อวานนี้ แต่ไม่ได้ติดตามพวกเขาจริงๆ

ลองใช้งานออนไลน์: การสาธิต

คำอธิบาย:

      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 ไบต์

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

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อที่ปรากฏkและtจากสแต็ก ( kที่ด้านบนของt ) และปล่อยให้อาร์เรย์ที่ต้องการกลับมา

ลองใช้ออนไลน์ในล่าม CJam

มันทำงานอย่างไร

: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 ไบต์

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:]

กลับกลายเป็นว่าฉันมีวิธีการแก้ปัญหาเกือบจะเหมือนกันกับของ Fryแต่ด้วยการเล่นซอเพิ่มเติมเล็กน้อย


ว้าวฉันดูจริง ๆ แล้วrandrangeแต่ฉันก็ไม่รู้ว่ามันใช้ได้กับข้อโต้แย้งเพียงข้อเดียว เยี่ยมมาก!
FryAmTheEggman

4

Java, 278 272 ไบต์

Java ไม่ใช่ภาษากอล์ฟที่ดีที่สุดและฉันไม่ใช่นักกอล์ฟที่เก่งที่สุด แต่มันสนุกมากที่ได้เขียนดังนั้นนี่คือ! แจ้งให้เราทราบเกี่ยวกับข้อบกพร่องและการปรับปรุง! (ฉันตัดสินใจที่จะส่งอีกครั้งเป็นเพียงฟังก์ชั่น)

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

และไฟล์ที่มีช่องว่างและความคิดเห็น:

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 นั่นอาจช่วยให้สามารถอ่านได้ ขอบคุณ (ใช้Alt+09หรือแท็บออกใน Notepad ++)
mbomb007

d[q]+=1;นี้จะกลายเป็นd[q]++;คุณสามารถเพิ่มโดยตรงบนอาร์เรย์แทนการใช้ + = ทุกที่ ที่ควรจะบันทึกพวงของตัวละคร
เข็มทิศ

@Compass ทำการเปลี่ยนแปลงไปแล้วขอบคุณแม้ว่า!
DeadChex

1
นอกจากนี้: for(;t>0;t--){ สามารถเปลี่ยนเป็นfor(;t-->0;){: D
Compass

ขอแสดงความยินดีกับกอล์ฟครั้งแรกของคุณที่นี่! : D ตอนนี้ .... เพียงแค่ทำการประกาศใหม่อีกครั้งและกลับมาใหม่ (แทนที่จะพิมพ์) ผลลัพธ์คุณสามารถทำให้มันลดลงได้เล็กน้อย อาจจะมีมากกว่าที่จะทำ แต่ฉันต้องไป นี่คือรุ่น 244 ไบต์: pastebin.com/TWAXvyHW
Geobits

4

Python 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 สำหรับการหาวิธีที่สั้นกว่าในการทำDและพิสูจน์อีกครั้งซึ่งnotมักจะเล่นกอล์ฟได้ และสำหรับการเขียนคำอธิบาย

ฉันพยายามสร้างโปรแกรมที่คล้ายกันใน Pyth แต่ดูเหมือนว่าจะมีปัญหาขอบเขตในสิ่งที่ฉันพยายามทำ การเล่นโดมิโนอย่างไร้เดียงสานี้สวยและฟังก์ชั่นUการแพร่กระจายของแผ่นดินไหว ทิศทางการลบในUไม่จำเป็นต้องมีตัวดัดแปลงเพราะมันจะพันกันตามธรรมชาติ องค์ประกอบสุดท้ายของการEนับจำนวนครั้งที่ศูนย์กลายเป็นหนึ่งดังนั้นมันจะไม่ถูกพิมพ์ในตอนท้าย

Ungolfed + คำอธิบาย:

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
การเปลี่ยนD[r]=not eเป็นD[r]=e<1ประหยัด 2 ไบต์และE=[0]*-~kเป็นการE=D+[0]ประหยัดอีก 2 เพื่อให้คุณได้ถึง 170
Kade

1

ES6, 224 196 189 179 172

สิ่งง่าย ๆ ได้รับการตีกอล์ฟ แต่ก็ยังมีงานที่ต้องทำ ฉันจะพิมพ์คำอธิบายในภายหลัง นอกจากนี้หากใครบางคนสามารถบอกฉันได้ว่าทำไมเรื่องสั้นถึงnew Date%kใช้งานไม่ได้อีกต่อไป

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}

การใช้งานคือ

f(10, 1000);

newคุณสามารถลบ คุณไม่ต้องการสิ่งนั้นtในการวนซ้ำไม่จำเป็นต้องใช้สองครั้งล่าสุด;
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer คุณเป็นฮีโร่ที่จะทำให้
Compass

a[r]^=1จะ defs ทำงานหากค่าเริ่มต้นเป็นอย่างใดอย่างหนึ่ง1หรือ0
เครื่องมือเพิ่มประสิทธิภาพ

1

Perl, 212

รุ่นก่อนหน้านี้ที่ฉันวางไว้ไม่ได้ห่ออย่างถูกต้องและการนำไปใช้นั้นใช้งานได้

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}

นี่อาจไม่ใช่อัลกอริทึมที่เหมาะสมสำหรับสิ่งนี้ แต่ฉันไม่สามารถคิดได้ตอนนี้ รุ่นที่ไม่ได้บรรจุอยู่ด้านล่าง

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 ไบต์

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

นี่มันไม่ค่อยมีการแข่งขัน แต่เนื่องจากฉันใช้เวลานานพอฉันจึงคิดว่าฉันจะโพสต์ต่อไป

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.

ลองออนไลน์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.