反射词典是一个自我描述的单词列表,用来描述它自己的字母计数。举个例子,艾德·米勒1985年在英语中发现了一个:
16 e,6 f,1 g,3 h,9 i,9 n,5 o,5 r,16 S,5 t,3 u,4 v,1 w,4 x‘s
这个反射词典包含了它所说的按照定义所做的事情。这些在计算上非常密集,但您的工作是使用罗马数字查找所有可能的反射词典;所涉及的字母(I V X L C D M)要少得多,这就是搜索空间减少的原因。注意包含“1g”的英语反射词汇-我们可以称它为“虚拟文本”,这是允许的。我们减少的字母表只包含数字中的字母。使用罗马数字的反射词典的形式如下:
第十二、四、五、二十
计数(12I,4V,2X)是不正确的-这只是说明了格式(注意没有复数's)。如果字母的计数为0,则完全省略(在本例中没有L )。
为了方便起见,这里列出了罗马数字1.40 (怀疑您需要的比这更多):
I II III IV V VI VII VIII IX X
XI XII XIII XIV XV XVI XVII XVIII XIX XX
XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX
XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII XXXIX XL这些都是有效的反射词典(但这些并不是全部!):
IV I,II V V I,I L,II V,I X V I,II V,I X,I L
标准的code-golf规则适用-找到所有使用罗马数字的自反词!每行一条
发布于 2021-12-19 11:02:43
≔⪪”{⊞‴ΣAº⧴θπ⪪λpAz” θΦE×¹⁶φ⪫Φ⁺E⮌↨﹪κφχ∧λ⁺⁺§θλ §IVXμE⮌↨÷κφ²×λ⁺I §LCDMμλ, ∧κ⁼﹪κφI⭆XVI№ιλ在网上试试!链接是详细的代码版本。解释:
≔⪪”{⊞‴ΣAº⧴θπ⪪λpAz” θ在空格上拆分压缩字符串I II III IV V VI VII VIII IX。由于只有七个不同的罗马数字,描述字符串只能有一个字母的22。然而,这意味着字母L、C、D和M只能出现一次,仅限于描述字符串中的14 Is。我不相信你真的可以超过9 Is,并且使用基本10使下面的循环有点像高尔夫。
ΦE×¹⁶φ⪫Φ⁺E⮌↨﹪κφχ∧λ⁺⁺§θλ §IVXμE⮌↨÷κφ²×λ⁺I §LCDMμλ, ∧κ⁼﹪κφI⭆XVI№ιλ获取数字的基10数字,直到1000,然后对高阶位使用基2,生成由数字表示的描述字符串,计数每个罗马数字出现的次数,将数字视为基10,并输出这些描述字符串,这等于原始数字。请注意,我不需要计算L、D、C和M的出现次数,因为它们总是出现正确的次数,并且只存在于膨胀Is的计数中。
发布于 2021-12-19 18:23:51
import itertools as i
d={'I':1,'II':2,'III':3,'IV':4,'V':5,'VI':6,'VII':7,'VIII':8,'IX':9,'X':10,'XI':11,'XII':12,'XIII':13,'XIV':14,'XV':15,'XVI':16,'XVII':17,'XVIII':18,'XIX':19,'XX':20,'XXI':21,'XXII':22,'XXIII':23,'XXIV':24,'XXV':25,'XXVI':26,'XXVII':27,'XXVIII':28,'XXIX':29,'XXX':30,'XXXI':31,'XXXII':32,'XXXIII':33,'XXXIV':34,'XXXV':35,'XXXVI':36,'XXXVII':37,'XXXVIII':38,'XXXIX':39,'XL':40}
q=lambda p,s:all(d[a]==s.count(b)for a,b in p)and all(any(m==j for _,m in p)for b,_ in p for j in b)
def g(s):
k=[1 if not(m:=max(h.count(i)for h in d))else sum([m]*len(s))for i in s]
yield from i.product(*[[j for j in d if d[j]<=a]for a in k])
f=lambda s:{n for b in range(1,len(s)+1)for m in i.combinations(s,b)for j in g(m)if q(u:=[*zip(j,m)],(n:=','.join(a+' '+b for a, b in u)))}代码能够在大约0.4秒内完成对反射词汇的处理。逻辑的关键是,对于“基”罗马数字输入中的每个字符(即IV、IVX、VXMC等),首先要找到字符可以出现的最大次数(例如,I出现的最大3次数,而M没有发生),取最大值(如果字母不发生,则设置为1),然后将最大值乘以基输入的长度,从而为每个罗马数字的范围生成一个上限,大幅度减少了必须生产的笛卡尔产品的总数。
我相信这个解决方案可以被进一步提高--罗马数字查找表占据了令人难以置信的空间。
发布于 2021-12-19 23:05:34
严格的输出格式促使我尝试一种kolmogorov-复杂性方法。这是基于尼尔的回答的输出。
这显然是非常快的,我认为与一些实际计算字符串的代码相比,这是相当有竞争力的(就大小而言)。
_=>`IV I, II V${"XLXCLCXDLDCDXMLMCMDM".replace(/../g,a=>[i=`
V`,0,0,0].map(n=>i+" I, II V0"+a[i+='I',0]+0+a[1]).join``)}
IX I0V, II X0L0C0D0M`.split`0`.join`, I `https://codegolf.stackexchange.com/questions/239815
复制相似问题