CSharp · Console
using System;
public class Program
{
private static readonly Random Random = new Random();
// Элементарная частица (к примеру, фотон)
public class Particle
{
private bool _measured = false;
public bool A { get; private set; } // Проекция спина на ось X
public bool B { get; private set; } // Проекция спина на ось Y
public bool C { get; private set; } // Проекция спина на ось Z
public Particle(bool a, bool b, bool c)
{
A = a;
B = b;
C = c;
}
// Получаем значение с учетом позиции переключателя на датчике (всего 3 позиции).
public bool GetValue(int sensorPosition)
{
if (_measured)
throw new InvalidOperationException("Измерить можно только один раз!");
_measured = true;
switch (sensorPosition)
{
case 1:
return A;
case 2:
return B;
case 3:
return C;
default:
throw new ArgumentOutOfRangeException();
}
}
}
// Пара запутанных частиц
public class EntanglementParticles
{
public Particle First { get; private set; } // Первая частица
public Particle Second { get; private set; } // Вторая частица
// Создание пары запутанных частиц (пока верим в детерминизм, считаем что с каждая частица имеет установленное значение до измерения)
public EntanglementParticles()
{
var a = GetRandomBoolean();
var b = GetRandomBoolean();
var c = GetRandomBoolean();
First = new Particle(a, b, c); // устанавливаем случайные значения
Second = new Particle(!a, !b, !c); // устанавливаем значения, противоположные первой частице
}
}
public static void Main(string[] args)
{
Experiment1(); // Эксперимент 1 по Мермину
Experiment2(); // Эксперимент 2 по Мермину
}
private static void Experiment1()
{
var totalAttempts = 10000; // всего измерений
var disparityCount = 0; // сколько значений не совпало
for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
{
var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
var position = GetRandomInteger(1, 3); // Выбираем позицию переключателя на датчике случайным образом
// Первый и второй датчик устанавливаем в одну и ту же позицию
int firstSensorPosition = position;
int secondSensorPosition = position;
bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
if (firstValue != secondValue) // подсчет количества не совпавших значений
disparityCount++;
}
Console.WriteLine("Эксперимент №1: {0}% значений не совпало", (decimal)disparityCount / totalAttempts * 100); // все не совпали
}
private static void Experiment2()
{
var totalAttempts = 10000; // всего измерений
var disparityCount = 0; // сколько значений не совпало
for (int attemptNumber = 1; attemptNumber <= totalAttempts; attemptNumber++)
{
var entanglementParticles = new EntanglementParticles(); // Зарождение пары запутанных частиц
int firstSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 1
int secondSensorPosition = GetRandomInteger(1, 3); // Случайным образом устанавливаем позицию датчика 2
bool firstValue = entanglementParticles.First.GetValue(firstSensorPosition); // Значение первой частицы с учетом позиции первого датчика
bool secondValue = entanglementParticles.Second.GetValue(secondSensorPosition); // Значение второй частицы с учетом позиции второго датчика
if (firstValue != secondValue) // подсчет количества не совпавших значений
disparityCount++;
}
Console.WriteLine("Эксперимент №2: {0}% значений не совпало", (decimal)disparityCount / totalAttempts * 100);
}
// Вспомогательные функции
private static bool GetRandomBoolean()
{
return GetRandomInteger(0, 1) == 1;
}
private static int GetRandomInteger(int from, int to)
{
return Random.Next(from, to + 1); // нам удобнее указывать с какого числа по какое включительно
}
}