Mots du tableau périodique des éléments [clos]

9

À l'époque où j'étais étudiant de première année en chimie, je regardais le tableau périodique des éléments et épelais les mots sales avec le nombre d'éléments (HeCK serait 2619, 2-6-19).

Je pensais à ça l'autre jour quand j'ai vu une chemise incroyable qui expliquait BeEr (4-68)

Donc, mon défi de codegolf est le programme le plus court pour produire une liste de mots que vous pouvez épeler avec le tableau périodique des éléments ET le code numérique qui représenterait ce mot.

/ usr / share / dict / words ou tout autre dictionnaire que vous souhaitez utiliser pour la liste de mots. Si vous utilisez une liste de mots "non standard", faites-le nous savoir!

Rob
la source
'Le' code numérique? Qu'en est-il des cas où il y en a plus d'un? Par exemple CO vs Co.
Peter Taylor
3
En lisant les réponses ci-dessous, j'ai remarqué un endroit où tout le monde pouvait découper quelques caractères. Ils peuvent supprimer Co, Si, Sc, Os, Hs, Po, Pb, Np, No, Yb, Cs et peut-être d'autres de leur liste d'éléments, car ils peuvent tous être construits à partir d'autres éléments.
PhiNotPi
1
Pas Ytterbium, c'est mon élément préféré!
Rob
2
Juste pour clarifier, les éléments que j'ai énumérés peuvent toujours être supprimés en toute sécurité. Par exemple, l'ytterbium peut toujours être remplacé par un yttrium et un bore, quelle que soit la langue de la liste de mots.
PhiNotPi
1
Je ne suis pas sûr de bien comprendre la tâche: trouverons-nous des mots correspondants pour les éléments jusqu'à ce que chaque élément soit imprimé, ou imprimerons-nous chaque mot du dict, qui peut être combiné à partir de la table des éléments? Ou autre chose?
utilisateur inconnu

Réponses:

6

GolfScript ( 339 303 302 301 294 caractères)

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}%;

Avec crédit à PhiNotPi dont l'observation sur les éléments inutiles m'a permis d'économiser 33 caractères.

C'est IMO beaucoup plus idiomatique GolfScript que l'approche récursive précédente.

Notez que j'autorise les mots du dictionnaire à être mélangés ( Lest une fonction pour le texte en minuscule en supposant que cela n'a pas d'importance si les caractères non alpha sont cassés), mais je rejette tout avec des apostrophes ou des accents.

Comme il s'agit de code golf, j'ai optimisé la longueur du code plutôt que la vitesse. C'est horriblement lent. Il s'attend à ce que la liste de mots soit fournie à stdin et les sorties à stdout au format:

"ac[89]"
"accra[89 6 88]"
"achebe[89 2 4]"
...

(en minuscule les mots d'entrée en casse mixte pour lesquels il trouve une correspondance).

Si vous êtes plus intéressé par les éléments que par les chiffres en soi, pour le bas prix bas de 261 253 caractères, vous pouvez utiliser

n/{{{32|}%}:L~['']{{`{\+}+'HHeLiBeBCNOFNeNaMgAlPSClArKCaTiVCrMnFeZnGaGeAsSeBrKrRbSrYZrMoTcRuRhPdAgCdTeIXeBaLaCePrNdPmSmEuGdTbDyErTmLuTaWReIrPtAuHgTlAtRnFrRaAcThPaUAmCmEsFmMdLrRfDbSgMtDsRgUutFlLv'[1/{.0=96>{+}*}/]/}%.{L}%2$?.){=p 0}{;{L.,2$<=},.}if}do}%;

ce qui donne une sortie comme

"Ac"
"AcCRa"
"AcHeBe"
...
Peter Taylor
la source
Supprimer le personnage supplémentaire, "ne me dérange pas du tout. Et bien sûr, Peter Taylor entre et souffle tout le monde avec Golfscript.
Rob
3

Ruby - 547 393

Nouvelle version, merci pour les suggestions:

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
}

utilise des expressions rationnelles. lent, et beaucoup de place pour l'amélioration mais je dois y aller maintenant :-)

Patrick Oscity
la source
1
1) Vous pouvez épargner le stockage en utilisant l'astuce de Peter Taylor (comme dans son code d' origine): e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) L'expression variable n'est jamais utilisée. 3) Lire les mots de l' entrée standard: $<.each{|w|.... Avec ces modifications, le code a été réduit à 410 caractères.
manatwork
Je pense que vous pouvez également appliquer la même approche peu encombrante pour les éléments inutiles, au prix d'ajouter deux caractères à l'expression rationnelle. Utilisez l'espace si vous n'aimez pas les sauts de ligne - j'utilise principalement les sauts de ligne afin qu'il ne soit pas nécessaire de faire défiler pour voir la boucle principale.
Peter Taylor
2

Python 710 (357 + 261 + 92)

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()

Il y a certainement de la place pour des améliorations quelque part. Il convient également de noter que le deuxième niveau d'indentation utilise le caractère de tabulation.

Il faut un peu plus de 5 secondes (sur mon ordinateur) pour parcourir tout le dictionnaire, produisant une sortie comme celle-ci:

acaciin [89, 89, 53, 49]
acacin [89, 89, 49]
acalycal [89, 13, 39, 6, 13]
...

En ajoutant 18 autres caractères, vous pouvez obtenir une sortie avec la bonne majuscule:

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]
...

Vous pouvez également vérifier les mots individuels:

>>> m("beer")
('beer', [4, 68])
grc
la source
Pouvez-vous ajouter celui qui génère une capitalisation appropriée? Je pense que c'est assez soigné et je suis assez nouveau sur python.
Rob
0

Python - 1328 (975 + 285 caractères de code + 68 code de dictionnaire)

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)

Pour la partie dictionnaire:

f=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()
beary605
la source
Il est vraiment plus court d'utiliser une initialisation de hachage explicite que d'utiliser une initialisation de tableau explicite et de la transformer en un hachage d'index?
Peter Taylor
Je viens d'utiliser un dictionnaire pour en faciliter l'utilisation. Avoir un tableau de tuples serait un peu plus cher. Bien que commander les éléments serait une bonne idée ...
beary605
0

C, 775 771 caractères

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);
}

Entrée : mot par ligne, doit être en minuscules. usr/share/dict/wordsc'est bien.
Sortie : mot et chiffres, par exemple:acceptances,89,58,15,73,7,6,99

Logique :
c(w,o,l)vérifie le mot w, en commençant par l'élément l.
La récursion bidirectionnelle est utilisée - si le premier élément correspond à la tête de la liste d'éléments, vérifiez le reste de par wrapport à la liste complète des éléments. Si cette correspondance échoue, vérifiez le mot par rapport à la fin de la liste.
Le tampon oaccumule les numéros d'éléments le long du chemin réussi. Après une correspondance, il contiendra la liste des numéros et sera imprimé.

Problèmes :
La liste n'est pas encodée efficacement - trop "et ,". Mais de cette façon, elle est facile à utiliser. Je suis sûr qu'elle peut être beaucoup améliorée, sans trop de coût en code.

ugoren
la source