Thí nghiệm khe đôi


16

Một nhà vật lý lười biếng có công việc để thực hiện thí nghiệm khe đôi. Tuy nhiên, họ lười biếng và không thể bận tâm để tự thiết lập tất cả các thiết bị và do đó sẽ mô phỏng các hiệu ứng. Họ không thể lập trình mặc dù vậy sẽ cần một số trợ giúp. Vì họ lười nên chương trình của bạn nên càng ngắn càng tốt.


Cho một số nguyên dương lẻ n( n >= 1n % 2 == 1), thực hiện mô phỏng.

Làm thế nào nó hoạt động

Bạn sẽ bắt đầu với một khung vẽ trống và mỗi khung hình, một hạt ánh sáng sẽ đi qua các khe và hạ cánh trên khung vẽ. Hạt sẽ hạ cánh ở cực đại với cơ hội:

n = 1:

+-----+
|     |
| 1/2 |
|     |
+-----+

n = 3:

+-----+ +-----+ +-----+
|     | |     | |     |
| 1/4 | | 1/2 | | 1/4 |
|     | |     | |     |
+-----+ +-----+ +-----+

n = 5:

+-----+ +-----+ +-----+ +-----+ +-----+
|     | |     | |     | |     | |     |
| 1/8 | | 1/4 | | 1/2 | | 1/4 | | 1/8 |
|     | |     | |     | |     | |     |
+-----+ +-----+ +-----+ +-----+ +-----+

Vân vân.

Ví dụ: đối với n=5chúng tôi kiểm tra hộp giữa, có 50% khả năng rơi vào đó. Nếu nó rơi vào cuối khung hình, nếu không chuyển sang hai khung hình tiếp theo, sẽ có 25% khả năng rơi vào những khung hình đó. Nếu nó rơi vào cuối khung hình, nếu không chuyển sang hai khung hình tiếp theo, sẽ có 12,5% cơ hội rơi vào những khung hình đó. Nếu nó không rơi thì không thành vấn đề, nó vẫn là phần cuối của khung.

Đã có một số nhầm lẫn về cách tính toán các cơ hội, hầu hết điều này là do mọi người nghĩ về chúng như xác suất nên tăng lên 1. Loại bỏ ý tưởng đó khỏi tâm trí của bạn và nó sẽ làm sáng tỏ một chút cho bạn.

  • Nhiều nhất một hạt sẽ xếp trên mỗi khung, điều này có nghĩa là một hạt có thể không hạ cánh hoàn toàn trên khung đó.
  • Một hạt có thể được đại diện bởi bất kỳ ký tự có thể in.
  • Các hạt sẽ hạ cánh bất cứ nơi nào trong hộp với một cơ hội ngẫu nhiên.
  • Chiều rộng của các hộp phải là 2n-1kích thước của khung vẽ. Vì vậy, đối với n=5họ nên là 1/9chiều rộng của khung vẽ.
  • Chiều cao của các hộp phải là chiều cao của khung vẽ.
  • Các hạt không nên hạ cánh bên ngoài các hộp.
  • Nếu một hạt đã hạ cánh tại một điểm được chọn mà không quan trọng thì nó có thể hạ cánh trở lại.
  • Các hộp ascii ở trên là cho rõ ràng, chúng không nên được rút ra.
  • Bạn có thể chọn kích thước vải của riêng bạn miễn là hợp lý. Ví dụ, nó không chỉ cao vài pixel. Nó cũng có thể phù hợp với tất cả các hộp trên đó.
  • Nếu mã của bạn ngủ giữa các khung, bạn không cần thêm mã đó vào số byte của mình.

Cần có khoảng cách giữa mỗi cực đại, cực tiểu. Cái này phải có cùng chiều rộng với một cái hộp nhưng không có hạt nào rơi xuống đó. Xem sơ đồ sau:

+---+---+---+---+---+
|   |   |   |   |   |
|max|min|max|min|max|
|   |   |   |   |   |
+---+---+---+---+---+

Chương trình sẽ chạy cho đến khi nó được dừng bằng tay.

Quy tắc

  • Một trình tạo số ngẫu nhiên giả (pRNG) là tốt.
  • Sơ hở tiêu chuẩn bị cấm.
  • Đầu vào có thể được thực hiện bởi bất kỳ định dạng hợp lý.
  • Bạn nên xuất ra STDOUT.
  • Đây là nên câu trả lời ngắn nhất sẽ thắng.

Thí dụ

GIF sau đây là một ví dụ chạy cho n = 5. Tôi chỉ gõ nó nhanh lên để cơ hội có thể tắt đi một chút.

Ví dụ khe đôi


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Martin Ender

Câu trả lời:


4

Python 2, 207 200 byte

Có một phương pháp cho sự điên rồ này, tôi hứa. Theo giải thích xác suất tôi đã nhận xét trong OP.

Chỉnh sửa: -7 byte thông qua một số đánh giá lười biếng thông minh (và loại bỏ một số dấu hiệu)

import time  # not counted for byte total
import random as R,curses as C
r=R.randint
c=C.initscr()
h,w=c.getmaxyx()
n=input()
w/=2*n-1
while 1:
 all(r(0,1)or c.addch(r(0,h-1),(i*(2-4*r(0,1))+n)*w-r(1,w),42)for i in range(n/2+1))
 c.refresh()
 time.sleep(0.1)  # not counted for byte total

4

BASH, 396 - 11 = 385 byte

E='echo -en';$E "\e[2J\e[99A";while :;do sleep 0.01;for i in `seq $((($1+1)/2)) -1 1`;do p=$(((($1+1)/2 - $i)));[ $p -lt 0 ]&&p=$((-$p));p=$((2**(p+1)));if [ $RANDOM -lt $((32768/$p)) ];then [ $(($RANDOM%2)) -eq 1 ]&&i=$((($1+1)-i));sector=$(((i*2-1)-1));C=`tput cols`;R=`tput lines`;SS=$((C/($1*2-1)));SX=$((SS*sector));X=$((SX+(RANDOM%SS)));Y=$((RANDOM%R));$E "\e[$Y;${X}H*";break;fi;done;done

Thật không may, tôi không thể chứng minh điều này trên TryItOnline vì các chuỗi thoát vô tận & vòng lặp ANSI di chuyển con trỏ, nhưng bạn vẫn có thể sao chép-dán nó vào thiết bị đầu cuối của mình!

Phiên bản chưa hoàn thành:

E='echo -en'
$E "\e[2J\e[99A"

while :
do
    sleep 0.01
    for i in `seq $((($1+1)/2)) -1 1`
    do
        p=$(((($1+1)/2 - $i)))
        [ $p -lt 0 ] && p=$((-$p));
        p=$((2**(p+1)))
        if [ $RANDOM -lt $((32768/$p)) ]
        then
            [ $(($RANDOM%2)) -eq 1 ] && i=$((($1+1)-i));
            sector=$(((i*2-1)-1))
            C=`tput cols`
            R=`tput lines`
            SS=$((C/($1*2-1)))
            SX=$((SS*sector))
            X=$((SX+(RANDOM%SS)))
            Y=$((RANDOM%R))
            $E "\e[$Y;${X}H*"
            break
        fi
    done
done

1
Kiểm tra các mẹo để chơi golf trong bash . Có khá nhiều loại trái cây treo thấp dễ dàng để bạn thu hoạch ở đây - ví dụ $[ ]thay vì $(( )). Thay vì for i in `seq $((($1+1)/2)) -1 1`;do ...;done, hãy thử for((i=($1+1)/2;i>0;i--));{ ...;}. Thay vì [ $(($RANDOM%2)) -eq 1 ], hãy thử ((RANDOM%2)). sector, SSv.v ... nên được thay thế bằng 1 tên biến char.
Chấn thương kỹ thuật số

3

Toán học, 231 byte

(R=RandomInteger;p=20(#+1)+10;s=Array[0&,{20,6p-3}];i=(#+1)/2;Monitor[While[1<2,y=RandomChoice[Join[q=Riffle[Array[2^#&,i,0],Table[0,i-1]],Reverse@Most@q]->Array[Range[4#+1]&,i,0][[i]]];s[[R@19+1,10y-R@9]]=1;s],Grid[s//. 0->" "]])&


đầu vào

[5]

đầu ra

nhập mô tả hình ảnh ở đây


Điều này dường như không hợp lệ, vì n = 5 chỉ nên có 5 hộp, bạn có 9
TheLethalCoder

Tôi nhận ra rằng tôi đã tính như {... 3,2,1,2,3 ...}. Tôi có thể sửa nó nếu nó không được chấp nhận
J42161217

2
@TheLethalCoder đã sửa! Cải thiện! Chơi gôn!
J42161217

Có vẻ tốt, upvote từ tôi
TheLethalCoder

2

C # (.NET 4.5), 319 254 byte

Đã lưu 65 byte nhờ TheLethalCoder!

namespace System{using static Console;n=>{for(var r=new Random();;)for(int w=WindowWidth/(2*n-1),i=(n-1)/2,c=0,m=2,l;i>-1;i--,c+=2)if((l=r.Next(0,(m*=2+1)*2))<2){SetCursorPosition((i+(l<1?c:0))*2*w+r.Next(0,w),r.Next(0,WindowHeight));Write('*');break;}}}

Phew, đó là rất nhiều công việc, nhưng nó hoạt động bằng cách nào đó.

Vì điều này sử dụng Consolecác chức năng cụ thể và ngủ theo chủ đề, nên nó sẽ không hoạt động trên TIO.


Biên dịch thành một Action<int>để lưu byte, while(true)-> ( while(1>0)-> for(;;). using C=Console;Hoặc using static Console;.
TheLethalCoder

Ứng dụng đó có được phép làm đại biểu không? Không biết điều đó. Tôi sẽ cập nhật nó trong giây lát.
Ian H.

Các chương trình / chức năng được cho phép theo mặc định và lambdas ẩn danh được tính là các chức năng (Mặc dù các quy tắc về chúng sẽ sâu hơn một chút khi bạn cần gọi chúng).
TheLethalCoder

255 bytenamespace System{using static Console;n=>{for(var r=new Random();;)for(int w=WindowWidth/(2*n-1),i=(n-1)/2,c=0,m=2,l;i>-1;i--,c+=2)if((l =r.Next(0,(m*=2+1)*2))<2){SetCursorPosition((i+(l<1?c:0))*2*w+r.Next(0,w),r.Next(0,WindowHeight));Write('*');break;}}}
TheLethalCoder

@TheLethalCoder Mã đó không hoạt động: / Chỉ đưa ra rất nhiều Variable is not existing in the current contextlỗi.
Ian H.

1

Clojure + Quil, 394 byte

(use '[quil.core])(defn -main[n](let[w 999 h 100 c(/ w(-(* n 2)1))s(range 0 w c)a(vec(take-nth 2 s))v(fn[x](<(rand)x))q(fn[a b](+ a(rand-int(- b a))))g(for[i(range(int(/ n 2))-1 -1)][i(- n 1 i)])z(for[[j i](map vector(range 1(inc(count g)))g)][(/ 1(Math/pow 2 j))i])](defsketch m :size[w h]:draw #(loop[[[p i]& r]z](when p(if(v p)(let[o(a(rand-nth i))](point(q o(+ o c))(q 0 h)))(recur r)))))))

Chà, tôi chắc chắn đã không chiến thắng, nhưng đây là một bài tập trí não tốt! Tôi có thể đã chọn một cách làm tròn quá mức để làm điều này, nhưng nó hoạt động! Về cơ bản, cách thức hoạt động của nó là:

  1. Giá trị x của mỗi cột được tính toán dựa trên n. Sau đó, "colums hoạt động" sẽ chứa các dấu chấm được lọc ra. Các cột sau đó được nén với các khả năng mà chúng sẽ được chọn.

  2. Hoạt hình bắt đầu và mỗi khung hình, một vòng lặp được nhập vào. Bắt đầu từ giữa, từng cặp cột được thử. Khi một cặp cột được chọn, một cột trong cặp được chọn ngẫu nhiên.

  3. Một dấu chấm được vẽ tại một vị trí ngẫu nhiên trong cột đã chọn, vòng lặp bên trong thoát ra và một khung mới bắt đầu.

Sử dụng thư viện đồ họa Quil, về cơ bản là một trình bao bọc Xử lý cho Clojure.

Lưu ý, mã đánh gôn không tạo ra hình ảnh động giống như trong GIF. Trong mã đánh gôn, nền màu xám và cửa sổ và các chấm nhỏ hơn. Nó có tác dụng tương tự, nó không đẹp bằng.

QUÀ TẶNG

Xem mã không mã hóa để được giải thích sâu hơn:

(ns bits.golf.interference.interference
  (:require [quil.core :as q]))

; Canvas size
(def width 1800)
(def height 800)

(defn -main [n]
  (let [col-width (/ width (- (* n 2) 1))
        ; The left-most x of each column
        col-starts (range 0 width col-width)

        ; The columns that need to be drawn. Need "vec" so I can index it later.
        active-cols (vec (take-nth 2 col-starts))

        ; Function taking a decimal percentage, and returning whether or not it's satisfied.
        ; (chance? 0.5) would be used to simulate a coin toss.
        chance? (fn [perc] (< (rand) perc))

        ; Function that returns a random int between a and b
        r-int (fn [a b] (+ a (rand-int (- b a))))

        ; Generates index pairs for each complimentary column.
        indices (for [i (range (int (/ n 2)) -1 -1)]
                  [i (- n 1 i)])

        ; Zips each index pair from above with the chance that it will be" chosen"
        zipped-perc (for [[j i] (map vector (range 1 (inc (count indices))) indices)]
                      [(/ 1 (Math/pow 2 j)) i])]

    ; Animation boilerplate
    (q/defsketch Interference
      :size [width height]
      :draw
      ; The animation loop. It contains a loop over each complimentary column. It tries each column pair starting
      ;  from the middle, and works outward. Once it picks a pair of columns, it randomly chooses one of them.
      #(loop [[[p i] & r] zipped-perc]
         (when p
           ; Pick this column?
           (if (chance? p)
             ; Pick one of the column pairs
             (let [col (active-cols (rand-nth i))]
               ; Set the coloring and dot size
               (q/fill 0 0 0)
               (q/stroke-weight 5)
               ; And finally draw the dot
               (q/point (r-int col (+ col col-width))
                        (r-int 0 height)))

             ; If the column wasn't chosen, loop again to try the next one
             (recur r)))))))

0

C #, 238 byte

namespace System{using static Console;n=>{for(var r=new Random();;)for(int i=0,p=1,w=WindowWidth/(2*n-1),x;i<n+1;i+=2)if(r.Next(p*=2)<1){SetCursorPosition(r.Next(x=(n-1+(r.Next(2)<1?i:-i))*w,x+w),r.Next(WindowHeight));Write("*");break;}}}

Hãy thử trực tuyến! (Nó sẽ không hoạt động nhưng bạn biết).

Phiên bản đầy đủ / được định dạng:

namespace System
{
    using static Console;

    class P
    {
        static void Main()
        {
            Action<int> f = n =>
            {
                for (var r = new Random(); ;)
                {
                    for (int i = 0, p = 1, w = WindowWidth / (2 * n - 1), x; i < n + 1; i += 2)
                        if (r.Next(p *= 2) < 1)
                        {
                            SetCursorPosition(r.Next(x = (n - 1 + (r.Next(2) < 1 ? i : -i)) * w, x + w), r.Next(WindowHeight));
                            Write("*");
                            break;
                        }

                    Threading.Thread.Sleep(25);
                }
            };

            f(5);
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.