Wörter aus dem Periodensystem der Elemente [geschlossen]

9

Als ich ein Neuling in der Highschool war und Chemie studierte, schaute ich mir das Periodensystem der Elemente an und buchstabierte schmutzige Wörter mit der Anzahl der Elemente (HeCK wäre 2619, 2-6-19).

Ich habe neulich darüber nachgedacht, als ich ein tolles Shirt sah, auf dem BeEr (4-68) stand.

Meine Codegolf-Herausforderung ist also das kürzeste Programm zur Ausgabe einer Liste von Wörtern, die Sie mit dem Periodensystem der Elemente UND dem Zahlencode, der dieses Wort darstellen würde, buchstabieren können.

/ usr / share / dict / words oder ein beliebiges Wörterbuch, das Sie für die Wortliste verwenden möchten. Wenn Sie eine "nicht standardmäßige" Wortliste verwenden, teilen Sie uns mit, was es ist!

rauben
quelle
'Der' Nummerncode? Was ist mit Fällen, in denen es mehr als einen gibt? ZB CO vs Co.
Peter Taylor
3
Als ich die Antworten unten las, bemerkte ich einen Ort, an dem jeder ein paar Zeichen herausschneiden konnte. Sie können Co, Si, Sc, Os, Hs, Po, Pb, Np, Nein, Yb, Cs und möglicherweise andere aus ihrer Liste der Elemente entfernen, da sie alle aus anderen Elementen konstruiert werden können.
PhiNotPi
1
Nicht Ytterbium, das ist mein Lieblingselement!
Rob
2
Zur Verdeutlichung können die von mir aufgelisteten Elemente immer sicher entfernt werden. Zum Beispiel kann Ytterbium immer durch ein Yttrium und ein Bor ersetzt werden, egal in welcher Sprache die Wortliste ist.
PhiNotPi
1
Ich bin mir nicht ganz sicher, ob ich die Aufgabe vollständig verstehe: Sollen wir passende Wörter für die Elemente finden, bis jedes Element gedruckt wurde, oder sollen wir jedes Wort aus dem Diktat drucken, das aus der Elementtabelle kombiniert werden kann? Oder etwas anderes?
Benutzer unbekannt

Antworten:

6

GolfScript ( 339 303 302 301 294 Zeichen)

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

Mit Dank an PhiNotPi, dessen Beobachtung über unnötige Elemente es mir ermöglichte, 33 Zeichen zu sparen.

Dies ist IMO viel idiomatischer GolfScript als der vorherige rekursive Ansatz.

Beachten Sie, dass ich zulasse, dass Wörter im Wörterbuch in Großbuchstaben geschrieben werden ( Leine Funktion für Kleinbuchstaben unter der Annahme, dass es keine Rolle spielt, wenn Nicht-Alpha-Zeichen gebrochen werden), aber Wörter mit Apostrophen oder Akzenten ablehne.

Da dies Codegolf ist, habe ich eher die Codelänge als die Geschwindigkeit optimiert. Das ist schrecklich langsam. Es wird erwartet, dass die Wortliste bei stdin bereitgestellt wird und die Ausgaben im folgenden Format an stdout ausgegeben werden:

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

(Kleinbuchstaben für Eingabewörter in Großbuchstaben, für die eine Übereinstimmung gefunden wird).

Wenn Sie mehr an den Elementen als an den Zahlen an sich interessiert sind, können Sie für den niedrigen Preis von 261 253 Zeichen verwenden

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

das gibt Ausgabe wie

"Ac"
"AcCRa"
"AcHeBe"
...
Peter Taylor
quelle
Nehmen Sie den zusätzlichen Charakter heraus, "stört mich überhaupt nicht. Und natürlich kommt Peter Taylor herein und haut alle mit Golfskript um.
Rob
3

Ruby - 547 393

Neue Version, danke für die Vorschläge:

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
}

verwendet reguläre Ausdrücke. langsam und viel Raum für Verbesserungen, aber ich muss jetzt gehen :-)

Patrick Oscity
quelle
1
1) Sie können Speicherplatz sparen, indem Sie den Trick von Peter Taylor verwenden (wie in seinem ursprünglichen Code) : e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) Variable Regex wird niemals verwendet. 3) Lesen Sie die Wörter aus der Standardeingabe : $<.each{|w|.... Mit dieser Änderung wurde der Code auf 410 Zeichen reduziert.
Manatwork
Ich denke, dass Sie den gleichen platzsparenden Ansatz auch für unnötige Elemente anwenden können, auf Kosten des Hinzufügens von zwei Zeichen zur regulären Regex. Verwenden Sie Leerzeichen, wenn Sie keine Zeilenumbrüche mögen. Ich verwende hauptsächlich Zeilenumbrüche, damit Sie nicht scrollen müssen, um die Hauptschleife anzuzeigen.
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()

Irgendwo gibt es sicher Raum für Verbesserungen. Es ist auch erwähnenswert, dass die zweite Einrückungsstufe das Tabulatorzeichen verwendet.

Es dauert etwas mehr als 5 Sekunden (auf meinem Computer), um das gesamte Wörterbuch zu durchlaufen und eine Ausgabe wie folgt zu erstellen:

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

Durch Hinzufügen weiterer 18 Zeichen erhalten Sie eine Ausgabe mit der richtigen Groß- und Kleinschreibung:

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

Sie können auch einzelne Wörter überprüfen:

>>> m("beer")
('beer', [4, 68])
grc
quelle
Können Sie diejenige hinzufügen, die die richtige Großschreibung ausgibt? Ich finde das ziemlich ordentlich und ich bin ziemlich neu in Python.
Rob
0

Python - 1328 (975 + 285 Zeichen Code + 68 Wörterbuchcode)

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ür den Wörterbuchteil:

f=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()
beary605
quelle
Es ist wirklich kürzer, eine explizite Hash-Initialisierung zu verwenden, als eine explizite Array-Initialisierung zu verwenden und sie in einen Hash-Index umzuwandeln.
Peter Taylor
Ich habe gerade ein Wörterbuch verwendet, um die Verwendung zu vereinfachen. Eine Reihe von Tupeln zu haben, wäre etwas kostspieliger. Obwohl es eine gute Idee wäre, die Elemente zu bestellen ...
beary605
0

C, 775 771 Zeichen

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

Eingabe : Wort pro Zeile, muss klein geschrieben sein. usr/share/dict/wordsist gut.
Ausgabe : Wort und Zahlen, zB:acceptances,89,58,15,73,7,6,99

Logik :
c(w,o,l)Überprüft das Wort w, beginnend mit Element l.
Die bidirektionale Rekursion wird verwendet. Wenn das erste Element mit dem Kopf der Elementliste übereinstimmt, überprüfen Sie den Rest von wmit der vollständigen Elementliste . Wenn diese Übereinstimmung fehlschlägt, überprüfen Sie das Wort am Ende der Liste.
Der Puffer osammelt die Elementnummern entlang des erfolgreichen Pfades. Nach einer Übereinstimmung enthält es die Liste der Zahlen und wird gedruckt.

Probleme :
Die Liste ist nicht effizient codiert - zu viel "und ,". Aber auf diese Weise ist sie einfach zu verwenden. Ich bin sicher, dass sie ohne zu hohe Codekosten erheblich verbessert werden kann.

ugoren
quelle