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


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.