[Br]eaking Code Golf [Ba]d

2018-04-22 23:45:23

Consider the following string:

Tin Snips

This string contains several atomic symbols on the periodic table. We could rewrite this string to identify several of them:

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

Of course, we could also write it this way:

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

The rules for rewriting the input are as follows:

The case of the input does not matter in terms of matching atomic symbols.

If an element is used in an atomic symbol, its case must change so the symbol is correct. Ex: h would become [H].

All element symbols are encased in ASCII square brackets, [ and ].

Whitespace is preserved: Big ego cannot combine the "g" and "e" into [Ge].

Not all input characters need be combined into an atomic symbol: if an input character is not put into a symbol, it is passed through as-is (case does not matter).

If a symbol can be made, it must be made. In other words, it is not allowed to output Tin in the above example because it is possible to create at least one symbol in that word.

  • Python 3, 289 263 bytes

    Found a more complete library on 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]

    Old answer:

    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]

    Uses a library elements.py from http://www.lfd.uci.edu/~gohlke/code/elements.py.html. It is missing elements 110 to 118, but it was the most up to date library I could find. Cost 40 bytes to add the missing elements.

    The trickiest part was the logic for when a character can be passed through without being part of an element symbol.

    2018-04-22 23:54:31
  • Jelly,  192  191 bytes

    -1 by use of Ɗ (a since-developed quick)

    “¦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Ɗ¹Ç?€€

    Try it online! - Too inefficient for the "Stack Exchange" test case to complete within the 60s limit (running it offline gives the correct result within 2 minutes).

    How?

    The first line of code is a niladic link to create a list containing all 118 element symbols. To do so it concatenates two lists, the first containing all length 2 lists of characters (i.e. strings) the second a list of characters and title cases the resulting list. The two lists themselves are created mostly by looking up words in Jelly's dictionary to make single strings.

    The first of these compressions is:

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

    which yields

    " biznagas s

    2018-04-23 00:48:28
  • C++11, 944 928 bytes

    Here's a piece of truly terrible code, but it should work. Could still be made a lot shorter probably.

    #import

    #import

    using namespace std;int r,i;setO;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*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){setV[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].inser

    2018-04-23 01:38:12