Нетранзитивные кости - это милые маленькие игрушки, которые бросают вызов нашей интуиции в теории вероятностей. Нам понадобится несколько определений для этой задачи:
Рассмотрим две кости A и B, которые выбрасываются одновременно. Мы говорим, что A побеждает B, если вероятность того, что A показывает большее число, чем B , строго больше, чем вероятность B показывает большее число , чем A .
Теперь рассмотрим набор из трех костей, с этикетками , B , C . Такой набор кубиков называется нетранзитивным, если
- либо A бьет B , B бьет C, а C бьет A
- или C бьет B , B бьет и бьется C .
В качестве одного из моих любимых примеров рассмотрим кости Грайма , у которых есть следующие стороны:
A: 3 3 3 3 3 6
B: 2 2 2 5 5 5
C: 1 4 4 4 4 4
Интересно, что среднее значение каждого кубика равно 3,5, как и у обычного кубика.
Можно показать, что:
- А бьет Б с вероятностью 7/12.
- B бьет C с вероятностью 7/12.
- С бьет А с вероятностью 25/36.
Теперь эти конкретные кости еще более странные. Если мы бросим каждый кубик дважды и суммируем результаты, порядок которых превосходит, который меняется на противоположный:
- B бьет A с вероятностью 85/144.
- С бьет В с вероятностью 85/144.
- А бьет С с вероятностью 671/1296.
Давайте назовем набор кубиков с этим свойством Grime-нетранзитивных .
С другой стороны, если кости сохраняют свой первоначальный цикл при использовании двух бросков, мы называем их строго нетранзитивными . (Если для двух бросков вообще нет цикла, мы просто называем их нетранзитивными .)
Соревнование
Принимая во внимание три шестигранного кубика, определяют , какие из указанных выше свойств этого набора имеет, и выход одного из следующих строк: none
, nontransitive
, Grime-nontransitive
, strongly nontransitive
.
Вы можете написать программу или функцию, получить ввод через STDIN, аргумент командной строки, приглашение или аргумент функции и записать результат в STDOUT или вернуть его в виде строки.
Вы можете предположить, что все стороны являются неотрицательными целыми числами. Вы не можете предполагать, что стороны или кости находятся в каком-то определенном порядке. Вы можете взять ввод в любом удобном формате списка или строки.
Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.
Тестовые случаи
none
1 2 3 4 5 6, 6 5 4 3 2 1, 1 3 5 2 4 6
1 1 1 6 6 6, 4 4 4 5 5 5, 5 5 5 5 5 5
1 1 2 5 6 6, 2 2 3 4 4 6, 2 3 3 4 4 5
0 1 2 3 4 5, 1 1 2 3 3 5, 1 2 2 2 3 5
3 13 5 7 13 7, 5 7 11 5 7 13, 5 9 13 5 7 9
nontransitive
1 2 2 4 6 6, 1 2 3 5 5 5, 2 3 4 4 4 4
1 4 4 4 4 4, 2 2 2 4 5 6, 2 3 3 3 5 5
1 2 1 6 5 6, 3 1 3 6 2 6, 2 4 2 4 4 5
3 4 6 6 7 7, 4 4 4 7 7 7, 5 5 5 5 6 7
2 5 11 11 14 14, 5 5 5 14 14 14, 8 8 8 8 8 17
Grime-nontransitive
3 3 3 3 3 6, 2 2 2 5 5 5, 1 4 4 4 4 4
1 1 4 5 5 5, 2 2 2 3 6 6, 3 3 3 4 4 4
2 1 4 6 4 4, 2 4 5 2 3 5, 3 3 6 3 3 3
11 11 13 15 15 16, 12 12 12 13 16 16, 13 13 13 14 14 14
4 4 7 16 19 19, 4 7 13 13 13 19, 4 10 10 10 16 19
strongly nontransitive
2 2 2 5 5 5, 2 3 3 3 5 5, 1 1 4 5 5 5
2 2 2 3 6 6, 2 2 2 5 5 5, 2 2 4 4 4 5
1 5 1 3 6 5, 6 6 4 2 2 1, 5 3 4 3 4 2
0 0 2 4 4 5, 0 1 1 3 5 5, 1 1 2 3 4 4
1 1 9 17 17 21, 1 5 5 13 21 21, 5 5 13 13 13 17
Если вы хотите протестировать свой код еще более тщательно, Питер Тейлор был достаточно любезен и написал эталонную реализацию, которая классифицировала все ~ 5000 наборов кубиков со сторонами от 1 до 6 и средним значением 3,5. Вставить ссылку
источник
1 2 2 4 6 6, 1 2 3 5 5 5, 2 3 4 4 4 4
Я получаю A <B 17/36, B> C 19/36, C <A 16/36.Ответы:
Dyalog APL,
107100 байт{({+/×+/¨,¨×⍵∘.-¨1⌽⍵}{3≠|a←⍺⍺⍵:1⋄a=b←⍺⍺∘.+⍨¨⍵:2⋄3+a=-b}⍵)⊃(⊂'none'),'strongly '⍬'Grime-',¨⊂'nontransitive'}
{T←{+/×+/¨∊¨×⍵∘.-¨1⌽⍵}⋄3≠|S←T⍵:'none'⋄N←'nontransitive'⋄S=D←T∘.+⍨¨⍵:'strongly ',N⋄S=-D:'Grime-',N⋄N}
(Спасибо @Tobia за это более простое, короткое и лучшее решение)
Основы:
←
назначение⋄
разделитель операторов{}
лямбда-форма⍺⍵
левый и правый аргументA:B
охранник («еслиA
потом вернутьсяB
»)T
является функцией, которая возвращает 3, если A бьет B, B бьет C, а C бьет A; -3, если с точностью до наоборот; и что-то среднее между прочим. В деталях:1⌽⍵
это одно вращение⍵
. Если⍵
ABC, вращение BCA.∘.-
вычисляет таблицу вычитания между двумя векторами (1 2...10 ∘.× 1 2...10
это будет таблица умножения, которую мы знаем из школы). Мы применяем это между каждым (¨
) элементом⍵
и соответствующим элементом в1⌽⍵
.×
знак всех чисел в таблицах вычитания∊¨
сплющить каждый стол+/¨
и подвести итог. Теперь у нас есть три числа, которые представляют сальдо: количество выигрышных минус проигрышных дел для каждого из A против B, B против C, C против A.×
подпись тех+/
суммаЗатем разберитесь со случаями по очереди:
3≠|S←T⍵:'none'
еслиT⍵
абсолютное значение не равно 3, вернуть «нет»N←'nontransitive'
нам нужно это слово многоS=D←T∘.+⍨¨⍵:'strongly ',N
вычислитьT
для пар костей (∘.+⍨¨⍵
← →⍵((∘.+)¨)⍵
) и вернуть «сильно ...», если все еще сохраняются те же отношения между ABCS=-D:'Grime-',N
Gri «Грязь», если отношения в противоположных направленияхN
если все остальное терпит неудачу, только "нетранзитивный"источник
{T←{+/×+/¨∊¨×⍵∘.-¨1⌽⍵}⋄3≠|S←T⍵:'none'⋄N←'nontransitive'⋄S=D←T∘.+⍨¨⍵:'strongly ',N⋄S=-D:'Grime-',N⋄N}
Python 2, 269
Вот миленькое выражение, которое оценивает функцию. Он принимает три списка целых чисел. Проходит все тестовые случаи.
источник
J -
311257 байтОбновление (13 января 2015 г.):
Пояснение: Используя Gerunds, упростите
if.
s до@.
s.Старая версия:
Сначала попробуйте как кодирование в J, так и гольф.
Запустите его, используя синтаксис, подобный следующему (дополнительные пробелы для ясности):
Объяснение:
g
определяется как диада с двумя массивами, которая сообщает, что если первая кость бьет вторые костиh
, определяется как диада с двумя массивами, которая сообщает, если два броска и сумма суммируются, будет ли первая кость бить вторуюf
- это монада, которая берет таблицу и возвращает строку с правильный ответРедактировать: Исправить ошибку в нетранзитивном состоянии (замена
,
на*
)источник
Pyth 129
133Попробуйте это здесь , или, по крайней мере, вы могли бы, но онлайн
eval
не похоже списки списков :( Если вы хотите попробовать это там, вручную сохраните список из 3 кубиков в переменную, не используемую программой, а затем замените все экземплярыQ
с этой переменной. Пример инициализации:Это проходит все тестовые задания Мартина, у меня нет сердца пройти через все дела Питера: P
Пояснение (это будет глупо)
Довольно просто, делает функцию,
y
которая возвращает сумму каждой декартовой пары значений в итерируемом. Эквивалент:def y(b):return map(lambda d:sum(d),product(b,repeats=2))
. Это используется для создания многогранных кубиков, которые имитируют бросание обычных кубиков дважды.Определяет функцию
g
из 2 аргументов, которая возвращает, сколько раз кубик бьет другого. Эквивалентdef g(G,H):return sum(map(lambda k:sum(map(lambda b:b>k,G)),H)
.Определяет функцию,
P
которая принимает список из двух кубиков в качестве аргумента. Возвращает -1, если первый кубик «проигрывает», 0 за ничью и 1, если первый кубик «выигрывает». Эквивалентно:Назначения
AGH
действуют как присваивание Python с двумя кортежами. по существуG,H=(result)
Собираюсь объяснить задом наперед по картам.
m,@Qb@QhbUQ
перебирает b = 0..2 и генерирует 2 набора игральных костей с индексом b и индексом b + 1. Это дает нам кости (A, B), (B, C), (C, A) (pyth автоматически изменяет индексы по длине списка).Затем
m,PkP,yhkyek
выполняется итерация по результату предыдущей карты с каждой парой костей, сохраняемой в k за каждый прогон. Возвращаетtuple(P(k),P(tuple(y(k[0]),y(k[-1]))))
для каждого значения. Это сводится к `((A бьет B ?, 2 * A бьет 2 * B), (B бьет C?, 2 * B бьет ..)).Наконец,
msdC
суммирует значения предыдущей карты после ее архивирования. Zip вызывает все значения «биений» одиночных костей в первом кортеже и значения двойных костей во втором.Грубая вещь, которая распечатывает результаты. Если G = 0 или не делится на 3, это ловит бот +/- 3, (
|!G%G3
), печатаетnone
, в противном случае выводит сумму списка follwing:[not(G+H)*"Grime",(G==H)*"strongly ","nontransitive"]
. Я думаю, что логические значения довольно очевидны в отношении определений в вопросе. Обратите внимание, что здесь G не может быть нулем, так как это поймано предыдущей проверкой.источник
J (204)
Слишком долго, вероятно, можно много играть в гольф, имея более эффективную систему для выбора правильной струны.
источник
Матлаб (427)
Это не так уж и мало, и я уверен, что это может быть гораздо больше, я просто попытался решить эту задачу, потому что я думал, что это было очень забавное задание, поэтому спасибо @ MartinBüttner за создание этого задания !
Вот полный код с некоторыми комментариями, если вы хотите попытаться понять, что происходит. Я включил несколько тестовых примеров зайца и исключил входные команды:
источник
input()
а затем назначаете три элементаa,b,c
? Кроме того , пожалуйста , используйте точные строки в спецификации (none
,nontransitive
и капитализированнойGrime
) ... должен , вероятно , даже сохранить вам байты.disp
команды в длинной версии, они были только для тестирования программы, но окончательное сообщение сохраняется вm
. И я исправилG
.JavaScript - 276 байт
Я не очень хорош в вероятности, поэтому, чтобы быть уверенным в моих результатах, я предпочитаю просто бросать кости сотни тысяч раз.
Выражение вычисляется как функция, которая должна вызываться только с одним аргументом: массивом из трех массивов целых чисел. Проверьте Fiddle, чтобы иметь возможность запустить код самостоятельно.
Вот негольфированная версия:
источник