[Br] Eaking Code Golf [Ba] d

20

Рассмотрим следующую строку:

Tin Snips

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

[Ti][N] [Sn][I][P][S]

Конечно, мы могли бы написать это так:

T[In] [S][Ni][P][S]

Правила переписывания ввода следующие:

  1. Случай ввода не имеет значения с точки зрения соответствия атомных символов.
  2. Если элемент используется в атомарном символе, его регистр должен измениться, чтобы символ был правильным. Пример: hстанет [H].
  3. Все символы элементов заключены в квадратные скобки ASCII [и ].
  4. Пробелы сохраняются: Big egoнельзя объединить «g» и «e» в [Ge].
  5. Не все входные символы нужно объединять в атомарный символ: если входной символ не помещается в символ, он передается как есть (регистр не имеет значения).
  6. Если символ может быть сделан, он должен быть сделан. Другими словами, Tinв приведенном выше примере не разрешается выводить данные, поскольку в этом слове можно создать хотя бы один символ. Единственный раз, когда символ может быть пропущен через неиспользованный, это когда он не может быть использован для создания атомарного символа.
  7. Для целей этой задачи, все элементы от водорода (1) до Oganesson (118) являются действительными. Никакие высшие элементы не действительны.
  8. Некоторые из высших элементов имеют неоднозначные имена и символы: для целей этого испытания должна использоваться версия из Википедии . Для удобства допустимые атомные символы находятся здесь: 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, Nh, Fl, Mc, Lv, Ts, Og.

Напишите программу или функцию, которая генерирует все возможные выходы из одного предоставленного ввода. И вход, и выход могут быть в любой форме по вашему выбору. Это может быть строка, массив символов или какая-то другая структура данных: все, что удобно и четко представляет ввод и вывод. И вход, и выход могут быть переданы в / из вашего кода, однако вы выбираете: стандартный ввод / вывод, аргумент / возврат функции или что-то еще.

  • Входные данные должны быть строкой (см. Предыдущий абзац) положительной длины, содержащей только символы ASCII произвольного регистра и 0x20символ пробела ( ).
  • Ваш код должен генерировать все выходные строки, которые могут быть созданы с использованием приведенных выше правил ввода.
  • Порядок вывода определяется реализацией. Единственное требование - все выходные строки присутствуют.
  • Если представлена ​​допустимая входная строка, которая не содержит атомарных символов, просто выведите входную строку.
  • Если она представлена ​​входной строкой, которая недопустима в соответствии с приведенными выше правилами (ноль, ноль символов, содержит недопустимые символы и т. Д.), Ваша программа может делать что угодно (сбой, пустой вывод и т. Д.)
  • Вывод нечувствителен к регистру, кроме атомарных символов, которые должны соответствовать периодической таблице.
  • Стандартные лазейки не допускаются.

Тестовые случаи:

Tin Snips
[Ti][N] [Sn][I][P][S]
[Ti][N] [S][Ni][P][S]
[Ti][N] [S][N][I][P][S]
T[In] [Sn][I][P][S]
T[In] [S][Ni][P][S]
T[In] [S][N][I][P][S]
T[I][N] ...

Quack
Q[U][Ac][K]
Q[U]a[C][K]

hehe
[H]e[H]e
[H]e[He]
[He][H]e
[He][He]

Stack Exchange
[S][Ta][C][K] Ex[C][H]a[N][Ge]
[S]t[Ac][K] Ex[C][H]a[N][Ge]

Это код гольф, так что позвольте мне увидеть ваш самый короткий код!

Джонатан Аллан
источник
1
Согласно комментарию @Rassars, Tin будет T[I][N]не [T][I][N]потому, что T не является элементом. Мой вопрос (и, возможно, вопрос Расара) таков: должны ли мы давать только 1. Только результаты, в которых сделано максимальное количество замен элементов? 2. Только минимальное количество отходов? (HeHe с водородом указывает, что ответ на этот вопрос - нет) 3. Все выходы, где совпадения полностью исчерпаны? (в этом случае T[I][N]так же, как и T[In]было бы действительным.) Я думаю, что правильная интерпретация - 3.
Уровень River St
1
Я думаю, что это дуплекс
Digital Trauma
1
Так что есть две возможности для кряка: Q[U][Ac][K]и Q[U]a[C][K]. Право?
RootTwo
1
Все случаи проверены.
CalculatorFeline
1
@ Challenger5 «Ваш код должен генерировать все выходные строки, которые могут быть созданы с использованием указанных выше правил ввода»
Джонатан Аллан

Ответы:

5

Python 3, 289 263 байта

Нашел более полную библиотеку на Pypi: mendeleev

from mendeleev import*
Z={element(i).symbol for i in range(1,119)}
L,R='[]'
def f(h,r=''):t=h.title();return((Z&{t[0]}and f(h[1:],r+L+t[0]+R)or[])+(Z>{(t+L)[:2]}and f(h[2:],r+L+t[:2]+R)or[])+(not{(r[-1:]+t[0]).title(),t[0]}&Z and f(h[1:],r+h[0])or[]))if h else[r]

Старый ответ:

from elements import*
Z={e.symbol for e in ELEMENTS}|{*'Cn Ds Fl Lv Mc Nh Og Rg Ts'.split()}
L,R='[]'
def f(h,r=''):t=h.title();return((Z&{t[0]}and f(h[1:],r+L+t[0]+R)or[])+(Z>{(t+L)[:2]}and f(h[2:],r+L+t[:2]+R)or[])+(not{(r[-1:]+t[0]).title(),t[0]}&Z and f(h[1:],r+h[0])or[]))if h else[r]

Использует библиотеку elements.pyот http://www.lfd.uci.edu/~gohlke/code/elements.py.html . В нем отсутствуют элементы от 110 до 118, но это была самая современная библиотека, которую я мог найти. Стоимость 40 байтов, чтобы добавить недостающие элементы.

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

RootTwo
источник
1
Подожди, не mendeleevпользователь, не библиотека?
Мэтью Ро,
3

Желе ,  192  191 байт

-1 при использовании Ɗ(разработано быстро)

“¦UV2ḤF2ı½ṅḶḊ⁼5JI5MẇvẋẊẊ¬Ḥḳ'ƈ<ḷėƤ7*⁾ṾxMæS⁺`?^Ƭb¦ɗDß⁼pþɲOṃ⁽2Ė>,Ḣ(ḞŒƊOGƤ×⁺ṇṂ®ȤT0y°^Ẇ⁺:Þ]ṢṬ¶ịṪḂƇ ñAƬCṫ$wÆĿĖỴỴƇẓƊqḌ@;ẏ`ṃFƥḣ⁽²»ḟ⁶s2;“¤²R.ȯ7ŒL£ɦ»Œt
Œte¢
ŒṖµL€=1oÇ€ṂµÐfµṡ2;€ÇÐfÇ€€S€¬SµÐḟ⁾[]jŒtƊ¹Ç?€€

Попробуйте онлайн! - Слишком неэффективно, чтобы тестовый сценарий «Stack Exchange» не был выполнен в течение 60 секунд (его автономный запуск дает правильный результат в течение 2 минут).

Как?

Первая строка кода представляет собой нулевую ссылку для создания списка, содержащего все 118 элементов символов. Для этого он объединяет два списка, первый из которых содержит все списки символов длиной 2 (т. Е. Строки), второй - список символов и заголовок с результирующим списком. Сами два списка создаются, главным образом, поиском слов в словаре Jelly для создания отдельных строк.

Первое из этих сжатий:

“¦UV2ḤF2ı½ṅḶḊ⁼5JI5MẇvẋẊẊ¬Ḥḳ'ƈ<ḷėƤ7*⁾ṾxMæS⁺`?^Ƭb¦ɗDß⁼pþɲOṃ⁽2Ė>,Ḣ(ḞŒƊOGƤ×⁺ṇṂ®ȤT0y°^Ẇ⁺:Þ]ṢṬ¶ịṪḂƇ ñAƬCṫ$wÆĿĖỴỴƇẓƊqḌ@;ẏ`ṃFƥḣ⁽²»

который дает

" biznagas sepmag ratbag catchflies paracmes mdse bharal ramcat monopteros irrepressibilities lunarnauts geniculate hopbinds rutabaga potlache broghs bergamas crossbirth purblind xebecs nonhardy classism fleurets moneybag scarce corf Mg Sr Zr CD HG CF FM Lr SG TM Gd Bk Fr Rh Fe Sn lv cndbmnnbkrmtpdnp"

Где все, кроме последней записи (разделенной пробелами), являются записями в словаре Jelly. Пробелы отфильтровываются ḟ⁶, а затем результат разбивается на две части:

["bi","zn","ag","as","se","pm","ag","ra","tb","ag","ca","tc","hf","li","es","pa","ra","cm","es","md","se","bh","ar","al","ra","mc","at","mo","no","pt","er","os","ir","re","pr","es","si","bi","li","ti","es","lu","na","rn","au","ts","ge","ni","cu","la","te","ho","pb","in","ds","ru","ta","ba","ga","po","tl","ac","he","br","og","hs","be","rg","am","as","cr","os","sb","ir","th","pu","rb","li","nd","xe","be","cs","no","nh","ar","dy","cl","as","si","sm","fl","eu","re","ts","mo","ne","yb","ag","sc","ar","ce","co","rf","Mg","Sr","Zr","CD","HG","CF","FM","Lr","SG","TM","Gd","Bk","Fr","Rh","Fe","Sn","lv","cn","db","mn","nb","kr","mt","pd","np"]

Секунда,

“¤²R.ȯ7ŒL£ɦ»

формируется из конкатенации слов «зяблик», «паб», «небо» и «клятва» (без пробелов) и, как таковой, представляет собой список символов:

['f','i','n','c','h','p','u','b','s','k','y','v','o','w']

Два списка объединяются, ;и каждая запись имеет титр, используя Œt:

["Bi","Zn","Ag","As","Se","Pm","Ag","Ra","Tb","Ag","Ca","Tc","Hf","Li","Es","Pa","Ra","Cm","Es","Md","Se","Bh","Ar","Al","Ra","Mc","At","Mo","No","Pt","Er","Os","Ir","Re","Pr","Es","Si","Bi","Li","Ti","Es","Lu","Na","Rn","Au","Ts","Ge","Ni","Cu","La","Te","Ho","Pb","In","Ds","Ru","Ta","Ba","Ga","Po","Tl","Ac","He","Br","Og","Hs","Be","Rg","Am","As","Cr","Os","Sb","Ir","Th","Pu","Rb","Li","Nd","Xe","Be","Cs","No","Nh","Ar","Dy","Cl","As","Si","Sm","Fl","Eu","Re","Ts","Mo","Ne","Yb","Ag","Sc","Ar","Ce","Co","Rf","Mg","Sr","Zr","Cd","Hg","Cf","Fm","Lr","Sg","Tm","Gd","Bk","Fr","Rh","Fe","Sn","Lv","Cn","Db","Mn","Nb","Kr","Mt","Pd","Np","F","I","N","C","H","P","U","B","S","K","Y","V","O","W"]

Список, содержащий все 118 элементов по мере необходимости (есть дубликаты, но это нормально).

Вторая строка кода - это монадическая ссылка (вспомогательная функция, предназначенная для получения одного ввода), которая возвращает 1, если вход, с титровальным регистром, существует в списке, созданном выше, и 0 в противном случае.

Третья строка кода - это основная ссылка, монадическая функция, которая принимает строку и возвращает требуемый список списков символов (т.е. строк):

ŒṖµL€=1oÇ€ṂµÐfµṡ2;€ÇÐfÇ€€S€¬SµÐḟ⁾[]jŒtƊ¹Ç?€€ - Main link: s
ŒṖ                                           - all partitions of s
  µ        µÐf                               - filter keep:
   L€=1                                      -     length €ach equals (vectorises) 1
       o                                     -     or
        ǀ                                   -     last link as a monad (is an element when title-cased)
          Ṃ                                  -     minimum 
                                             - (i.e. all partitions that are all single characters OR are strings that when title-cased are elements)
              µ              µÐḟ             - filter discard:
               ṡ2                            -     slices of length 2
                 ;€                          -     concatenate €ach
                    Ðf                       -     filter keep:
                   Ç                         -         last link as a monad (is an element when title-cased)
                      Ç€€                    -     last link as a monad for €ach for €ach
                         S€                  -     sum €ach
                           ¬                 -     logical not
                            S                -     sum
                                             - (i.e. discard any partitions that contain a run of two that joined together and title-cased ARE an element but separately NEITHER are)
                                         ?€€ - if then else for €ach (partition) for €ach (part):
                                        Ç    -     IF: last link as a monad (is an element when title-cased)
                                             -   THEN:
                                      Ɗ      -         last three links as a monad:
                                ⁾[]                      "[]"
                                   j         -           joined by:
                                    Œt       -           title case the part
                                             -   ELSE:
                                       ¹     -         the part itsef (¹ is the identity atom)
Джонатан Аллан
источник
1

C ++ 11, 944 928 байт

Вот кусок действительно ужасного кода, но он должен работать. Возможно, все еще можно сделать намного короче.

#import<iostream>
#import<set>
using namespace std;int r,i;set<string>O;S(string&s){s[0]-=s[0]>90?32:0;if(s[1])s[1]+=s[1]<91?32:0;char*l="HHeLiBeBCNOFNeNaMgAlSiPSClArKCaScTiVCrMnFeCoNiCuZnGaGeAsSeBrKrRbSrYZrNbMoTcRuRhPdAgCdInSnSbTeIXeCsBaLaCePrNdPmSmEuGdTbDyHoErTmYbLuHfTaWReOsIrPtAuHgTlPbBiPoAtRnFrRaAcThPaUNpPuAmCmBkCfEsFmMdNoLrRfDbSgBhHsMtDsRgCnNhFlMcLvTsOg";for(r=0;*l++;)if(*l>90){if(*(l++-1)==s[0]&&*(l-1)==s[1])r=1;}else if(*(l-1)==s[0]&&!s[1])r=1;}P(set<string>*V,string s,string o,int b,int l=0,int m=0){if(!s[b])O.insert(o);else if(l)P(V,s,o,b+1);else if(V[b].size()==0)P(V,s,o+s[b],b+1);else for(auto t:V[b]){P(V,s,o+"["+t+"]",b+1,t.length()-1);if(t.length()>1&&V[b].size()==1&&V[b+1].size()>0&&!m)P(V,s,o+s[b],b+1,0,1);}}F(string s){set<string>V[s.length()];for(i=0;s[i++];){string t="";t+=s[i-1];S(t);if(r)V[i-1].insert(t);t+=s[i];S(t);if(r&&s[i])V[i-1].insert(t);}P(V,s,"",0);for(auto o:O)cout<<o<<"\n";O.clear();}

Звоните с:

int main()
{
    F("Tin Snips");cout << "\n";
    F("Quack");cout << "\n";
    F("hehe");cout << "\n";
    F("Stack Exchange");
}
Steadybox
источник