Псевдовипадковий стільниковий автомат


14

Вступ

У цьому виклику ми будемо моделювати певний імовірнісний стільниковий автомат, використовуючи дуже погані псевдовипадкові числа. Стільниковий автомат визначається на двійкових рядках за наступним локальним правилом. Припустимо, що лівий сусід клітини і сама клітина мають стани aі b.

  • Якщо min(a,b) == 0, то новий стан Росії bє max(a,b).
  • Якщо min(a,b) == 1, то новий стан bA вибирається випадковим чином {0,1}.

На наступному малюнку показана одна можлива 10-ступінчаста еволюція синглу 1.

1
11
101
1111
11001
101011
1111111
10001001
110011011
1010111101

Зверніть увагу, як два суміжних 1s іноді еволюціонують до 1, а іноді до 0, і найбільш бітові біти завжди є 1s. Ваше завдання - створити еволюцію стільникового автомата цієї форми.

Вхідні дані

Ваші вхідні дані - це натуральне число n, що позначає кількість рядків для відображення, і не порожній список бітів L, який ми використовуємо як джерело випадковості.

Вихідні дані

Вихід - це список списків або двовимірний масив бітів, що зображує еволюцію одиничного 1для nчасових кроків, як на малюнку вище. Ви можете накласти на висновок 0s, щоб отримати рядки однакової довжини, за бажанням, але не повинно бути провідних 0s.

Випадкові вибори в стільниковому автоматі повинні бути зроблені зі списку L, відскакуючи на початок, коли він вичерпаний. Більш чітко, якщо результат проходить по одному рядку за часом у формі зверху вниз, зліва направо, то послідовні випадкові вибори формують список, Lповторюваний стільки разів, скільки потрібно.

Приклад

Припустимо, входи є n = 7і L = [0,1,0]. Тоді стільниковий автомат розвивається наступним чином протягом 7 кроків, де ми поставили vправо над кожним випадковим вибором:

[1]

[1,1]
   v
[1,0,1]

[1,1,1,1]
   v v v
[1,1,0,0,1]
   v
[1,1,1,0,1,1]
   v v   v
[1,0,0,1,1,1,1]

Якщо ми прочитаємо всі біти, позначені символом a v, отримаємо 01001001, що Lповторюється 2,66 рази. Наступний випадковий біт був би 0.

Правила та підрахунок балів

Ви можете написати повну програму або функцію. Виграє найменший байт, а стандартні лазівки заборонені. Точний формат входів і виходів є неважливим (в межах причини).

Випробування

Детермінована версія, кожен випадковий біт 0:

Inputs: 10 [0]
Output:
1
11
101
1111
10001
110011
1010101
11111111
100000001
1100000011

Кожен випадковий біт 1:

Inputs: 6 [1,1]
Output:
1
11
111
1111
11111
111111

Псевдовипадкові версії:

Inputs: 10 [0,0,1]
Output:
1
11
101
1111
10101
111111
1010011
11110101
101011111
1111101001

Inputs: 10 [1,0,0,1]
Output:
1
11
111
1001
11011
111111
1001101
11010111
111111101
1011001111

Inputs: 15 [1,1,1,0,0,0]
Output:
1
11
111
1111
10001
110011
1110111
11011001
111111011
1100011111
11100100011
111101100101
1001111101111
11011000111111
101101001011101

Відповіді:


3

Pyth, 33 байти

jjLk.u++1m?hSde=.<Q1sd.:N2 1tvz]1

Спробуйте в Інтернеті: Демонстрація або Тестовий набір

Пояснення:

jjLk.u++1m?hSde=.<Q1sd.:N2 1tvz]1  implicit: Q = input list
    .u                      tvz]1  reduce N=[1] input-1 times by applying
                      .:N2           all substrings of length 2
         m                           map each d of ^ to:
          ?hSd                         if min(d) = 0 then:
               =.<Q1                     rotate Q by one
              e                          and use the last element
                    sd                 else use sum(d) (=max(d))
      ++1                  1         add a 1 at the front and the back
                                   .u gives all intermediate results
 jLk                               join these lists to strings
j                                  print each string on a line

7

Сітківка , 139 байт

^.
1

 00:0 01:1 10:1 11:
(m`^(..)((\S*)(?<=0) .*)
$1$3#$1!$2
+m`(?<=^(?<-2>.)*(..).*?#(.)*.)\d!(.)(.*\1:)(.)(\d*)
$5$3!$4$6$5
)`!0
0
 .+
<empty>

Де <empty>вказується на те, що є порожній рядок. Кожен рядок складається в окремому файлі, і його #слід замінити на рядки стрічки (0x0A).

Чекає введення , щоб бути nв унарна (з нулів, як в унарна ), за яким слід пробіл, за яким слід «псевдослучайная» рядок, наприклад , 10, [1, 0, 0, 1]буде читати як

0000000000 1001

Вихід є як у виклику, але з нулями, напр

1000000000
1100000000
1110000000
1001000000
1101100000
1111110000
1001101000
1101011100
1111111010
1011001111

Це було складніше, ніж я очікував ...


3

Пітон, 142 135 132 131 байт

133 132 131 байт-версія

f=input;n=f();L=f()*n*n;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if r[x-1]&r[x]else r[x-1]+r[x]for x in range(1,i)];r=[1]+r+[1];i+=1

замінено r[x-1]+r[x]>1на r[x-1]&r[x]оператор побітових операцій і дає мінімальне значення в(r[x-1],r[x])

Дякуємо @ThomasKwa за пропозицію, n*nзамість n**2чого економиться 1 байт!

Дякую @Shebang за -1 байт

135-байтна версія

f=input;n=f();L=f()*n**2;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if r[x-1]+r[x]>1 else r[x-1]+r[x]for x in range(1,i)];r=[1]+r+[1];i+=1

Дякуємо @Cole за -7 байт:

min(r[x-1],r[x])->r[x-1]+r[x]>1

max(r[x-1],r[x])->r[x-1]+r[x]

142-байтна версія

f=input;n=f();L=f()*n**2;r=[1];i=1
while i<=n:print r;r=[L.pop(0)if min(r[x-1],r[x])else max(r[x-1],r[x])for x in range(1,i)];r=[1]+r+[1];i+=1

Навіть не близький до відповіді @ Jakube, але мені було дуже весело кодування і гольфу цього.

Очікує два входи: перший вхід - це кількість рядків, а другий - список джерел псевдовипадковості . Він друкує на консолі один рядок за іншим, кожен у новому рядку.

Як приклад:

10 # This is input
[0] # This is input
[1] <- First output row
[1, 1]
[1, 0, 1]
[1, 1, 1, 1]
[1, 0, 0, 0, 1]
[1, 1, 0, 0, 1, 1]
[1, 0, 1, 0, 1, 0, 1]
[1, 1, 1, 1, 1, 1, 1, 1]
[1, 0, 0, 0, 0, 0, 0, 0, 1]
[1, 1, 0, 0, 0, 0, 0, 0, 1, 1]

Тепер коротке пояснення про те, як це працює:

f=input;n=f();L=f()*n*n;r=[1];i=1 First we define the input() function as f 
                                   for saving bytes as we have to call it twice.
                                   Then L is defined as a list made of the 
                                   pseudorandom numbers in their order *many* times 
                                   (were *many* is an upperbound of the canges that 
                                   could be done); r as the first row and i as the row 
                                   counter.

while i<=n:print r                 A while loop that exits when the nth row has been 
                                   calculated and the printing of the actual row.

r=[L.pop(0)if r[x-1]&r[x] else r[x-1]+r[x] for x in range(1,i)];r=[1]+r+[1];i+=1
     ^           ^                 ^                         ^
     |           |                 |Same as max(r[x-1],r[x]) | from 2nd to last element
     |           | Same as min(r[x-1],r[x]) (0->False;1->True)                
     | get random bit from pseudorandom list    

Підступність полягає в тому, що ми знаємо, що бітовий список завжди починатиметься і закінчуватиметься a, 1тому що перший і останній елементи ніколи не змінюються завдяки специфікаціям. питання. Ось причина заяви [1]+r+[1].

Але якщо rініціалізовано як [1], в першому рядку немає змін, і тоді ми додамо, [1]+r+[1]як не виходить другий рядок [1,1,1]?

Це пов’язано з тим, що на першій ітерації i=1таким чином range(1,i)повертається порожній список і в результаті forрозуміння списку, що не має нічого перебирати, rстає порожнім списком [1]+r+[1]=[1,1]. Це відбувається лише на першій ітерації, яка ідеально підходить для нас!

PS: Не соромтеся робити будь-які пропозиції щодо того, як більше пограти в гольф.


1
Мої вибачення , якщо я не розумію проблему правильно, але ви не можете замінити min(a,b)з a+b>1і max(a,b)з a+b? Я усвідомлюю, що вам, мабуть, доведеться щось зробити, щоб впоратися з першим випадком 1-> 11(я думаю, ви могли б це зробити L=[1]+f()..., або знайти якийсь спосіб вставити 1 в передній частині, Lтому що це завжди з'явиться 1 для другого рядка)
cole

@Cole На щастя жодних змін не потрібно вносити до решти програми, оскільки зміни впливають лише на спосіб пізнання мінімальних та максимальних значень пари біт.
Іоанна

1
Ви пропустили, що можете видалити пробіл тут: r[x-1]&r[x] else:)
Kade

Чи буде n ** 2 -> n * n працювати?
lirtosiast

@Thomas Ти маєш рацію!
Іоанна

2

MATLAB, 146 143 138

(Також працює на Octave в Інтернеті, але вам потрібно увійти, щоб зберегти функцію у файлі).

function o=c(n,L);o=zeros(n);o(:,1)=1;for i=2:n;for j=2:i;a=o(i-1,j-1);b=o(i-1,j);c=a|b;d=a&b;c(d)=L(d);L=circshift(L,-d);o(i,j)=c;end;end

Функція приймає вхід nі Lповертає масив, oякий містить вихід.

Для вхідних значень nє скалярним і Lявляє собою вектор стовпців, який можна вказати у форматі [;;;]. Не зовсім те, що ви показуєте, але ви кажете, що це гнучко в межах розуму, і це здається так.

Вихід відформатований у вигляді n x nмасиву, що містить 0 та 1.

І пояснення:

function o=c(n,L)
%Create the initial array - an n x n square with the first column made of 1's
o=zeros(n);o(:,1)=1;
%For each row (starting with the second, as the first is done already)
for i=2:n;
    %For each column in that row, again starting with the second as the first is done
    for j=2:i;
        %Extract the current and previous elements in the row above
        a=o(i-1,j-1); %(previous)
        b=o(i-1,j);   %(current)
        %Assume that min()==0, so set c to max();
        c=a|b;
        %Now check if min()==1
        d=a&b;
        %If so, set c to L(1)
        c(d)=L(d);
        %Rotate L around only if min()==1
        L=circshift(L,-d);
        %And store c back to the output matrix
        o(i,j)=c;
    end;
end

Оновлення: мені вдалося оптимізувати оператор if-else, щоб зберегти кілька байт. Формат введення знову змінився на вектор стовпця.


1

Haskell, 153 149 байт

j[_]o l=(l,o)
j(a:u@(b:c))o q@(l:m)|a*b==0=j u(o++[a+b])q|1<2=j u(o++[l])m
k(r,a)=fmap((1:).(++[1]))$j a[]r
n%l=map snd$take n$iterate k(cycle l,[1])

%повертає список бітових списків. Приклад використання:

> 10 % [1,0,0,1] 
[[1],[1,1],[1,1,1],[1,0,0,1],[1,1,0,1,1],[1,1,1,1,1,1],[1,0,0,1,1,0,1],[1,1,0,1,0,1,1,1],[1,1,1,1,1,1,1,0,1],[1,0,1,1,0,0,1,1,1,1]]

О Боже! Проведення випадкового списку Lнавколо - це чистий біль. Подивимось, чи може це бути коротше.


1

C #, 152 байти

Тут немає нічого особливого. Функція повертає 2D масив, де перший ранг - це рядок, а другий - стовпець.

Відступ та нові рядки для наочності:

int[,]F(int n,int[]l){
    var o=new int[n,n];
    for(int y=0,x,i=0,m;y<n;y++)
        for(o[y,x=0]=1;x++<y;)
            o[y,x]=(m=o[y-1,x-1]+o[y-1,x])<2?m:l[i++%l.Length];
    return o;
}

1

TI-BASIC, 106 94 87 86 87 байт

Prompt N,B
"∟B(1+remainder(𝑛,dim(∟B→u
{1
For(I,1,N
Disp Ans
augment({0},Ans)+augment(Ans,{0
Ans and Ans≠2+seq(u(𝑛-(Ans(X)<2)+2dim(∟B)),X,1,dim(Ans
End

У TI-BASIC немає оператора приросту, правда? Ну, це так і є. Змінна рівняння u, яка зазвичай використовується з послідовностями, має незрозумілу особливість: коли uвикликається аргументом, змінна 𝑛встановлюється на один, більший за цей аргумент. Від цього залежить умовний приріст. (Я давно чекав використовувати його.)

Щоб індексування списку працювало належним чином, 𝑛повинно бути його значення за замовчуванням 0 і 𝑛Minмає бути його за замовчуванням 1, тому очистіть оперативну пам'ять калькулятора або встановіть ці значення вручну перед запуском цього.

augment({0},Ans)+augment(Ans,{0обчислює список сум двох сусідніх елементів, тому він повертає список 0s, 1s та 2s. Тоді магія на цій лінії:

Ans and Ans≠2+seq(u(𝑛-(Ans(X)≠2)+dim(∟B)),X,1,dim(Ans

Ans and                 ;set 0s to 0
Ans≠                    ;set to 0 all sums that equal...
2+
  seq(...,X,1,dim(Ans   ;execute for each element of the list
      u(                ;return this element in list of bits (looping)        
        𝑛               ;current location in the list
        -(Ans(X)≠2)+    ;subtract 1 if the element isn't 2
        2dim(∟B)        ;Add twice the dimension of the list
                           ;(because n<nMin on the first iteration, it's out of the domain
                           ;this prevents an error)
       )                      ;set n to one greater than that value
                              ;i.e. increment if element≠2
                        ;Will equal Ans(X) iff Ans(X)=2 and the bit read false

Результатом цього рядка буде те, що елементи списку дорівнюють 0, якщо вони були 0 або якщо вони були 2, а біт, прочитаний - 0.

Result of above line
n \ u |  0  |  1
0        0     0

Тестовий випадок:

N=?7
B=?{0,1,0
             {1}
           {1 1}
         {1 0 1}
       {1 1 1 1}
     {1 1 0 0 1}
   {1 1 1 0 1 1}
 {1 0 0 1 1 1 1}
            Done
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.