Створіть програму для аналізу варіантів послідовності відкидання монет


15

У головоломці в старій моїй книзі визначена гра, в якій два гравці вибирають послідовності монет, які, на їхню думку, з’являться першими, коли монета повторно перегортається. (Це були насправді дивні і парні рулони, але ця маленька деталь не має значення в еквівалентності проблеми.)

Зазначається, що якщо гравець 1 вибирає, TTTа гравець 2 вибирає HTT, той гравець 2 має шанси 7/8 виграти гру, оскільки єдиний шлях TTTможе бути раніше HTT, якщо перші три перевертання - це всі хвости.

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

HTT
TTT

І виведіть ймовірність того, що перший гравець виграє, або в дробовій, або в десятковій формі:

7/8
0.875

Виграє найкоротший код для будь-якої мови.


6
Чи послідовності завжди однакові між собою?
Урі Гранта

1
@UriZarfaty Ні, не обов’язково.
Джо З.

Хоча, мабуть, послідовності повинні бути чіткими (оскільки результат не може вказати кратність).
Урі Гранта

Так, послідовності повинні бути чіткими.
Джо Z.

Більш конкретно, один не може бути кінцевим підрядком іншого.
Джо З.

Відповіді:


4

Python 3 (139 136 134 132 126 115 143)

Використовує алгоритм Конвея, як описано тут . Обробляє всі пари послідовностей до тих пір, поки перша не є завершальною послідовністю другої (згідно інструкцій).

def f(a,b):c=lambda x,y=a:sum((x[~i:]==y[:i+1])<<i for i in range(len(x)));return 0 if b in a else(1/(1+(c(a)-c(a,b))/(c(b,b)-c(b))),1)[a in b]

Дякую xnor за гоління 6 байт. Дякую Згарбу за те, що помітив помилку з подальшими наслідками


Поточна версія для мене не працює. Для введення "HTT"і "TTT", oмає значення, -1і воно ділить його на 0.
Якубе

1
Гарний гольф! Мені подобається трюк аргументів за замовчуванням. Пара (неперевірені) поради: ви можете помножити на 2**iз <<i, а ймовірність виходу може бути записана в вигляді 1/(1/o + 1), в якому ви можете поставити зворотну oбезпосередньо.
xnor

Спасибі. Гарне місце ре о / (1 + о). Трохи соромно, що пропустили <<!
Урі Гранта

@Jakube Вибачте, не помітив ваш коментар! Поточна версія для мене добре працює з "HTT" та "TTT".
Урі Гранта

1
Це дає ненульову відповідь HTHі T, хоча перший гравець не може виграти. Інша відповідь має ту саму проблему.
Згарб

3

CJam, 44 38 36 байт

Використовуючи той самий алгоритм Конвея, як і тут .

ll]_m*{~1$,,@f>\f{\#!}2b}/\-:X--Xd\/

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

Я використовую формулу для виграшу коефіцієнтів ( p) для першого гравця А як

введіть тут опис зображення

Тоді ймовірність визначається як

введіть тут опис зображення

який після спрощення стає

введіть тут опис зображення

і після деякого спрощення стає

введіть тут опис зображення


Приклад введення:

HTT
TTT

Вихід:

0.875

Спробуйте його онлайн тут


Джо в коментарях (після цього було опубліковано) сказав, що рядки необов'язково однакової довжини. І все-таки +1, тому що я не розумію CJam.
mdc32

@ mdc32 виправлено, зараз на 1 байт більше :(
Оптимізатор

Ви вже дозволяєте мені повірити, що codegolfSE тепер підтримує LaTeX ... = (
недолік

@flawr HAHA. Вибачте з цього приводу :(. Це PNG від онлайн-редактора LaTeX.
Оптимізатор

Це дає ненульову відповідь HTHі T, хоча перший гравець не може виграти. Інша відповідь має ту саму проблему.
Згарб

0

Луа 211 190 184

Також використовується алгоритм Конвея. Досі новачок для Lua, так що це можна отримати гольф більше точно.

z=io.read;e=function(s,t)r='';for d in s:gmatch"."do r=r..(d==t:sub(1,1)and 1 or 0);end;return tonumber(r,2);end;a=z();b=z();print((e(a,a)-e(a,b))/(e(b,b)-e(b,a))/(1/((1/2)^b:len())));

Безумовно

z=io.read;
e=function(s,t)
r='';
    for d in s:gmatch"."do 
        r=r..(d==t:sub(1,1)and 1 or 0);
    end;
    return tonumber(r,2);
end;
a=z();
b=z();
print((e(a,a)-e(a,b))/(e(b,b)-e(b,a))/(1/((1/2)^b:len())));

Перша версія

z=io.read;
e=function(s,t) 
    r=0;
    for d in s:gmatch"."do 
        r=r*10;
        if d==t:sub(1,1)then r=r+1 end;
    end
    return tonumber(r,2);
end;
f=function(n,o)
    return ((e(n,n)-e(n,o))/(e(o,o)-e(o,n)))/(1/((1/2)^3));
end;
print(f(z(),z()));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.