Физика цепочек


21

Задний план

Да, физика цепочек - это реальная вещь . Идея состоит в том, чтобы построить новую теорию физики, используя только цепочки битов, которые развиваются по вероятностному правилу ... или что-то в этом роде. Несмотря на чтение нескольких статей об этом, я все еще в замешательстве. Тем не менее, вселенная битрейн делает для милого маленького кода гольф.

Программа Вселенная

Физика цепочек происходит в так называемой программной вселенной . На каждом этапе эволюции вселенной существует конечный список Lцепочек битов некоторой длины k, начиная с двухэлементного списка [10,11]где k = 2. Один временной шаг обрабатывается следующим образом (в Python-подобном псевдокоде).

A := random element of L
B := random element of L
if A == B:
    for each C in L:
        append a random bit to C
else:
    append the bitwise XOR of A and B to L

Все случайные выборы равномерно случайны и не зависят друг от друга.

пример

Пример эволюции из 4 шагов может выглядеть следующим образом. Начнем с начального списка L:

10
11

Мы выбираем случайным образом A := 10и B := 10, которые являются одной и той же строкой, что означает, что нам нужно расширить каждую строку Lслучайным битом:

101
110

Далее мы выбираем A := 101и B := 110, и поскольку они не равны, мы добавляем их XOR к L:

101
110
011

Затем мы выбираем A := 011и B := 110, и снова добавляем их XOR:

101
110
011
101

Наконец, мы выбираем A := 101(последний ряд) и B := 101(первый ряд), которые равны, поэтому мы расширяем со случайными битами:

1010
1100
0111
1010

Задание

Ваша задача - принять неотрицательное целое число в tкачестве входных данных, смоделировать программный юниверс для tвременных шагов и вернуть или распечатать полученный список L. Обратите внимание, что t = 0результаты в начальном списке [10,11]. Вы можете вывести Lкак список списков целых чисел, список списков логических значений или список строк; если вывод идет в STDOUT, вы можете также распечатать битовые строки по одной на строку в некотором приемлемом формате. Порядок цепочек битов значителен; в частности, первоначальный список не может быть [11,10], [01,11]или что-то в этом роде. Приемлемы как функции, так и полные программы, стандартные лазейки запрещены, и побеждает меньшее количество байтов.


Можем ли мы ограничить длину строки битов (то есть: могу ли я использовать 32-битные числа и битовые операции)?
edc65

1
@ edc65 Нет, длина строк может быть сколь угодно высокой.
Згарб

3
@ edc65 Ожидаемое время и требования к памяти для получения более 32 бит астрономические, но это просто соответствует, так как мы моделируем вселенную. ;)
Згарб

5
Является ли эта физика битовых струн идеей сумасшедшего? Я не читал всю статью, но фраза « Мы использовали физику струнных струн», чтобы дать теорию, в которой приближение hbar c / e2 = 22 - 1 + 23 - 1 + 27 - 1 = 137 имеет смысл с точки зрения компьютерный алгоритм и теория информации кажутся мне немного ... нумерологическими.
xebtl

1
@ xebtl Мне это тоже кажется сумасшедшим. Я помню, как где-то читал обоснование алгоритма, и это звучало скорее как плохая псевдофилософия, чем физика. Кроме того, ваше описание алгоритма, кажется, соответствует моей версии, может быть, я каким-то образом неправильно вас понимаю.
Згарб

Ответы:


7

Pyth, 27 26 байтов

u?+RO2GqFKmOG2aGxVFKQ*]1U2

Попробуйте онлайн: демонстрация

Объяснение:

                              implicit: Q = input number
                     *]1U2    the initial list [[1,0], [1,1]]
u                   Q         reduce, apply the following expression Q times to G = ^
          mOG2                  take two random elements of G
         K                      store in K
       qF                       check if they are equal
 ?                              if they are equal:
  +RO2G                           append randomly a 0 or 1 to each element of G
                                else:
              aG                  append to G
                xVFK              the xor of the elements in K

xVFKэквивалентно xMK.
Исаак

@isaacg Нет, xVFKэквивалентно тому xMCKже количеству байтов.
Якуб

11

CJam, 42 40 38 37 байт

1 байт сохранен Sp3000.

B2b2/q~{:L_]:mR_~#L@~.^a+L{2mr+}%?}*p

объяснение

Создайте начальное состояние как число base-2:

B2b e# Push the the binary representation of 11: [1 0 1 1]
2/  e# Split into chunks of 2 to get [[1 0] [1 1]]

А затем выполните основной цикл и напечатайте результат в конце:

q~       e# Read and eval input t.
{        e# Run this block t times.
  :L     e#   Store the current universe in L.
  _]     e#   Copy it and wrap both copies in an array.
  :mR    e#   Pick a random element from each copy.
  _~     e#   Duplicate those two elements, and unwrap them.
  #      e#   Find the second element in the first. If they are equal, it will be found at
         e#   index 0, being falsy. If they are unequal, it will not be found, giving
         e#   -1, which is truthy.

         e#   We'll now compute both possible universes for the next step and then select
         e#   the right one based on this index. First, we'll build the one where they were
         e#   not equal.

  L@~    e#   Push L, pull up the other copy of the selected elements and unwrap it.
  .^     e#   Take the bitwise XOR.
  a+     e#   Append this element to L.

  L      e#   Push L again.
  {      e#   Map this block onto the elements in L.
    2mr+ e#     Append 0 or 1 at random. 
  }%     
  ?      e#   Select the correct follow-up universe.
}*
p        e# Pretty-print the final universe.

Проверьте это здесь.


6

Юлия, 141 129 байт

t->(L=Any[[1,0],[1,1]];for i=1:t r=1:length(L);A=L[rand(r)];B=L[rand(r)];A==B?for j=r L[j]=[L[j],rand(0:1)]end:push!(L,A$B)end;L)

Ничего умного. Создает безымянную функцию, которая принимает целое число в качестве входных данных и возвращает массив массивов. Чтобы назвать его, дайте ему имя, например f=t->....

Ungolfed + объяснение:

function f(t)
    # Start with L0
    L = Any[[1,0], [1,1]]

    # Repeat for t steps
    for i = 1:t
        # Store the range of the indices of L
        r = 1:length(L)

        # Select 2 random elements
        A = L[rand(r)]
        B = L[rand(r)]

        if A == B
            # Append a random bit to each element of L
            for j = r
                L[j] = [L[j], rand(0:1)]
            end
        else
            # Append the XOR of A and B to L
            push!(L, A $ B)
        end
    end

    # Return the updated list
    L
end

Примеры:

julia> f(4)
4-element Array{Any,1}:
 [1,0,1,0]
 [1,1,1,1]
 [0,1,1,0]
 [0,1,0,0]

julia> f(3)
3-element Array{Any,1}:
 [1,0,1,1]
 [1,1,1,0]
 [0,1,0,1]

Сохранено 12 байтов благодаря ML!


Вы можете сократить его до 133 символов, если вы используете оператор терне вместо if / else и если вы измените A=something;B=something else to A,B=something,something else:t->(L=Any[[1,0],[1,1]];for i=1:t r=1:length(L);A,B=L[rand(r)],L[rand(r)];A==B?(for j=r L[j]=[L[j],rand(0:1)]end):(push!(L,A$B))end;L)
ML

@ML: Хорошо, спасибо. Я не думал использовать троичный оператор. Но на самом деле вам не нужны круглые скобки в троице, что экономит еще 4 над вашим предложением. Назначение Aи Bотдельно - фактически такая же длина, как и назначение их вместе, поэтому я оставил эту часть как есть. Еще раз спасибо за ваше предложение!
Алекс А.

Пожалуйста. Ах я вижу. Да, скобки не нужны.
ML

4

Python 2, 141

Я попробовал несколько разных методов, но лучшее, что я мог получить, было относительно простым. Спасибо @ Sp3000 за 15 символов или около того (и за то, что научили меня существованию int.__xor__).

from random import*
L=[[1,0],[1,1]];C=choice
exec"A=C(L);B=C(L);L=[L+[map(int.__xor__,A,B)],[x+[C([1,0])]for x in L]][A==B];"*input()
print L

Вот 141: ссылка
Sp3000

4

Python 2, 127 122

Предполагая, что строки битов Python формы '0b1'и т. Д. В порядке:

from random import*
C=choice
L=[2,3]
exec"x=C(L)^C(L);L=L+[x]if x else[a*2+C([0,1])for a in L];"*input()
print map(bin,L)

Единственным легким нюансом здесь является использование того факта, что XOR (A, B) = 0 тогда и только тогда, когда A = B.

Спасибо @ Sp300 за укорочение forзамкнутого контура



Я не могу проверить этот ответ прямо сейчас, но если он не сохраняет начальные нули, он действительно, к сожалению, неверен.
Згарб


2

K 46 53 46 байт

{x{:[~/t:2?x;{x,*1?2}'x;x,,,/~=/t]}/(1 0;1 1)}

Хорошая часть этого размера (около 7 байт) связана с тем, что K не имеет xor оператора, поэтому мне пришлось реализовать его самому. Первоначально я использовал список строк, а затем понял, что это безумно глупо. Так что теперь я снова отрезал 7 байтов!

До:

{x{:[~/t:2?x;{x,*$1?2}'x;x,,,/$~=/(0$')'t]}/$:'10 11}

@JohnE указал в комментариях, что начальное состояние должно быть жестко закодировано, что стоит 7 дополнительных байтов. : /


Мое прочтение спецификации проблемы состоит в том, что вы всегда должны начинать с жестко закодированного «юниверса» (1 0;1 1)- ваша программа принимает это как ввод.
JohnE

@JohnE Исправлено. Однако нет гарантии, что это сработает, потому что я не тестировал изменения; Я только что попробовал заключительную часть в твоем репортаже ...
kirbyfan64sos

Кажется, хорошо работает и в Kona.
JohnE

2

JavaScript ( ES6 ) 152

Функция, использующая строки (с числами она должна быть короче, но в битовых операциях javascript ограничены 32-битными целыми числами).

Проверьте в Firefox, используя фрагмент ниже.

F=(t,L=['10','11'],l=2,R=n=>Math.random()*n|0,a=L[R(l)],b=L[R(l)])=>
   t--?a==b
     ?F(t,L.map(x=>x+R(2)),l)
     :F(t,L,L.push([...a].map((x,p)=>x^b[p]).join('')))
  :L
  
test=_=>O.innerHTML=F(+I.value).join('\n')
#I{width:3em}
<input id=I value=10><button onclick=test()>-></button><pre id=O></pre>


1

К, 45 41 38 байт

{x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}

Структура моего ответа очень похожа на структуру @ kirbyfan64sos, но вместо строк я использовал 1/0 векторов, и я избегаю необходимости в условном ( :[ ; ; ]), вместо этого индексируя в списке.

Несколько прогонов:

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0 0
 1 1 1 1
 0 1 1 1)

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0
 1 1 0
 0 1 0
 1 0 0)

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0
 1 1 0
 0 1 0
 1 1 0)

Редактировать:

Сохранены четыре байта с более компактным способом построения начальной вселенной:

1,'!2     / new
(1 0;1 1) / old

Edit2:

Я забыл, что «выбрать» может принять список в качестве правильного аргумента:

  2?"abcd"
"dc"
  2?"abcd"
"cc"
  2?"abcd"
"ca"

Так что я могу упростить часть этого. Отдайте должное, Кирби получил этот трюк раньше, чем я.

2?x    / new
x@2?#x / old

1
Черт, иногда я думаю, что знаю K, тогда я вижу ваши ответы ...: O
kirbyfan64sos

Я думаю, что это решение определенно считается командным усилием!
JohnE

1

Javascript, 241 233 байта

Это довольно долго.

a=[[1,0],[1,1]];for(b=prompt();b--;)if(c=a.length,d=a[c*Math.random()|0],e=a[c*Math.random()|0],d+""==e+"")for(f=0;f<c;f++)a[f].push(2*Math.random()|0);else{g=[];for(h=0;h<d.length;h++)g.push(d[h]^e[h]);a.push(g)}alert(a.join("\n"));

Закрытие Compiler сжал его, сохранив 8 байт.
Густаво Родригес

216 байт: for(b=prompt(a=[[1,0],[1,1]]),R=Math.random;b--;){c=a.length;d=a[c*R()|0];e=a[c*R()|0];if(d+""==e+"")for(f=0;f<c;f++)a[f].push(2*R()|0);else{for(h=0,g=[];h<d.length;)g.push(d[h]^e[h++]);a.push(g)}}alert(a.join("\n"))производит желаемый результат в 3/5 времени.
Исмаэль Мигель

217 байт: for(b=prompt(a=[[1,0],[1,1]]),R=Math.random;b--;){c=a.length;d=a[c*R()|0];e=a[c*R()|0];if(d+""==e+"")for(f=0;f<c;f++)a[f].push(2*R()|0);else{g=[];for(h=0;h<d.length;h++)g.push(d[h]^e[h]);a.push(g)}}alert(a.join("\n"))работает 90% времени.
Исмаэль Мигель

1

T-SQL (2012+), 1019

Мне очень жаль, что это далеко не конкурентоспособно, но, честно говоря, я не думал, что смогу заставить это работать, и мне пришлось опубликовать его, как только я это сделал. Я попытался немного поиграть в гольф :)

Для обработки двоичных / целочисленных преобразований мне пришлось создать пару скалярных функций (513 байтов). Aидет от целого числа до битовой строки. Bделает обратное.

CREATE FUNCTION A(@ BIGINT)RETURNS VARCHAR(MAX)AS
BEGIN
DECLARE @S VARCHAR(MAX);
WITH R AS(SELECT @/2D,CAST(@%2 AS VARCHAR(MAX))M
UNION ALL
SELECT D/2,CAST(D%2 AS VARCHAR(MAX))+M
FROM R
WHERE D>0)SELECT @S=M FROM R WHERE D=0
RETURN @S
END
CREATE FUNCTION B(@ VARCHAR(MAX))RETURNS BIGINT AS
BEGIN
DECLARE @I BIGINT;
WITH R AS(SELECT CAST(RIGHT(@,1)AS BIGINT)I,1N,LEFT(@,LEN(@)-1)S
UNION ALL 
SELECT CAST(RIGHT(S,1)AS BIGINT)*POWER(2,N),N+1,LEFT(S,LEN(S)-1)
FROM R
WHERE S<>''
)SELECT @I=SUM(I)FROM R
RETURN @I
END

Тогда есть процедура. @Cэто количество шагов

DECLARE @C INT=9
DECLARE @ TABLE(S VARCHAR(MAX))
DECLARE @R VARCHAR(MAX)
INSERT @ VALUES('10'),('11')
WHILE(@C>=0)
BEGIN
SET @C-=1
SELECT @R=CASE WHEN MAX(S)=MIN(S)THEN''ELSE RIGHT(REPLICATE('0',99)+dbo.A(dbo.B(MAX(S))^dbo.B(MIN(S))),LEN(MAX(S)))END
FROM(SELECT TOP 2S,ROW_NUMBER()OVER(ORDER BY(SELECT\))N FROM @,(VALUES(1),(1),(1))D(D)ORDER BY RAND(CAST(NEWID()AS VARBINARY(50))))A
IF @R=''UPDATE @ SET S=CONCAT(S,ROUND(RAND(CAST(NEWID() AS VARBINARY(50))),0))
ELSE INSERT @ VALUES(@R)
END
SELECT * FROM @

Десять тысяч итераций заняли около 2 минут и вернули 9991 ряд

1001001100110
1101001001110
0111100100101
1111100001011
1111001010011
0110101001101
...
1110101000100
1111011101100
1100001100010
0110010001001
1110100010100

0

Pyth - 37 байт

Очевидно, просто следует psuedocode. Вероятно, может много играть в гольф.

KPP^,1Z2VQ=K?m+dO1KqFJ,OKOKaKxVhJeJ;K

Попробуйте здесь онлайн .


3
Тебе нужно O2вместо O1. O1дает случайное число из диапазона U1 = [0].
Якуб

2
Таким образом, вы всегда добавляете 0.
Якуб

0

Mathematica, 106 байт

Nest[If[Equal@@#,Map[#~Append~RandomInteger[]&],Append[BitXor@@#]]&[#~RandomChoice~2]@#&,{{1,0},{1,1}},#]&

0

Perl, 102

#!perl -p
@l=qw(10 11);$_=$l[rand@l]^$l[rand@l],$_|=y//0/cr,@l=/1/?(@l,$_):map{$_.~~rand 2}@l for 1..$_;$_="@l"

Попробуй меня .


0

R 186

L=list(0:1,c(1,1))
if(t>0)for(t in 1:t){A=sample(L,1)[[1]]
B=sample(L,1)[[1]]
if(all(A==B)){L=lapply(L,append,sample(0:1, 1))}else{L=c(L,list(as.numeric(xor(A,B))))}}
L

Здесь нет ничего волшебного. Введите значение для tв консоли R и запустите скрипт. Трудно «сыграть в гольф» R-код, но вот более читаемая версия:

L <- list(0:1, c(1, 1))
if(t > 0) {
  for(t in 1:t) {
    A <- sample(L, 1)[[1]]
    B <- sample(L, 1)[[1]]
    if (all(A == B)) {
      L <- lapply(L, append, sample(0:1, 1))
    } else {
      L <- c(L,list(as.numeric(xor(A, B))))
    }
  }
}
L

Вы можете сохранить количество символов, назначив sampleпеременную. например s=sample, тогда используйте s вместо образца. К сожалению, я думаю, что ваш метод добавления случайного бита в lapplyконец в конечном итоге добавляет одну случайную выборку ко всем элементам в списке. lapply(L,function(x)append(x,sample(0:1,1)))кажется, работает, но за плату. Вы можете заменить вас as.numericс 1*который должен получить обратно.
MickyT

Хороший улов по обоим пунктам, а также хороший трюк с принуждением
shadowtalker

Также только что заметил, что ваш счет отсутствует. Я делаю это 168, используя это
MickyT

0

Руби, 82

Довольно просто. По сравнению с другими не относящимися к гольфу языками, ruby, похоже, хорошо справляется со своей большой стандартной библиотекой.

->t{l=[2,3]
t.times{a,b=l.sample 2
a.equal?(b)?l.map!{|x|x*2+rand(2)}:l<<(a^b)}
l}

Пример вывода для t = 101010:

[9, 15, 6, 13, 5, 12, 10, 11, 5, 4, 15, 13, 2, 7, 11, 9, 3, 3, 8, 6, 3, 13, 13, 12, 10, 9, 2, 4, 14, 9, 9, 14, 15, 7, 10, 4, 10, 14, 13, 7, 15, 7]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.