Słowa z układu okresowego pierwiastków [zamknięte]


9

Kiedy byłem studentem pierwszego roku w liceum przyjmującym chemię, patrzyłem na układ okresowy pierwiastków i przeliterowałem brudne słowa wraz z liczbą pierwiastków (HeCK to 2619, 2-6-19).

Myślałem o tym pewnego dnia, gdy zobaczyłem niesamowitą koszulę z napisem BeEr (4-68)

Tak więc moim wyzwaniem dla codegolf jest najkrótszy program do wypisania listy słów, które możesz przeliterować za pomocą okresowej tablicy elementów ORAZ kodu liczbowego, który reprezentowałby to słowo.

/ usr / share / dict / words lub dowolny słownik, którego chcesz użyć do listy słów. Jeśli używasz „niestandardowej” listy słów, daj nam znać, co to jest!


„Numer”? Co z przypadkami, w których jest więcej niż jeden? Np. CO vs Co.
Peter Taylor,

3
Gdy czytam poniższe odpowiedzi, zauważyłem jedno miejsce, w którym każdy mógł wyciąć kilka znaków. Mogą usunąć Co, Si, Sc, Os, Hs, Po, Pb, Np, No, Yb, Cs i być może inne z ich listy elementów, ponieważ wszystkie można zbudować z innych elementów.
PhiNotPi

1
Nie Ytterbium, to mój ulubiony pierwiastek!
Rob

2
Aby wyjaśnić, elementy, które wymieniłem, zawsze można bezpiecznie usunąć. Na przykład Ytterbium można zawsze zastąpić itrem i borem, bez względu na język, w jakim znajduje się lista słów.
PhiNotPi

1
Nie jestem do końca pewien, czy całkowicie rozumiem to zadanie: czy znajdziemy pasujące słowa dla elementów, dopóki każdy element nie zostanie wydrukowany, czy też wydrukujemy każde słowo ze słownika, które można połączyć z tabeli elementów? Albo coś innego?
użytkownik nieznany

Odpowiedzi:


6

GolfScript ( 339 303 302 301 294 znaków)

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

Podziękowania dla PhiNotPi, którego obserwacja niepotrzebnych elementów pozwoliła mi zaoszczędzić 33 znaki.

To jest IMO o wiele bardziej idiomatyczny GolfScript niż poprzednie podejście rekurencyjne.

Zauważ, że zezwalam na słowa w słowniku na mieszanie małych i wielkich liter ( Ljest to funkcja tekstu pisanego małymi literami przy założeniu, że nie ma znaczenia, czy znaki inne niż alfa zostaną złamane), ale odrzucam dowolne z apostrofami lub akcentami.

Ponieważ jest to golf golfowy, zoptymalizowałem raczej długość kodu niż szybkość. To jest strasznie wolne. Oczekuje, że lista słów zostanie podana na stdin, a wyniki na stdout w formacie:

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

(małymi literami słowa wejściowe o małych i małych literach, dla których znajdzie dopasowanie).

Jeśli bardziej interesują Cię elementy niż liczby same w sobie, za niską cenę 261 253 znaków możesz użyć

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

co daje wynik jak

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

Wyjmij dodatkową postać, "wcale mi to nie przeszkadza. I oczywiście wchodzi Peter Taylor i zdmuchuje wszystkich w golfa.
Rob

3

Rubin - 547 393

Nowa wersja, dziękuję za sugestie:

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
}

używa wyrażeń regularnych. powolne i dużo miejsca na ulepszenia, ale muszę już iść :-)


1
1) Można oszczędzić przechowywania za pomocą sztuczki Peter Taylor (jak w jego oryginalnym kodzie) e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) Zmienne regex nigdy nie jest używane. 3) Przeczytaj rozmowę ze standardowego wejścia: $<.each{|w|.... Dzięki tym modyfikacjom kod został skrócony do 410 znaków.
manatwork

Myślę, że możesz zastosować to samo podejście oszczędzające miejsce również w przypadku niepotrzebnych elementów, kosztem dodania dwóch znaków do wyrażenia regularnego skanowania. Użyj spacji, jeśli nie lubisz nowych linii - używam głównie nowych linii, aby nie trzeba było przewijać, aby zobaczyć główną pętlę.
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()

Gdzieś tam jest miejsce na ulepszenia. Warto również zauważyć, że drugi poziom wcięcia używa znaku tabulacji.

Przejście całego słownika zajmuje nieco ponad 5 sekund (na moim komputerze), co daje następujące wyniki:

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

Dodając kolejne 18 znaków, możesz uzyskać dane wyjściowe z odpowiednią literą:

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

Możesz także sprawdzić poszczególne słowa:

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

Czy możesz dodać ten, który generuje odpowiednią wielkość liter? Myślę, że to całkiem fajne i jestem całkiem nowy w Pythonie.
Rob

0

Python - 1328 (975 + 285 znaków kodu + 68 kodów słownika)

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)

W części dotyczącej słownika:

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

Czy naprawdę krótsze jest użycie jawnej inicjalizacji skrótu niż użycie jawnej inicjalizacji tablicy i przekształcenie jej w indeks skrótu?
Peter Taylor,

Właśnie dla ułatwienia użyłem słownika. Posiadanie szeregu krotek byłoby nieco bardziej kosztowne dla postaci. Chociaż zamawianie elementów byłoby dobrym pomysłem ...
beary605

0

C, 775 771 znaków

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

Wprowadzanie : słowo w wierszu, musi być pisane małymi literami. usr/share/dict/wordsjest w porządku.
Wyjście : słowo i liczby, np .:acceptances,89,58,15,73,7,6,99

Logika :
c(w,o,l)sprawdza słowo w, zaczynając od elementu l.
Wykorzystywana jest dwukierunkowa rekurencja - jeśli pierwszy element pasuje do nagłówka listy elementów, sprawdź resztę wwzględem pełnej listy elementów. Jeśli to dopasowanie się nie powiedzie, sprawdź słowo na końcu listy.
Bufor ogromadzi numery elementów wzdłuż udanej ścieżki. Po dopasowaniu będzie zawierać listę liczb i zostanie wydrukowany.

Problemy :
lista nie jest zakodowana efektywnie - za dużo "i ,". Ale w ten sposób jest łatwa w użyciu. Jestem pewien, że można ją znacznie ulepszyć bez nadmiernych kosztów w kodzie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.