Parole dalla tavola periodica degli elementi [chiuso]


9

Quando ero una matricola al liceo che prendeva chimica, guardavo la tavola periodica degli elementi e scrivevo parole sporche con il numero degli elementi (HeCK sarebbe 2619, 2-6-19).

Ci stavo pensando l'altro giorno quando ho visto una maglietta straordinaria che spiegava BeEr (4-68)

Quindi la mia sfida con codegolf è il programma più breve per produrre un elenco di parole che puoi scrivere con la tavola periodica degli elementi E il codice numerico che rappresenterebbe quella parola.

/ usr / share / dict / words o qualunque dizionario si desideri utilizzare per l'elenco di parole. Se stai usando un elenco di parole "non standard", facci sapere di cosa si tratta!


'Il' codice numerico? E i casi in cui ce n'è più di uno? Ad esempio CO vs Co.
Peter Taylor,

3
Mentre leggo le risposte di seguito, ho notato un posto in cui tutti potevano ritagliare alcuni personaggi. Potrebbero rimuovere Co, Si, Sc, Os, Hs, Po, Pb, Np, No, Yb, Cs e forse altri dalla loro lista di elementi, dal momento che possono essere tutti costruiti da altri elementi.
PhiNotPi

1
Non Ytterbium, questo è il mio elemento preferito!
Rob,

2
Solo per chiarire, gli elementi che ho elencato possono sempre essere rimossi in modo sicuro. Ad esempio, Ytterbium può sempre essere sostituito con un ittrio e un boro, indipendentemente dalla lingua dell'elenco delle parole.
PhiNotPi

1
Non sono del tutto sicuro di aver compreso completamente il compito: troveremo le parole corrispondenti per gli elementi fino a quando non viene stampato ogni elemento, o dovremmo stampare ogni parola dal dict, che può essere combinata dalla tabella degli elementi? O qualcos'altro?
utente sconosciuto

Risposte:


6

GolfScript ( 339 303 302 301 294 caratteri)

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 il merito a PhiNotPi la cui osservazione su elementi non necessari mi ha permesso di salvare 33 caratteri.

Questo è IMO GolfScript molto più idiomatico rispetto al precedente approccio ricorsivo.

Si noti che consento alle parole nel dizionario di essere maiuscole / minuscole ( Lè una funzione per scrivere lettere minuscole partendo dal presupposto che non importa se i caratteri non alfabetici si rompono) ma le rifiuto con apostrofi o accenti.

Dato che si tratta di code golf, ho ottimizzato la lunghezza del codice piuttosto che la velocità. Questo è tremendamente lento. Si aspetta che la lista di parole sia fornita su stdin e le uscite su stdout nel formato:

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

(in minuscolo tutte le parole di input maiuscole e minuscole per le quali trova una corrispondenza).

Se sei più interessato agli elementi che ai numeri in sé, puoi usare il basso prezzo di 261 253 caratteri

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

che dà un output simile

"Ac"
"AcCRa"
"AcHeBe"
...

Elimina il personaggio in più, "non mi disturba affatto. E, naturalmente, Peter Taylor entra e colpisce tutti con il golfscript.
Rob,

3

Rubino - 547 393

Nuova versione, grazie per i suggerimenti:

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 regex. lento e molto margine di miglioramento, ma ora devo andare :-)


1
1) Si può risparmiare di archiviazione utilizzando il trucco di Peter Taylor (come nel suo codice originale): e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) La regex variabile non viene mai utilizzata. 3) Leggere le parole da standard input: $<.each{|w|.... Con queste modifiche il codice è stato ridotto a 410 caratteri.
arte

Penso che sia possibile applicare lo stesso approccio salvaspazio anche per elementi non necessari, al costo di aggiungere due caratteri alla regex di scansione. Usa lo spazio se non ti piacciono le newline: sto usando le newline principalmente in modo che non sia necessario scorrere per vedere il ciclo 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()

Ci sarà sicuramente spazio per miglioramenti da qualche parte. Vale anche la pena notare che il secondo livello di rientro utilizza il carattere di tabulazione.

Ci vogliono poco più di 5 secondi (sul mio computer) per passare attraverso l'intero dizionario, producendo un output come questo:

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

Aggiungendo altri 18 caratteri, puoi ottenere l'output con la giusta maiuscola:

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

Puoi anche controllare singole parole:

>>> m("beer")
('beer', [4, 68])

Puoi aggiungere quello che genera una corretta capitalizzazione? Penso che sia abbastanza pulito e sono abbastanza nuovo per Python.
Rob,

0

Python - 1328 (975 + 285 caratteri di codice + 68 codice dizionario)

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)

Per la parte del dizionario:

f=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()

È davvero più breve usare un'inizializzazione di hash esplicita che usare un'inizializzazione di array esplicita e trasformarla in un indice di hash?
Peter Taylor,

Ho appena usato un dizionario per facilità d'uso. Avere una serie di tuple sarebbe un po 'più costoso per i personaggi. Anche se ordinare gli elementi sarebbe una buona idea ...
beary605

0

C, 775 771 caratteri

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

Input : parola per riga, deve essere minuscola. usr/share/dict/wordsè ok.
Output : parole e numeri, ad es .:acceptances,89,58,15,73,7,6,99

Logica :
c(w,o,l)controlla la parola w, iniziando con l'elemento l.
Viene utilizzata la ricorsione a due vie: se il primo elemento corrisponde alla testa dell'elenco di elementi, controllare il resto di wcontro l'elenco di elementi completo. Se questa corrispondenza fallisce, controlla la parola in fondo alla lista.
Il buffer oaccumula i numeri degli elementi lungo il percorso corretto. Dopo una partita, conterrà l'elenco dei numeri e verrà stampato.

Problemi :
l'elenco non è codificato in modo efficiente, troppo "e ,". Ma in questo modo è facile da usare. Sono sicuro che può essere molto migliorato, senza troppi costi nel codice.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.