Генератор карток / SpotIt


15

Вступ

Dobble / SpotIt - це карткова гра, де люди повинні за короткий час помітити один і той же символ на пару карт, вказати його та перейти до наступної пари. Кожна карта має кілька символів (8 у звичайній версії), але саме одна є загальною між кожною парою карт.

Приклад з фізичної копії гри: Картки з прикладами пар

Виклик

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

Це код-гольф, тому коротше код, тим краще.

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

Вхідні дані

Два аргументи до функції / stdin (на ваш вибір)

  • Спочатку це колекція символів, на кшталт "ABCDE" або ["A", "B", "C", "D", "E"] - ваш вибір формату, будь то рядок, набір, список, потік або будь-яка інша мова для вибору мови. Символи будуть надані з набору [A-Za-z0-9], без дублікатів (тому максимальний розмір набору символів введення - 62). Вони не обов'язково будуть впорядковані в ( тож ви можете отримати "yX4i9A" також для 6-символьного випадку).

  • Другий аргумент - ціле число, що вказує кількість символів на одній карті. Це буде <= розмір набору символів.

Вихідні дані

Роздрукуйте кілька рядків, розділених новими рядками, кожен з яких містить символи для однієї картки.

Приклади

ABC
2
>>>>
AB
BC
AC

Або

ABCDEFG
3
>>>>
ABC
BDE
CEF
BFG
AEG
CDG
ADF

Або

ABCDE
4
>>>>
ABCD

Підказки

  • Кількість виготовлених карток не може перевищувати кількість виразних символів, і в багатьох комбінаціях вона буде значно меншою
  • Можливо, ви захочете прочитати деякий математичний фон, якщо вам потрібна допомога з математичної сторони проблеми

Це мій перший виклик гольфу з кодом, тому, будь ласка, пробачте можливі проблеми із форматуванням / стилем - я спробую виправити помилки, якщо ви вкажете їх у коментарях.



Пропонований тестовий випадок ('abcdefghijklmnopqrstu', 5)-> ['abcde', 'afghi', 'ajklm', 'anopq', 'arstu', 'bfjnr', 'bgkpt', 'bhlou', 'bimqs', 'cfkqu', 'cgjos', 'chmpr', 'cilnt', 'dfmot', 'dglqr', 'dhkns', 'dijpu', 'eflps', 'egmnu', 'ehjqt', 'eikor']або інше робоче рішення з 21 карткою. (Зверніть увагу, що це проективна кінцева площина порядку 4).
Джонатан Аллан

Відповіді:


5

Python 2 , 192 162 байти

У мене є аргумент, що це створює максимальний набір карт для кожного сценарію, і він обробляє 3 тестові справи.

from itertools import*
def m(a,s):
    C=["".join(x)for x in combinations(a,s)]
    while len(C):
        print C[0]
        C=list(set(A for A in C if len(set(A)&set(C[0]))==1<s))

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

Алгоритм

Враховуючи алфавіт aта розмір картки s, візьміть усі комбінації sелементів aта назвіть її C, а потім:

  • Візьміть перший елемент C, назвіть йогоC0
  • Зберегти C0
  • Видаліть з нього всі елементи, Cякі мають з'єднання з C0рівним1
  • Повторіть з другим елементом C
  • Продовжуйте, поки Cпорожньо не буде

Потім надрукуйте збережені елементи.

Аргумент

Деякий непорожня підмножина Cнашого максимальне рішення K. Оскільки він містить щонайменше один елемент, а будь-які два елементи не відрізняються, виберіть довільний елемент C0, з якого Cслід входити K. Для будь-якого елемента eв K, простота eоб'єднання xдорівнює 1 для x != eв K; таким чином, усуньте всі елементи C, з’єднання з якими C0не має кардинальної стихії 1. За тими ж міркуваннями виберіть новий довільний елемент у C, додайте його Kта зменшіть C. Врешті-решт, Cце порожній набір і Kстане максимальним рішенням, оскільки ні в якому разі ми не вибрали елемент, який відрізнявся від будь-якого іншого елемента.


Випробування

Ці тестові справи були написані ще до того, як я зрозумів, що друк - це вимога.

a=["a","b","c"]
b=2
c=3
d=m(a,b)
print d,len(d)==c
>> ['bc', 'ab', 'ac'] True

a=["a","b","c","d","e","f","g"]
b=3
c=7
d=m(a,b)
print d,len(d)==c
>> ['aef', 'abc', 'bde', 'ceg', 'adg', 'cdf', 'bfg'] True

a=["a","b","c","d","e"]
b=4
c=1
d=m(a,b)
print d,len(d)==c
>> ['abcd'] True

Оновлення

  • +9 [16-12-07] Встановіть вимогу друку
  • -11 [16.12.2007] Гольф з моєї Rзмінної
  • -30 [16-12-09] Я переграв мою Kзмінну, завдяки @Leo !

1
Чи дійсно потрібно віднімати множину K від C на кожному кроці? Я думаю, що фільтрація, яку ви робите ( A for A in C if len(set(A)&set(C[0]))==1), вже видаляє вибрані елементи, якщо тільки s == 1 (у цьому випадку len (set (C [0]) & set (C [0])) буде 1). Ви можете покатати свій другий на останній рядок:C=[A for A in C if len(set(A)&set(C[0]))==1<s]
Лев

Я писав виклик Dobble у пісочниці, і Дом Гастінгс вказав мені на це питання як на можливий дуп (що це може бути), проте одне, що я помітив, - набагато важче зробити повноцінну колоду Dobble N * N Картки + N + 1 (і символи) з N + 1 символами на кожну карту, причому N є не першочерговою силою. Для N = 4 = 2 ^ 2 це була б колодка, що використовує 4 * 4 + 4 + 1 = 21 символи і стільки ж карт; однак це рішення виробляє колоду всього з 13 карт - все ж 21 можлива .
Джонатан Аллан

@JonathanAllan Щойно додав посилання TIO. Я керував функцією з алфавітом з 21 символом і з 5 символами на картці. Він випускає 21 карту. Я думаю, що це правильно, якщо я не зрозумів.
нелінійний

Хм, вибачте, я, мабуть, помилився, запустивши його локально! ( Ось повна колодка замовлення 4. :) )
Джонатан Аллан

2

Haskell, 175 156 байт

Моє перше заняття гольфом, дайте мені знати, чи я щось зіпсував.

import Data.List
f 0_=[[]]
f n a=g$c n a
c n a=[a!!i:x|i<-[0..(length a)-1],x<-f(n-1)(drop(i+1)a)]
g[]=[]
g(x:t)=x:g(filter(\z->length(z`intersect`x)<= 1)t)

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

Дякуємо @Paul Mutser за покращення та -19 байт


Оригінальна версія


1
Ласкаво просимо до PPCG! Зауважте, що імпорт зараховується до вашого показника. Можливе поліпшення: 156 байт, включаючи імпорт
Пол Муцер

Дякую за голову вгору, я не був впевнений, чи вони це зробили!
клопи

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