Хто може врятуватися від Нонарської гри?


13

The Nonary Game - це вигадана гра, що грається в однойменній трилогії відеоігор. Ваша мета - знайти, скільки гравців (у кращому випадку) можуть уникнути даної гри, за якомога менше байтів коду.

Правила гри

  • Є 9 гравців, які пронумеровані від 1 до 9.
  • Усі гравці починаються в одній кімнаті.
  • Є будь-яка кількість дверей, кожна з номером від 1 до 9. Можуть бути дублікати або відсутні номера дверей.
  • Двері - це односторонні з'єднання між кімнатами. Кожну двері можна використовувати лише один раз .
  • Лише групи з 3 до 5 гравців можуть пройти через двері.
  • Група може пройти через двері, лише якщо сума їх числа за модулем 9 збігається з номером модуля 9 дверей.
  • Будь-який гравець, який проходить через 9 дверей, тікає (виграє).

Приклади

┌───┬───┬───┐
│   6   4   9
│ < │   |   |
│   3   5   9
└───┴───┴───┘ 

<являє собою вихідну точку. Усі гравці починають там.

У цій обстановці всі можуть втекти. Існують різні способи досягти цього, один з яких:

  • [1, 2, 3, 4, 5] проходять через двері 6 ((1 + 2 + 3 + 4 + 5)% 9 = 6), а [6, 7, 8, 9] проходять через двері 3 ((6 + 7 + 8 + 9)% 9 = 3). Усі зустрічаються у другій кімнаті.
  • [1, 2, 3, 7] проходять через двері 4, а [4, 5, 6, 8, 9] через двері 5.
  • [1, 2, 3, 4, 8] пройти через одну з 9 дверей, [5, 6, 7, 9] пройти через іншу.
┌───┬───┐
│   │   |
│ < 8   9
│   │   |
└───┴───┘ 

Цього разу можна врятуватись не більше ніж 4 людини:

  • [1, 3, 5, 8, 9] проходять через двері 8.
  • [1, 3, 5, 9] пройти через двері 9.

Можливі й інші списки тих, хто вижив, таких як [2, 3, 4] або [1, 4, 6, 7], але більше ніж 4 людини не можуть врятуватися.

Змагання

Давши карту, виведіть максимальну кількість гравців, які можуть втекти.

  • Не хвилюйтесь, вам не потрібно розбирати мої жахливі діаграми! Введення - це позначений графіком спрямований графік, який ви можете представити у будь-якому зручному форматі (набір ребер, матриця суміжності ...).
  • Якщо для представлення потрібні мітки для приміщень, ви можете використовувати будь-який послідовний набір значень. Однак двері повинні бути представлені цілими числами 1 до 9.
  • Вхід завжди матиме щонайменше одну 9 дверей. Усі 9 дверей завжди ведуть до виходу, тоді як інші двері ніколи не роблять.
  • Ваше подання може бути функцією або повноцінною програмою.
  • Стандартні лазівки заборонені.

Тестові справи

Вхідні дані відображаються у вигляді списків [номер дверей, від кімнати до кімнати] трійки, 0 - початкова кімната, а -1 - вихід. Якщо ви вирішите використовувати інший формат, вам доведеться їх належним чином перетворити.

Input                                                                      Output
[[6, 0, 1], [3, 0, 1], [4, 1, 2], [5, 1, 2], [9, 2, -1], [9, 2, -1]]       9
[[8, 0, 1], [9, 1, -1]]                                                    4
[[9, 0, -1]]                                                               5
[[2, 0, 1], [1, 1, 2], [9, 2, -1]]                                         0
[[2, 0, 1], [3, 1, 2], [9, 2, -1]]                                         3
[[1, 0, 1], [9, 1, -1], [1, 0, 2], [9, 2, -1]]                             4
[[2, 0, 1], [3, 0, 1], [5, 1, 2], [4, 0, 2], [9, 2, -1], [9, 2, -1]]       8
[[3, 0, 1], [4, 0, 1], [5, 0, 1], [9, 1, -1], [7, 1, 2], [9, 2, -1]]       7
[[1, 0, 1], [2, 0, 1], [4, 0, 1], [9, 1, -1], [8, 1, 2], [9, 2, -1]]       6
[[6, 0, 1], [7, 0, 1], [9, 1, -1], [9, 1, -1]]                             7

4
Я знаю, що це пережиток гри 999, але мене
— клопочуть,

Можливо, варто розібратися в описі та мальовничих прикладах того, що деякі двері обходять кімнати. Чи можуть двері коли-небудь йти назад? Тобто деякі люди можуть піти 0-> 1-> вихід, а інші йти 0-> 2-> 1-> вихід?
— Нік Кеннеді

@NickKennedy не впевнений, що ви маєте на увазі під «обходом». Двері можуть підключити будь-яку кімнату до будь-якої іншої кімнати. Це спрямований графік.
— Grimmy

Якщо ви вважаєте, що ця серія правил може стати цікавішою із загрозою мимовільного вибуху, як тільки хто помилиться, будь ласка, спробуйте. Це чудово.
— розкидання

@Grimy впевнений, але мальовничі приклади та перші 5 фактичних прикладів мають усі двері, що ведуть від однієї кімнати до наступної праворуч.
— Нік Кеннеді

Відповіді:


7

JavaScript (ES6), 219 байт

Більш повільна, але значно коротша версія, що використовує бітові маски замість рядків.

f=(D,P=[511],e=m=0)=>P.map((X,r)=>[...Array(-~X)].map((_,p)=>D.map(([d,s,t],j)=>(N=(g=(n,k)=>n&&n%2+g(n>>1,++k,x+=n%2*k))(p&=X,x=0))<3|N>5|r-s|x%9^d%9||f(D.filter(_=>j--),A=[...P],e+!~t*N,A[r]^=p,A[t]^=p))),m=m>e?m:e)|m

Спробуйте в Інтернеті!

X(XAND⁡p)0≤p≤X


JavaScript (ES7),  293 272  271 байт

Вводить дані у форматі, описаному в виклику. Це жорстокий пошук.

f=(D,P=[17**6+'8'],e=m=0)=>P.map((X,r)=>X&&[...X].reduce((a,x)=>[...a,...a.map(y=>y+x)],['']).map(p=>D.map(([d,s,t],j)=>p<99|p[5]|r-s|eval([...p].join`+`)%9^d%9||f(D.filter(_=>j--),A=[...P],e+!~t*p.length,A[r]=X.replace(eval(`/[${p}]/g`),''),A[t]=[A[t]]+p))),m=m>e?m:e)|m

Спробуйте в Інтернеті! (у TIO вийшов перший тестовий випадок)

Як?

Масив P[]містить список рядків, що описують гравців у кожній кімнаті.

P=['241375698']176=241375690

Для кожної кімнати Xв положенні rми обчислюємо живлення X:

[...X].reduce((a, x) => [...a, ...a.map(y => y + x)], [''])

Для кожної групи гравців, що знаходяться pтам, і для кожної двері [d,s,t]в індексі j, ми перевіряємо, чи група не може пройти через двері:

                         // we can't pass if:
p < 99 |                 // there are less than 3 players
p[5] |                   // or there are more than 5 players
r - s |                  // or the source room s is not equal to the current room
eval([...p].join`+`) % 9 // or the sum of the players modulo 9
^ d % 9                  // does not match the ID of the door modulo 9

Якщо група може пройти, ми робимо рекурсивний дзвінок:

f(                       //
  D.filter(_ => j--),    // remove the door that has just been used from D[]
  A = [...P],            // use a copy A[] of P[]
  e + !~t * p.length,    // if t = -1, add the length of p to e (number of escaped guys)
  A[r] = X.replace(      // remove the players from the source room A[r]
    eval(`/[${p}]/g`),   //
    ''                   //
  ),                     //
  A[t] = [A[t]] + p      // and append them to the target room A[t]
)                        //

Ми відстежуємо максимальну кількість гравців, що втекли, mі, врешті, повертаємо їх.


Ви просто випробовуєте всі можливості?
— Йона

1
@Jonah Так. Це може бути або дуже швидким, або дуже повільним, залежно від обмежень, накладених вхідними даними.
— Арнольд

2

Желе , 76 байт

2ịịœc3r5¤ẎS,%9EʋƇ1ị${ḟ@;ƭⱮ€Ḋị¥ż€Ḋ{ṛṪ}¦ƒ€
ç@€Ẏ;ḷṢ€€Q
“”WẋḊ€FṀƊ9RW¤;Wçƒ@⁸ẈṪ$€Ṁ

Спробуйте в Інтернеті!

Повна програма, що бере єдиний аргумент, спрямований графік, використовуючи кімнати 1, 2, ... і 0 як вихід. Повертає ціле число, яке є максимальним числом, яке може вийти. Повне пояснення, яке слід дотримуватися.

Потрібно працювати без Ṣ€€Q4-байтової економії, але спокійно відпочивати.

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