Palavras da tabela periódica de elementos [fechado]

9

Quando eu era calouro no ensino médio cursando química, olhava para a tabela periódica de elementos e escrevia palavras sujas com o número de elementos (HeCK seria 2619, 2-6-19).

Eu estava pensando nisso outro dia, quando vi uma camisa incrível que soletrava BeEr (4-68)

Portanto, meu desafio do codegolf é o programa mais curto para gerar uma lista de palavras que você pode escrever com a tabela periódica de elementos E o código numérico que representaria essa palavra.

/ usr / share / dict / words ou qualquer outro dicionário que você deseja usar para a lista de palavras. Se você estiver usando uma lista de palavras "não padrão", informe-nos o que é!

Roubar
fonte
'O' código numérico? E os casos em que há mais de um? Exemplo: CO vs Co.
Peter Taylor
3
Enquanto lia as respostas abaixo, notei um lugar em que todos podiam recortar alguns caracteres. Eles podem remover Co, Si, Sc, Os, Hs, Po, Pb, Np, Não, Yb, Cs e talvez outros da lista de elementos, pois todos podem ser construídos a partir de outros elementos.
PhiNotPi
11
Não o itérbio, esse é o meu elemento favorito!
9263 Rob
2
Apenas para esclarecer, os elementos que listei sempre podem ser removidos com segurança. Por exemplo, o itérbio sempre pode ser substituído por um ítrio e um boro, independentemente do idioma da lista de palavras.
PhiNotPi
11
Não tenho certeza se entendo completamente a tarefa: encontraremos palavras correspondentes para os elementos até que cada elemento seja impresso, ou devemos imprimir todas as palavras do ditado, que podem ser combinadas na tabela de elementos? Ou alguma outra coisa?
usuário desconhecido

Respostas:

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

Com o crédito ao PhiNotPi, cuja observação sobre elementos desnecessários me permitiu economizar 33 caracteres.

Isso é muito mais idiomático do GolfScript do que a abordagem recursiva anterior.

Observe que eu permito que as palavras no dicionário sejam maiúsculas e minúsculas ( Lé uma função para o texto em minúsculas, supondo que não importa se caracteres não-alfa são quebrados), mas rejeito qualquer um com apóstrofos ou acentos.

Como se trata de código de golfe, otimizei o tamanho do código, e não a velocidade. Isso é terrivelmente lento. Ele espera que a lista de palavras seja fornecida em stdin e produza stdout no formato:

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

(em maiúsculas e minúsculas quaisquer palavras de entrada em maiúsculas e minúsculas para as quais encontra uma correspondência).

Se você está mais interessado nos elementos do que nos números em si, pelo preço baixo e baixo de 261 253 caracteres, você pode usar

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

o que dá saída como

"Ac"
"AcCRa"
"AcHeBe"
...
Peter Taylor
fonte
Pegue o personagem extra, "não me incomoda. E, é claro, Peter Taylor entra e impressiona a todos com o golfscript.
9263 Rob
3

Ruby - 547 393

Nova versão, obrigado pelas sugestões:

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 expressões regulares. lento e muito espaço para melhorias, mas devo ir agora :-)

Patrick Oscity
fonte
11
1) Você pode poupar armazenamento usando o truque de Peter Taylor (como no seu código original): e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) Regex variável nunca é usado. 3) Leia as palavras de entrada padrão: $<.each{|w|.... Com essas modificações, o código foi reduzido para 410 caracteres.
manatwork
Eu acho que você também pode aplicar a mesma abordagem de economia de espaço para elementos desnecessários, com o custo de adicionar dois caracteres ao regex de verificação. Use espaço se você não gosta de novas linhas - eu estou usando novas linhas principalmente para que não seja necessário rolar para ver o loop 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()

Certamente haverá espaço para melhorias em algum lugar. Também é importante notar que o segundo nível de recuo usa o caractere de tabulação.

Leva apenas mais de 5 segundos (no meu computador) para percorrer todo o dicionário, produzindo resultados como este:

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

Ao adicionar outros 18 caracteres, você pode obter a saída com a capitalização correta:

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

Você também pode verificar palavras individuais:

>>> m("beer")
('beer', [4, 68])
grc
fonte
Você pode adicionar o que gera uma capitalização adequada? Eu acho isso muito legal e eu sou muito novo em python.
Rob
0

Python - 1328 (975 + 285 caracteres de código + 68 código de dicionário)

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 a parte do dicionário:

f=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()
beary605
fonte
É realmente mais curto usar uma inicialização explícita de hash do que usar uma inicialização explícita de matriz e transformá-la em um índice de hash?
22411 Peter
Acabei de usar um dicionário para facilitar o uso. Ter uma matriz de tuplas seria um pouco mais caro para o personagem. Embora a ordenação dos elementos seria uma boa ideia ...
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 : o Word por linha deve estar em minúsculas. usr/share/dict/wordsestá bem.
Saída : palavra e números, por exemplo:acceptances,89,58,15,73,7,6,99

Lógica :
c(w,o,l)verifica a palavra w, começando com o elemento l.
A recursão bidirecional é usada - se o primeiro elemento corresponder ao início da lista de elementos, verifique o restante da wlista de elementos completa. Se essa correspondência falhar, verifique a palavra no final da lista.
O buffer oacumula os números dos elementos ao longo do caminho bem-sucedido. Após uma correspondência, ela conterá a lista de números e será impressa.

Problemas :
a lista não é codificada com eficiência - muito "e ,". Mas dessa maneira é fácil de usar. Tenho certeza de que pode ser muito melhorada, sem muito custo no código.

Ugoren
fonte