回到我高中一年级时读化学的时候,我会看一下元素周期表,并用元素的数量拼出脏话(HeCK会是2619,2-6-19)。
前几天,我在想这件事,当时看到一件出色的衬衫拼出BeEr(4-68)
因此,我的codegolf挑战是用于输出可以与元素周期表拼写的单词列表以及代表该单词的数字代码的最短程序。
/ usr / share / dict / words或要用于单词列表的任何词典。如果您使用的是“非标准”单词列表,请告诉我们它是什么!
回到我高中一年级时读化学的时候,我会看一下元素周期表,并用元素的数量拼出脏话(HeCK会是2619,2-6-19)。
前几天,我在想这件事,当时看到一件出色的衬衫拼出BeEr(4-68)
因此,我的codegolf挑战是用于输出可以与元素周期表拼写的单词列表以及代表该单词的数字代码的最短程序。
/ usr / share / dict / words或要用于单词列表的任何词典。如果您使用的是“非标准”单词列表,请告诉我们它是什么!
Answers:
n/{{{32|}%}:L~['']{{`{\+}+'HHeLiBeBCNOFNeNaMgAl
PSClArKCa TiVCrMnFe
ZnGaGeAsSeBrKrRbSrYZr
MoTcRuRhPdAgCd
TeIXe
BaLaCePrNdPmSmEuGdTbDy
ErTm
Lu
TaWRe
IrPtAuHgTl
AtRnFrRaAcThPaU
AmCm
EsFmMd
LrRfDbSg
MtDsRg
UutFl
Lv'{[1/{.0=96>{+}*}/]}:S~:^/}%.{L}%2$?.){=S{^?}%`+p 0}{;{L.,2$<=},.}if}do}%;
归功于PhiNotPi,他对不必要元素的观察使我节省了33个字符。
与以前的递归方法相比,这是IMO更加惯用的GolfScript。
请注意,我允许字典中的单词混合使用大小写(L
假设非字母字符不被破坏,这是小写文本的功能),但拒绝任何带有撇号或重音符号的单词。
由于这是代码高尔夫,因此我针对代码长度而不是速度进行了优化。这太慢了。它期望单词列表在stdin提供,并以以下格式输出到stdout:
"ac[89]"
"accra[89 6 88]"
"achebe[89 2 4]"
...
(将找到匹配的所有大小写混合的输入单词的小写)。
如果您对元素本身比对数字更感兴趣,那么可以使用261253个字符的低廉低价来使用
n/{{{32|}%}:L~['']{{`{\+}+'HHeLiBeBCNOFNeNaMgAlPSClArKCaTiVCrMnFeZnGaGeAsSeBrKrRbSrYZrMoTcRuRhPdAgCdTeIXeBaLaCePrNdPmSmEuGdTbDyErTmLuTaWReIrPtAuHgTlAtRnFrRaAcThPaUAmCmEsFmMdLrRfDbSgMtDsRgUutFlLv'[1/{.0=96>{+}*}/]/}%.{L}%2$?.){=p 0}{;{L.,2$<=},.}if}do}%;
这给出了输出
"Ac"
"AcCRa"
"AcHeBe"
...
"
一点也不打扰我。当然,彼得·泰勒(Peter Taylor)进来,用golfscript打击了所有人。
新版本,感谢您的建议:
e='HHeLiBeBCNOFNeNaMgAlSiPSClArKaCaScTiVCrMnFeCoNiCuZnGaGeAsSeBrKrRbSrYZrNbMoTcRuRhPdAgCdInSnSbTeIXeCsBaLaCePrNdPmSmEuGdTbDyHoErTmYbLuHfTaWReOsIrPtAuHgTlPbBiPoAtRnFrRaAcThPaUNpPuAmCmBkCfEsFmMdNoLrRfDbSgBhHsMtDsRgCnUutFlUupLvUusUuo'.scan(/[A-Z][a-z]*/).map &:upcase
r="(#{e.join ?|})"
$<.each{|w|(i=0;i+=1 until w=~/^#{r*i}$/i
$><<w;p$~.to_a[1..-1].map{|m|e.index(m.upcase)+1})if w=~/^#{r}+$/i}
e=%w{h he li be b c n o f ne na mg al si p s cl ar ka ca sc ti v cr mn fe co ni cu zn ga ge as se br kr rb sr y zr nb mo tc ru rh pd ag cd in sn sb te i xe cs ba la ce pr nd pm sm eu gd tb dy ho er tm yb lu hf ta w re os ir pt au hg tl pb bi po at rn fr ra ac th pa u np pu am cm bk cf es fm md no lr rf db sg bh hs mt ds rg cn uut fl uup lv uus uuo}
x = "(#{e.join(?|)})"
regex = /^#{x}+$/i
File.foreach('/usr/share/dict/words'){|w|
if w=~/^#{x}+$/i
puts w
i=1
i+=1 until w=~/^#{x*i}$/i
puts $~[1..-1].map{|m|e.index(m.downcase)+1}.join ?-
end
}
使用正则表达式。速度慢,还有很多改进的余地,但我现在必须走了:-)
e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase
。2)永远不要使用可变正则表达式。3)从标准输入中读取单词:$<.each{|w|...
。经过这些修改,代码减少到410个字符。
e=". h he li be b c n o f ne na mg al si p s cl ar k ca sc ti v cr mn fe co ni cu zn ga ge as se br kr rb sr y zr nb mo tc ru rh pd ag cd in sn sb te i xe cs ba la ce pr nd pm sm eu gd tb dy ho er tm yb lu hf ta w re os ir pt au hg tl pb bi po at rn fr ra ac th pa u np pu am cm bk cf es fm md no lr rf db sg bh hs mt ds rg cn uut fl uup lv uus uuo".split()
i=e.index
def m(w,p=("",[])):
if not w:return p
x,y,z=w[0],w[:2],w[:3]
if x!=y and y in e:
a=m(w[2:],(p[0]+y,p[1]+[i(y)]))
if a:return a
if x in e:
b=m(w[1:],(p[0]+x,p[1]+[i(x)]))
if b:return b
if z in e:
c=m(w[3:],(p[0]+z,p[1]+[i(z)]))
if c:return c
f=open('/usr/share/dict/words','r')
for l in f:
x=m(l[:-1])
if x:print x[0],x[1]
f.close()
在某个地方肯定会有改进的空间。还值得注意的是,第二级缩进使用制表符。
(在我的计算机上)整个字典花了5秒钟多的时间,产生如下输出:
acaciin [89, 89, 53, 49]
acacin [89, 89, 49]
acalycal [89, 13, 39, 6, 13]
...
通过再添加18个字符,可以获得正确的大小写输出:
e=". H He Li Be B C N O F Ne Na Mg Al Si P S Cl Ar K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe Cs Ba La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn Fr Ra Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr Rf Db Sg Bh Hs Mt Ds Rg Cn Uut Fl Uup Lv Uus Uuo".split()
i=e.index
def m(w,p=("",[])):
if not w:return p
w=w.capitalize()
x,y,z=w[0],w[:2],w[:3]
if x!=y and y in e:
a=m(w[2:],(p[0]+y,p[1]+[i(y)]))
if a:return a
if x in e:
b=m(w[1:],(p[0]+x,p[1]+[i(x)]))
if b:return b
if z in e:
c=m(w[3:],(p[0]+z,p[1]+[i(z)]))
if c:return c
OUTPUT:
AcAcIIn [89, 89, 53, 49]
AcAcIn [89, 89, 49]
AcAlYCAl [89, 13, 39, 6, 13]
...
您还可以检查单个单词:
>>> m("beer")
('beer', [4, 68])
t1={'c':6,'b':5,'f':9,'i':53,'h':1,'k':19,'o':8,'n':7,'p':15,
's':16,'u':92,'w':74,'v':23,'y':39}
t2={'ru':44,'re':75,'rf':104,'rg':111,'ra':88,'rb':37,
'rn':86,'rh':45,'be':4,'ba':56,'bh':107,'bi':83,
'bk':97,'br':35,'os':76,'ge':32,'gd':64,'ga':31,
'pr':59,'pt':78,'pu':94,'pb':82,'pa':91,'pd':46,
'cd':48,'po':84,'pm':61,'hs':108,'ho':67,'hf':72,
'hg':80,'he':2,'md':101,'mg':12,'mo':42,'mn':25,
'mt':109,'zn':30,'eu':63,'es':99,'er':68,'ni':28,
'no':102,'na':11,'nb':41,'nd':60,'ne':10,'np':93,
'fr':87,'fe':26,'fl':114,'fm':100,'sr':38,'kr':36,
'si':14,'sn':50,'sm':62,'sc':21,'sb':51,'sg':106,
'se':34,'co':27,'cn':112,'cm':96,'cl':17,'ca':20,
'cf':98,'ce':58,'xe':54,'lu':71,'cs':55,'cr':24,
'cu':29,'la':57,'li':3,'lv':116,'tl':81,'tm':69,
'lr':103,'th':90,'ti':22,'te':52,'tb':65,'tc':43,
'ta':73,'yb':70,'db':105,'dy':66,'ds':110,'at':85,
'ac':89,'ag':47,'ir':77,'am':95,'al':13,'as':33,
'ar':18,'au':79,'zr':40,'in':49}
t3={'uut':113,'uuo':118,'uup':115,'uus':117}
def p(s):
o=0;b=0;a=[];S=str;l=S.lower;h=dict.has_key;L=len
while o<L(s):
D=0
for i in 1,2,3:exec('if h(t%d,l(s[o:o+%d])) and b<%d:a+=[S(t%d[s[o:o+%d]])];o+=%d;b=0;D=1'%(i,i,i,i,i,i))
if D==0:
if b==3 or L(a)==0:return
else:b=L(S(a[-1]));o-=b;a.pop()
return '-'.join(a)
对于字典部分:
f=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()
char*e[]={"h","he","li","be","b","c","n","o","f","ne","na","mg","al","si","p","s","cl","ar","k","ca","sc","ti","v","cr","mn","fe","co","ni","cu","zn","ga","ge","as","se","br","kr","rb","sr","y","zr","nb","mo","tc","ru","rh","pd","ag","cd","in","sn","sb","te","i","xe","cs","ba","la","ce","pr","nd","pm","sm","eu","gd","tb","dy","ho","er","tm","yb","lu","hf","ta","w","re","os","ir","pt","au","hg","tl","pb","bi","po","at","rn","fr","ra","ac","th","pa","u","np","pu","am","cm","bk","cf","es","fm","md","no","lr","rf","db","sg","bh","hs","mt","ds","rg","cn","uut","fl","uup","lv","uus","uu",0};
b[99],n;
c(w,o,l)char*w,*o,**l;{
return!*w||!strncmp(*l,w,n=strlen(*l))&&c(w+n,o+sprintf(o,",%d",l-e+1),e)||*++l&&c(w,o,l);
}
main(){
while(gets(b))c(b,b+9,e)&&printf("%s%s\n",b,b+9);
}
输入:每行单词,必须小写。usr/share/dict/words
很好
输出:单词和数字,例如:acceptances,89,58,15,73,7,6,99
逻辑:
c(w,o,l)
检查单词w
,从元素开始l
。
使用双向递归-如果第一个元素与元素列表的开头匹配,请w
对照完整元素列表检查其余元素。如果此匹配失败,请对照列表尾部检查单词。
缓冲区o
沿成功路径累积元素编号。比赛之后,它将包含数字列表并被打印。
问题:
列表没有被有效地编码-太多"
和,
“。但是这种方式很容易使用。我相信它可以大大改进,而无需花费太多代码。