Das Doppelspaltexperiment


16

Ein fauler Physiker hat die Aufgabe, das Doppelspaltexperiment durchzuführen. Sie sind jedoch faul und können nicht die Mühe machen, alle Geräte selbst einzurichten, und werden daher die Auswirkungen simulieren. Sie können jedoch nicht programmieren und brauchen Hilfe. Da sie faul sind, sollte Ihr Programm so kurz wie möglich sein.


Führen Sie bei einer ungeraden positiven Ganzzahl n( n >= 1und n % 2 == 1) die Simulation durch.

Wie es funktioniert

Sie beginnen mit einer leeren Leinwand, und in jedem Rahmen geht ein einzelnes Lichtteilchen durch die Schlitze und landet auf der Leinwand. Das Partikel landet mit einer Wahrscheinlichkeit von:

n = 1:

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

n = 3:

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

n = 5:

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

etc.

Zum Beispiel, wenn n=5wir das mittlere Kästchen überprüfen, besteht eine 50% ige Wahrscheinlichkeit, dass wir hineinfallen. Wenn es das Ende des Frames erreicht, oder wenn es nicht zu den nächsten beiden wechselt, besteht eine 25% ige Chance, dass es in diese fällt. Wenn es das Ende des Frames erreicht, wenn es nicht zu den nächsten beiden wechselt, besteht eine Wahrscheinlichkeit von 12,5%, dass es in diese fällt. Wenn es nicht fällt, spielt es keine Rolle, es ist immer noch das Ende des Rahmens.

Es gab einige Unklarheiten darüber, wie man die Chancen berechnet. Die meisten davon sind darauf zurückzuführen, dass die Leute sie als Wahrscheinlichkeiten ansehen, die sich zu 1 addieren sollten. Entfernen Sie diese Idee aus Ihrem Kopf und sie sollte für Sie ein wenig klarer werden.

  • Es wird höchstens ein Partikel pro Frame geladen. Dies bedeutet, dass ein Partikel möglicherweise überhaupt nicht auf diesem Frame landet.
  • Ein Partikel kann durch ein beliebiges druckbares Zeichen dargestellt werden.
  • Das Partikel landet irgendwo in der Box mit einer zufälligen Chance.
  • Die Breite der Kästchen sollte 2n-1der Größe der Leinwand entsprechen. Also für n=5sie sein sollten 1/9th der Leinwand Breite.
  • Die Höhe der Kästchen sollte der Höhe der Leinwand entsprechen.
  • Das Partikel sollte überhaupt nicht außerhalb der Boxen landen.
  • Wenn ein Partikel bereits an einer Stelle gelandet ist, die ausgewählt wurde und keine Rolle spielt, kann es dort erneut landen.
  • Die obigen ASCII-Felder dienen der Übersichtlichkeit und sollten nicht gezeichnet werden.
  • Sie können Ihre eigene Leinwandgröße wählen, solange dies angemessen ist. Zum Beispiel darf es nicht nur ein paar Pixel hoch sein. Es sollte auch in der Lage sein, alle Kästen darauf zu passen.
  • Wenn Ihr Code zwischen Frames ruht, müssen Sie dies nicht zu Ihrer Byteanzahl hinzufügen.

Zwischen jedem der Maxima und Minima sollten Lücken bestehen. Dies sollte die gleiche Breite wie eine Kiste haben, aber dort werden keine Partikel landen. Siehe folgendes Diagramm:

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

Das Programm sollte so lange ausgeführt werden, bis es manuell gestoppt wird.

Regeln

  • Ein Pseudozufallszahlengenerator (pRNG) ist in Ordnung.
  • Standardlücken sind verboten.
  • Die Eingabe kann in jedem vernünftigen Format erfolgen.
  • Sie sollten auf STDOUT ausgeben.
  • Das ist also gewinnt die kürzeste Antwort.

Beispiel

Das folgende GIF ist ein Beispiellauf für n = 5. Ich habe es nur schnell geklopft, damit die Chancen etwas nachlassen.

Doppelspalt Beispiel


Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
Martin Ender

Antworten:


4

Python 2, 207 200 Bytes

Ich verspreche, dass dieser Wahnsinn eine Methode hat. Folgt der Wahrscheinlichkeitsinterpretation, die ich im OP kommentiert habe.

Bearbeiten: -7 Bytes durch einige clevere faule Auswertung (und einige Zeichen entfernen)

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 Bytes

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

Leider kann ich dies auf TryItOnline nicht demonstrieren, da der Cursor durch Endlosschleifen- und ANSI-Escape-Sequenzen bewegt wird, aber Sie können es trotzdem kopieren und in Ihr Terminal einfügen!

Unbegrenzte Version:

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
Lesen Sie die Tipps zum Golfen in Bash . Hier gibt es einige leicht hängende Früchte, die Sie ernten können - z . B. $[ ]statt $(( )). for i in `seq $((($1+1)/2)) -1 1`;do ...;doneVersuchen Sie es stattdessen for((i=($1+1)/2;i>0;i--));{ ...;}. [ $(($RANDOM%2)) -eq 1 ]Versuchen Sie es stattdessen ((RANDOM%2)). sector, SSSollte usw. mit 1 Zeichen Variablennamen ersetzt werden.
Digital Trauma

3

Mathematica, 231 Bytes

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


Eingang

[5]

Ausgabe

Bildbeschreibung hier eingeben


Dies scheint ungültig zu sein, für n = 5 sollte es nur 5 Kästchen geben, Sie haben 9
TheLethalCoder

Ich habe festgestellt, dass ich wie {... 3,2,1,2,3 ...} gezählt habe. Ich kann es beheben, wenn es nicht akzeptiert wird
J42161217

2
@TheLethalCoder Behoben! Verbessert! Golf gespielt!
J42161217

Sieht gut aus, stimmt mir zu
TheLethalCoder

2

C # (.NET 4.5), 319 254 Bytes

65 Bytes gespart dank 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;}}}

Puh, das war eine Menge Arbeit, aber es funktioniert irgendwie.

Da dies Consolebestimmte Funktionen und den Thread-Ruhezustand verwendet, funktioniert es unter TIO leider nicht.


Kompilieren Sie in ein Action<int>, um Bytes zu speichern. while(true)-> ( while(1>0)-> for(;;). using C=Console;Oder using static Console;.
TheLethalCoder

Darf dieser Antrag auch ein Delegierter sein? Wusste das nicht. Ich werde es in einer Sekunde aktualisieren.
Ian H.

Programme / Funktionen sind standardmäßig erlaubt und anonyme Lambdas gelten als Funktionen (obwohl die Regeln für sie ein bisschen tiefer gehen, wenn Sie sie aufrufen müssen).
TheLethalCoder

255 Bytesnamespace 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 Dieser Code funktioniert nicht: / Gibt nur eine Menge Variable is not existing in the current contextFehler aus.
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)))))))

Nun, ich habe auf keinen Fall gewonnen, aber das war ein gutes Gehirntraining! Ich habe mich vielleicht für einen übermäßigen Umweg entschieden, aber es funktioniert! Grundsätzlich funktioniert es wie folgt:

  1. Die x-Werte jeder Spalte werden basierend auf berechnet n. Dann werden die "aktiven Spalten", die die Punkte enthalten, herausgefiltert. Die Spalten werden dann mit den Möglichkeiten, die sie ausgewählt werden, komprimiert.

  2. Die Animation startet und für jedes Bild wird eine Schleife eingegeben. Ausgehend von der Mitte wird jedes Spaltenpaar ausprobiert. Sobald ein Spaltenpaar ausgewählt ist, wird eine Spalte aus dem Paar zufällig ausgewählt.

  3. Ein Punkt wird an einer zufälligen Position in der ausgewählten Spalte gezeichnet, die innere Schleife wird beendet und ein neuer Frame beginnt.

Verwendet die Quil-Grafikbibliothek, die im Wesentlichen ein Verarbeitungswrapper für Clojure ist.

Beachten Sie, dass der Golf-Code nicht die gleiche Animation wie im GIF erzeugt. Im Golfcode ist der Hintergrund grau und das Fenster und die Punkte sind kleiner. Es hat den gleichen Effekt, es ist einfach nicht so hübsch.

GIF

Eine ausführliche Erklärung finden Sie im ungolfed-Code:

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

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

Probieren Sie es online! (Es wird nicht funktionieren, aber weißt du).

Voll / Formatierte Version:

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);
        }
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.