Eksperimen Celah Ganda

16

Seorang fisikawan yang malas memiliki tugas untuk melakukan eksperimen celah ganda. Namun, mereka malas dan tidak mau repot untuk mengatur semua peralatan sendiri dan akan mensimulasikan efeknya. Mereka tidak dapat memprogram meskipun begitu akan membutuhkan bantuan. Karena mereka malas, program Anda harus sesingkat mungkin.


Diberikan bilangan bulat positif ganjil n( n >= 1dan n % 2 == 1), lakukan simulasi.

Bagaimana itu bekerja

Anda akan mulai dengan kanvas kosong dan setiap frame satu partikel cahaya akan melewati celah dan mendarat di kanvas. Partikel akan mendarat pada maksimum dengan kemungkinan:

n = 1:

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

n = 3:

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

n = 5:

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

dll.

Misalnya untuk n=5kami memeriksa kotak tengah, ada kemungkinan 50% untuk jatuh di dalamnya. Jika jatuh dari frame, jika tidak pindah ke dua berikutnya, ada kemungkinan 25% jatuh pada mereka. Jika jatuh di akhir frame, jika tidak pindah ke dua berikutnya, ada kemungkinan 12,5% jatuh pada mereka. Jika tidak jatuh itu tidak masalah, itu masih merupakan akhir dari frame.

Ada beberapa kebingungan tentang bagaimana cara menghitung peluang, sebagian besar karena orang-orang menganggapnya sebagai probabilitas yang seharusnya bertambah hingga 1. Hapus ide itu dari pikiran Anda dan itu harus menjernihkannya sedikit untuk Anda.

  • Paling banyak satu partikel akan lad per frame, ini berarti sebuah partikel mungkin tidak mendarat sama sekali pada frame itu.
  • Sebuah partikel dapat diwakili oleh karakter yang dapat dicetak.
  • Partikel akan mendarat di mana saja di dalam kotak dengan peluang acak.
  • Lebar kotak harus 2n-1seukuran kanvas. Jadi untuk n=5mereka harus 1/9th dari lebar kanvas.
  • Ketinggian kotak harus setinggi kanvas.
  • Partikel tidak boleh mendarat di luar kotak sama sekali.
  • Jika sebuah partikel telah mendarat di tempat yang dipilih, tidak masalah ia bisa mendarat di sana lagi.
  • Kotak ascii di atas adalah untuk kejelasan, mereka tidak boleh ditarik.
  • Anda dapat memilih ukuran kanvas sendiri selama itu wajar. Misalnya, tingginya tidak boleh beberapa piksel. Itu juga harus dapat memenuhi semua kotak di atasnya.
  • Jika kode Anda tidur di antara frame, Anda tidak perlu menambahkannya ke jumlah byte Anda.

Harus ada celah di antara masing-masing maxima, minima. Ini harus sama lebar dengan kotak tetapi tidak ada partikel yang akan mendarat di sana. Lihat diagram berikut:

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

Program harus berjalan sampai dihentikan secara manual.

Aturan

  • Generator nomor acak semu (pRNG) baik-baik saja.
  • Celah standar dilarang.
  • Input dapat diambil dengan format apa pun yang wajar.
  • Anda harus output ke STDOUT.
  • Ini adalah sehingga jawaban terpendek menang.

Contoh

GIF berikut adalah contoh dijalankan untuk n = 5. Saya hanya mengetuknya dengan cepat sehingga peluangnya mungkin sedikit.

Contoh celah ganda

TheLethalCoder
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Martin Ender

Jawaban:

4

Python 2, 207 200 byte

Saya yakin ada metode untuk kegilaan ini. Mengikuti interpretasi probabilitas yang saya komentari di OP.

Sunting: -7 byte melalui beberapa evaluasi malas yang pintar (dan menghapus beberapa tanda)

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
algmyr
sumber
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

Sayangnya saya tidak dapat mendemonstrasikan ini di TryItOnline karena loop tanpa akhir & urutan pelarian ANSI yang memindahkan kursor, tetapi Anda masih dapat menyalin-menempelkannya ke terminal Anda!

Versi tidak minminasi:

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
Andrew Dunai
sumber
1
Lihatlah kiat untuk bermain golf di bash . Ada beberapa buah gantung rendah yang mudah untuk Anda panen di sini - misalnya, $[ ]bukan $(( )). Alih-alih for i in `seq $((($1+1)/2)) -1 1`;do ...;done, coba for((i=($1+1)/2;i>0;i--));{ ...;}. Alih-alih [ $(($RANDOM%2)) -eq 1 ], coba ((RANDOM%2)). sector,, SSdll harus diganti dengan 1 nama variabel char.
Digital Trauma
3

Mathematica, 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->" "]])&


memasukkan

[5]

keluaran

masukkan deskripsi gambar di sini

J42161217
sumber
Ini tampaknya tidak valid, karena n = 5 seharusnya hanya ada 5 kotak, Anda memiliki 9
TheLethalCoder
Saya menyadari bahwa saya menghitung seperti {... 3,2,1,2,3 ...}. Saya dapat memperbaikinya jika tidak diterima
J42161217
2
@TheLethalCoder Diperbaiki! Ditingkatkan! Golf!
J42161217
Terlihat bagus,
tersanjung
2

C # (.NET 4.5), 319 254 byte

Disimpan 65 byte berkat 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;}}}

Fiuh, itu banyak pekerjaan, tapi entah bagaimana berhasil.

Karena ini menggunakan Consolefungsi khusus dan Thread tidur, itu tidak akan berfungsi pada TIO, sayangnya.

Ian H.
sumber
Kompilasi ke an Action<int>untuk menyimpan byte, while(true)-> ( while(1>0)-> for(;;). using C=Console;Atau using static Console;.
TheLethalCoder
Aplikasi itu diizinkan untuk menjadi delegasi juga? Tidak tahu itu. Saya akan memperbaruinya dalam beberapa detik.
Ian H.
Program / fungsi diperbolehkan secara default dan lambdas anonim dihitung sebagai fungsi (Meskipun aturan tentang mereka menjadi sedikit lebih dalam ketika Anda perlu memanggil mereka).
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 Kode itu tidak berfungsi: / Hanya memberikan banyak Variable is not existing in the current contextkesalahan.
Ian H.
1

Clojure + Quil, 394 bytes

(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)))))))

Ya, tentu saja saya tidak menang, tetapi ini adalah latihan otak yang bagus! Saya mungkin telah memilih cara yang terlalu memutar untuk melakukan ini, tetapi itu berhasil! Pada dasarnya cara kerjanya adalah:

  1. Nilai x dari setiap kolom dihitung berdasarkan n. Kemudian, "colum aktif" yang akan berisi titik-titik disaring. Kolom kemudian dizip dengan kemungkinan bahwa mereka akan dipilih.

  2. Animasi dimulai, dan setiap frame, sebuah loop dimasukkan. Mulai dari tengah, setiap pasangan kolom dicoba. Setelah satu pasang kolom dipilih, satu kolom dari pasangan dipilih secara acak.

  3. Sebuah titik diambil pada posisi acak di dalam kolom yang dipilih, loop dalam keluar, dan bingkai baru dimulai.

Menggunakan perpustakaan grafis Quil, yang pada dasarnya adalah pembungkus Pemroses untuk Clojure.

Catatan, kode golf tidak menghasilkan animasi yang sama seperti yang ditunjukkan pada GIF. Dalam kode golf, latar belakang abu-abu, dan jendela dan titik lebih kecil. Ini memiliki efek yang sama, hanya saja tidak secantik itu.

GIF

Lihat kode yang tidak dipisahkan untuk penjelasan mendalam:

(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)))))))
Carcigenicate
sumber
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;}}}

Cobalah online! (Itu tidak akan berhasil tetapi kamu tahu).

Versi Lengkap / Terformat:

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