Задача «Шпионы и яд»
Давно хотел проверить не забыл ли я язык «Эр» («R»). В 2017-м много на нём программировал — было интересно изучить, но с тех пор как-то и не трогал. Интересно было посмотреть что в мозге осталось, а что улетучилось за восемь лет.
А тут — оказия, у Романа Парпалака в блоге появилась небольшая заметка о задаче «Шпионы за круглым столом»:
На банкете за круглым столом сидят n шпионов. Каждый шпион независимо от остальных случайным образом выбирает одного из двух соседей — левого или правого — и подсыпает яд ему в бокал. Каково математическое ожидание числа выживших шпионов?
Он там её решает аналитически, а я подумал, что это удобный случай запрограммировать что-нибудь на «Эре». Притворимся, что не верим Роману и попробуем сравнить найденное решение и эксперимент (у меня проводится сто тысяч экспериментов на каждое число шпионов за столом).

Написал сначала, разумеется, «в лоб» — цикл в цикле в цикле: для каждого числа шпионов цикл по количеству экспериментов, где каждый шпион в цикле решает кого он будет травить. Получилось медленно — «Эр» не очень быстрый язык.
После чего я сделал всё более параллельно — сначала готовлю матрицу выбора, где строки — эксперименты. Каждый элемент матрицы содержит выбор — будет отравлен сосед слева или справа. Следующим шагом преобразую эту матрицу в другую, которая содержит уже позиции отравляемых за столом. Дальше в строках подсчитываются уникальные значения и получается количество отравленных. Если вычесть его из количество шпионов за столом, получится количество выживших. После этого уже совсем просто подсчитать требуемое.
С матрицами получилось намного быстрее, но недостаточно. Поэтому я применил ещё и модуль parallel, который умеет раскидывать задачи по ядрам. Там используются немного другие функции, но в остальном всё работает так же.
Если кому-нибудь хочется посмотреть на синтаксис «Эра», код есть у меня в репозитории.
Интересное продолжение темы! Для читателей отмечу, что при таких маленьких n можно было бы ещё вычислить точное значение полным перебором по 2^n вариантам. Например, для n=20 будет чуть больше 1 миллиона итераций.
Надо будет попозже ещё вернуться к этому, подольше подержать в активном состоянии области мозга, которые отвечают у меня за Эр. Но миллион перебирается долго, я пробовал, впрочем подождать не проблема.