Слова из периодической таблицы элементов [закрыто]

9

Когда я был новичком в старших классах, изучая химию, я смотрел на периодическую таблицу элементов и излагал грязные слова с количеством элементов (HeCK было бы 2619, 2-6-19).

Я думал об этом на днях, когда увидел удивительную рубашку с надписью BeEr (4-68)

Так что моя задача Codegolf - самая короткая программа для вывода списка слов, которые вы можете записать с помощью периодической таблицы элементов И числового кода, который будет представлять это слово.

/ usr / share / dict / words или любой другой словарь, который вы хотите использовать для списка слов. Если вы используете «нестандартный» список слов, дайте нам знать, что это такое!

обкрадывать
источник
Числовой код? Как насчет случаев, когда их больше одного? Например, CO против Ко
Питер Тейлор
3
Читая ответы ниже, я заметил одно место, где каждый мог вырезать несколько символов. Они могут удалить Co, Si, Sc, Os, Hs, Po, Pb, Np, No, Yb, Cs и, возможно, другие из своего списка элементов, поскольку все они могут быть построены из других элементов.
PhiNotPi
1
Не Иттербий, это мой любимый элемент!
Роб
2
Просто чтобы уточнить, элементы, которые я перечислил, всегда можно безопасно удалить. Например, иттербий всегда можно заменить на иттрий и бор, независимо от того, на каком языке находится список слов.
PhiNotPi
1
Я не совсем уверен, полностью ли я понимаю задачу: найдем ли мы подходящие слова для элементов до тех пор, пока не будет напечатан каждый элемент, или мы напечатаем каждое слово из dict, которое можно объединить из таблицы элементов? Или что-то другое?
пользователь неизвестен

Ответы:

6

GolfScript ( 339 303 302 301 294 символа)

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

С благодарностью PhiNotPi, чьи наблюдения за ненужными элементами позволили мне сэкономить 33 символа.

Это IMO гораздо более идиоматичный GolfScript, чем предыдущий рекурсивный подход.

Обратите внимание, что я допускаю, чтобы слова в словаре были в смешанном регистре ( Lэто функция для текста в нижнем регистре при условии, что не имеет значения, если не-буквенные символы разбиты), но отвергаю любые с апострофами или ударениями.

Поскольку это кодовый гольф, я оптимизировал код по длине, а не по скорости. Это ужасно медленно. Ожидается, что список слов будет предоставлен на стандартный ввод и выводится на стандартный вывод в формате:

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

(Строчные все входные слова в смешанном регистре, для которых найдено совпадение).

Если вас больше интересуют элементы, чем числа как таковые, за низкую цену в 261 253 символа вы можете использовать

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

который дает вывод как

"Ac"
"AcCRa"
"AcHeBe"
...
Питер Тейлор
источник
Убери лишнего персонажа, "меня совсем не беспокоит. И, конечно же, приходит Питер Тейлор и уносит всех с ног на голову.
Роб
3

Рубин - 547 393

Новая версия, спасибо за предложения:

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
}

использует регулярные выражения медленно и много возможностей для улучшения, но я должен идти сейчас :-)

Патрик Осцити
источник
1
1) Вы можете сэкономить память, используя трюк Питера Тейлора (как в его исходном коде) e='HHeLiBe...LvUusUuo'.scan(/[A-Z][a-z]*/).map &:downcase. 2) Переменное регулярное выражение никогда не используется. 3) Прочитайте слова из стандартного ввода: $<.each{|w|.... С этой модификацией код был сокращен до 410 символов.
Манатворк
Я думаю, что вы можете применить тот же подход к экономии места и для ненужных элементов, за счет добавления двух символов в регулярное выражение сканирования. Используйте пробел, если вам не нравятся новые строки - я использую новые строки главным образом, чтобы не было необходимости прокручивать, чтобы увидеть основной цикл.
Питер Тейлор
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()

Там наверняка есть место для улучшения где-то там. Также стоит отметить, что на втором уровне отступа используется символ табуляции.

Для просмотра всего словаря требуется чуть более 5 секунд (на моем компьютере), выводя примерно так:

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

Добавив еще 18 символов, вы можете получить вывод с правильной прописной буквой:

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

Вы также можете проверить отдельные слова:

>>> m("beer")
('beer', [4, 68])
GRC
источник
Можете ли вы добавить тот, который выводит правильную капитализацию? Я думаю, что это довольно аккуратно, и я довольно плохо знаком с Python.
Роб
0

Python - 1328 (975 + 285 символов кода + 68 словарного кода)

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=open(input(),'r')
for i in f.readlines():print p(i[:-1])
f.close()
beary605
источник
Действительно короче использовать явную инициализацию хеша, чем использовать явную инициализацию массива и превратить его в хэш индекса?
Питер Тейлор
Я просто использовал словарь для простоты использования. Наличие массива кортежей будет немного дороже. Хотя упорядочение элементов было бы хорошей идеей ...
beary605
0

С 775 771 символ

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

Ввод : слово в строке, должно быть в нижнем регистре. usr/share/dict/wordsЭто хорошо.
Вывод : слово и цифры, например:acceptances,89,58,15,73,7,6,99

Логика :
c(w,o,l)проверяет слово w, начиная с элемента l.
Используется двусторонняя рекурсия - если первый элемент совпадает с заголовком списка элементов, сравните остаток wс полным списком элементов. Если это совпадение не удается, проверьте слово в конце списка.
Буфер oнакапливает номера элементов по успешному пути. После матча он будет содержать список номеров и будет напечатан.

Проблемы :
список не закодирован эффективно - слишком много "и ,". Но этот способ прост в использовании. Я уверен, что он может быть значительно улучшен без слишком больших затрат в коде.

ugoren
источник