CSharp · Console
using System;
public class Program
{
private static readonly Random Random = new Random();
// Элементарная частица (к примеру, фотон)
public class Particle
{
private Particle _superluminalChannel; // Организация связи с второй запутанной частицей по сверхсветовому каналу.
private int? _measuredPosition;
public bool? A { get; private set; } // Проекция спина на ось X
public bool? B { get; private set; } // Проекция спина на ось Y
public bool? C { get; private set; } // Проекция спина на ось Z
internal void CreateSuperluminalChannelWith(Particle particle)
{
_superluminalChannel = particle;
}
// Получаем значение с учетом позиции переключателя на датчике (всего 3 позиции).
public bool GetValue(int sensorPosition)
{
if (null != _measuredPosition)
throw new InvalidOperationException("Измерить можно только один раз!");
_measuredPosition = sensorPosition;
if (null != _superluminalChannel._measuredPosition) // если другая запутанная частица уже была измеряна
{
var measuredValue = _superluminalChannel.GetNakedValue();
// Если измеряли тот же параметр у другой частицы (позиция переключателя на датчиках совпала), то возвращаем значение, противоположное значению уже измерянной частицы.
if (sensorPosition == _superluminalChannel._measuredPosition)
return !measuredValue;
if (GetRandomInteger(1, 4) == 1)
return !measuredValue;
return measuredValue;
}
// Установка значения. Происходит в момент измерения с нарушением принципа причинности, никакие причины на значение не влияли - чистый рандом.
// Детерминизм терпит крах!
var value = GetRandomBoolean();
SetValue(sensorPosition, value);
return value;
}
private bool GetNakedValue() // Запутанная частица получает значение частицы по сверхсветовому каналу уже после того, как было произведено измерение.
{
if (null == _measuredPosition)
throw new InvalidOperationException();
switch (_measuredPosition.Value)
{
case 1:
return A.Value;
case 2:
return B.Value;
case 3:
return C.Value;
default:
throw new InvalidOperationException();
}
}
private void SetValue(int position, bool value)
{
switch (position)
{
case 1:
A = value;
break;
case 2:
B = value;
break;
case 3:
C = value;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
// Пара запутанных частиц
public class EntanglementParticles
{
public Particle First { get; private set; } // Первая частица
public Particle Second { get; private set; } // Вторая частица
// Создание пары запутанных частиц (значения не установлены, находятся в суперпозиции)
public EntanglementParticles()
{
First = new Particle(); // значения не установлены, находятся в суперпозиции
Second = new Particle(); // значения не установлены, находятся в суперпозиции
// Частицы имеют возможность общаться по сврехсветовому каналу связи
First.CreateSuperluminalChannelWith(Second);
Second.CreateSuperluminalChannelWith(First);
}
}
public static void Main(string[] args)
{
Experiment1();
Experiment2();
}
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); // нам удобнее указывать с какого числа по какое включительно
}
}