Palabras de la tabla periódica de elementos [cerrado]

9

Cuando era un estudiante de primer año en la escuela secundaria que tomaba química, miraba la tabla periódica de elementos y deletreaba palabras sucias con el número de elementos (HeCK sería 2619, 2-6-19).

Estaba pensando en esto el otro día cuando vi una camiseta increíble que explicaba BeEr (4-68)

Entonces, mi desafío codegolf es el programa más corto para generar una lista de palabras que puede deletrear con la tabla periódica de elementos Y el código numérico que representaría esa palabra.

/ usr / share / dict / words o cualquier diccionario que quieras usar para la lista de palabras. Si está utilizando una lista de palabras "no estándar", ¡háganos saber qué es!

Robar
fuente
'El' código de número? ¿Qué pasa con los casos en los que hay más de uno? Por ejemplo, CO vs Co.
Peter Taylor
3
Mientras leo las respuestas a continuación, noté un lugar en el que todos podían eliminar algunos caracteres. Pueden eliminar Co, Si, Sc, Os, Hs, Po, Pb, Np, No, Yb, Cs y quizás otros de su lista de elementos, ya que todos pueden construirse a partir de otros elementos.
PhiNotPi
1
¡No el iterbio, ese es mi elemento favorito!
Rob
2
Solo para aclarar, los elementos que enumeré siempre se pueden eliminar de forma segura. Por ejemplo, el iterbio siempre se puede reemplazar con un itrio y un boro, sin importar en qué idioma esté la lista de palabras.
PhiNotPi
1
No estoy muy seguro de si entiendo la tarea por completo: ¿encontraremos palabras coincidentes para los elementos hasta que se imprima cada elemento, o imprimiremos cada palabra del dict, que se puede combinar desde la tabla de elementos? ¿O algo mas?
usuario desconocido

Respuestas:

6

GolfScript ( 339 303 302 301 294 caracteres)

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

Con crédito a PhiNotPi, cuya observación sobre elementos innecesarios me permitió guardar 33 caracteres.

Esto es IMO GolfScript mucho más idiomático que el enfoque recursivo anterior.

Tenga en cuenta que permito que las palabras en el diccionario sean mayúsculas y minúsculas ( Les una función para texto en minúsculas suponiendo que no importa si los caracteres no alfabéticos se rompen), pero rechazo cualquiera con apóstrofes o acentos.

Como se trata de código de golf, he optimizado la longitud del código en lugar de la velocidad. Esto es terriblemente lento. Espera que la lista de palabras se suministre en stdin y las salidas a stdout en el formato:

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

(en minúsculas las palabras de entrada de mayúsculas y minúsculas para las que encuentra una coincidencia).

Si está más interesado en los elementos que en los números en sí, por el bajo precio de 261 253 caracteres puede usar

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

que da salida como

"Ac"
"AcCRa"
"AcHeBe"
...
Peter Taylor
fuente
Saca el personaje extra, "no me molesta en absoluto. Y, por supuesto, entra Peter Taylor y sorprende a todos con golfscript.
Rob
3

Ruby - 547 393

Nueva versión, gracias por las sugerencias:

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
}

usa expresiones regulares. lento, y mucho margen de mejora, pero debo ir ahora :-)

Patrick Oscity
fuente
1
1) Se puede prescindir de almacenamiento utilizando el truco de Peter Taylor (como en el código original): e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) La expresión regular variable nunca se usa. 3) Leer las palabras de entrada estándar: $<.each{|w|.... Con esta modificación, el código se redujo a 410 caracteres.
manatwork
Creo que también puede aplicar el mismo enfoque de ahorro de espacio para elementos innecesarios, a costa de agregar dos caracteres a la expresión regular de escaneo. Use el espacio si no le gustan las líneas nuevas: estoy usando líneas nuevas principalmente para que no sea necesario desplazarse para ver el bucle principal.
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()

Seguramente habrá margen de mejora en algún lugar. También vale la pena señalar que el segundo nivel de sangría utiliza el carácter de tabulación.

Toma un poco más de 5 segundos (en mi computadora) revisar todo el diccionario, produciendo resultados como este:

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

Al agregar otros 18 caracteres, puede obtener resultados con la capitalización correcta:

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

También puede verificar palabras individuales:

>>> m("beer")
('beer', [4, 68])
grc
fuente
¿Puedes agregar el que produce la capitalización adecuada? Creo que eso es bastante bueno y soy bastante nuevo en Python.
Rob
0

Python - 1328 (975 + 285 caracteres de código + 68 código de diccionario)

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)

Para la parte del diccionario:

f=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()
beary605
fuente
¿Es realmente más corto usar una inicialización de hash explícita que usar una inicialización de matriz explícita y convertirla en un índice de hash?
Peter Taylor
Acabo de usar un diccionario para facilitar su uso. Tener una serie de tuplas sería un poco más costoso. Aunque ordenar los elementos sería una buena idea ...
beary605
0

C, 775 771 caracteres

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

Entrada : Palabra por línea, debe estar en minúscula. usr/share/dict/wordsestá bien.
Salida : palabra y números, por ejemplo:acceptances,89,58,15,73,7,6,99

Lógica :
c(w,o,l)verifica la palabra w, comenzando con el elemento l.
Se utiliza la recursión bidireccional: si el primer elemento coincide con el encabezado de la lista de elementos, compruebe el resto de wla lista de elementos completa. Si esta coincidencia falla, verifique la palabra en la cola de la lista.
El búfer oacumula los números de elementos a lo largo de la ruta exitosa. Después de una coincidencia, contendrá la lista de números y se imprimirá.

Problemas :
La lista no está codificada de manera eficiente, demasiado "y ,". Pero de esta manera es fácil de usar. Estoy seguro de que se puede mejorar mucho, sin demasiado costo en el código.

Ugoren
fuente