Dobble / SpotIt卡生成器


15

介绍

Dobble / Spot这是一种纸牌游戏,人们必须在最短的时间内在一对纸牌上发现相同的符号,并指出并移到下一对。每张卡具有多个符号(普通版为8个),但每对卡之间恰好有一个共同的符号。

来自游戏实体副本的示例: 带有成对示例的卡片

挑战

编写一个程序,给定一组符号(单个ascii字符)和单个卡上的符号数量,将生成输出列表卡,其中每个卡都有符号。显然有许多等效的组合,您的程序只需要编写任何组合就可以为给定的输入产生最大数量的卡片。

这是一个代码问题,因此代码越短越好。

如果在最复杂的情​​况下,在宇宙热死之前完成计算,那将也很好。

输入值

函数/ stdin的两个参数(您的选择)

  • 首先是符号的集合,例如'ABCDE'或['A','B','C','D','E']-您选择的格式,可以是字符串,集合,列表,流,或所选择语言的惯用语言。字符将从[A-Za-z0-9]的集合中给出,不能重复(因此输入符号集的最大大小为62)。它们不会在(因此您也可以在6个符号的情况下获得“ yX4i9A”)。

  • 第二个参数是整数,表示单张卡上的符号数量。小于符号集的大小。

输出量

打印用换行符分隔的多行,每行包含一张卡的符号。

例子

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阶的投影有限平面)。
乔纳森·艾伦

Answers:


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。对于任何元件eK,的基数e联盟x是1 x != eK; 因此,消除所有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-07]淘汰了我的R变量
  • -30 [16-12-09] K感谢@Leo,感谢我的意见

1
您真的需要在每一步中从C中减去集合K吗?我认为您进行的过滤(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挑战, Dom Hastings向我指出了这个问题可能是一个骗局(很可能是骗子),但是我注意到的一件事是,要制作一个N * N的完整Dobble牌面要困难得多+ N + 1张卡(和符号),每张卡具有N + 1个符号,其中N为非素数素数幂。对于N = 4 = 2 ^ 2,这将是一个使用4 * 4 + 4 + 1 = 21个符号和相同张数的纸牌;但是,此解决方案只能产生13张卡片的套,但可能只有21张
乔纳森·艾伦

@JonathanAllan刚刚添加了TIO链接。我以21个字符的字母和每张卡5个字符的字母运行该功能。它输出21张卡。我认为这是正确的,除非我误解了。
NonlinearFruit

嗯,对不起,那我一定在本地运行时出错了!(这是令4的全部Dobble甲板:)
乔纳森·艾伦

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字节,包括导入
Paul Mutser

感谢您的注意,我不确定他们是否这样做!
错误

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.