Gráfico de golfe uma solubilidade

12

Dado o nome de um cátion e ânion, produza "S" (solúvel) ou "I" (insolúvel). A tabela que usaremos é da wikipedia: https://en.wikipedia.org/wiki/Solubility_chart . É copiado no final da pergunta para referência futura.

Entrada : O cátion, seguido pelo ânion, separado por um espaço. O cátion será um dos seguintes:

Lithium Sodium Potassium Ammonium Beryllium Magnesium Calcium 
Strontium Barium Zinc Iron(II) Copper(II) Aluminium Iron(III) Lead(II) Silver

e o ânion será um dos seguintes:

Fluoride Chloride Bromide Iodide Carbonate Chlorate Hydroxide Cyanide Cyanate 
Thiocyanate Nitrate Oxide Phosphate Sulfate Dichromate

Cada um terá sua primeira letra maiúscula.

Exemplo de entrada: Sodium Chloride

Saída : Um valor verdadeiro ou S, se for solúvel, falsey ou de Ioutra forma. Se a página da wikipedia listar qualquer outra coisa (por exemplo, ligeiramente solúvel ou reagir com água) ou se a entrada não estiver na forma "ânion cátion", seu programa poderá fazer qualquer coisa (comportamento indefinido) e, portanto, produzir 'S', ' Eu ', ou qualquer outra coisa.

Mesa:

?,S,S,S,?,S,S,S,?,S,S,?,I,S,S
S,S,S,S,S,S,S,S,S,S,S,?,S,S,S
S,S,S,S,S,S,S,S,S,S,S,?,S,S,S
S,S,S,S,S,S,S,S,?,S,S,?,S,S,S
S,S,S,?,?,?,?,?,?,?,S,?,?,S,?
?,S,S,S,I,S,I,?,?,?,S,I,I,S,I
I,S,S,S,I,S,?,S,?,?,S,?,I,?,I
?,S,S,S,I,S,S,?,?,?,S,?,?,I,?
?,S,S,S,I,S,S,S,?,?,S,?,?,I,?
?,S,S,S,I,S,I,I,?,?,S,I,I,S,I
S,S,S,S,I,S,I,?,?,?,S,I,I,S,I
?,S,S,?,I,S,I,?,?,I,S,I,I,S,I
S,S,S,?,?,S,I,?,?,?,S,I,I,S,I
?,S,S,?,?,S,I,?,?,?,S,I,I,?,I
?,?,?,I,I,S,I,?,?,?,S,I,I,I,?
S,I,I,I,I,S,?,I,I,?,S,?,I,?,I

As linhas são cátions na ordem listada acima e as colunas são ânions. Por exemplo, como o iodeto de magnésio é solúvel e o magnésio é o sexto cátion e o iodeto é o quarto ânion, a sexta linha e a quarta coluna têm o caractere 'S'. O ?indica comportamento indefinido.

soktinpk
fonte
1
Eu gosto disso porque o comportamento indefinido de ?s dá muita liberdade em quais algoritmos se pode usar.
Jo rei
1
@FryAmTheEggman Apesar da kolmogorov-complexitytag, o desafio não exige a saída da tabela, mas o valor correto para um determinado par (cátion, ânion).
Arnauld
4
Removai a tag kolmogorov-complexidade e adicionei a tag do problema de decisão, já que não se trata de criar uma saída fixa (ou parcialmente fixa), mas determinar se uma determinada entrada atende a alguns critérios.
Stewie Griffin
Você consideraria permitir a saída de 2 valores consistentes distintos em vez de apenas truthy/ 'S'ou falsy/ 'I'?
Arnauld
Eu sugiro que você solte a especificação "separados por um espaço" e, em vez disso, diga algo como "além dos padrões do site, as duas entradas podem ser aceitas como uma única entrada separada por um caractere não utilizado consistente (por exemplo, um espaço) " Duas entradas podem permitir mais criatividade no golfe aqui (por exemplo, funções com caril).
Jonathan Allan

Respostas:

8

JavaScript (Node.js) , 143 bytes

Retorna 1 para solúvel, 0 para insolúvel.

s=>Buffer(`## 5)6.'04+ n:# (F* E"/$;&-"/"7&#.%`).map(c=>S+='1'.repeat(c-32)+0,S='')|S[parseInt(s.split` `[1].slice(1,7)+s[0]+s[1],35)%1325%508]

Experimente online!

Quão?

Conversão da cadeia de entrada em um índice de pesquisa

Primeiro construímos uma chave extraindo o 2º ao 7º caracteres do ânion e adicionando os dois primeiros caracteres do cátion:

key = s.split` `[1].slice(1, 7) + s[0] + s[1]

Exemplos:

'Lithium Fluoride'  --> 'luoridLi'
'Sodium Fluoride'   --> 'luoridSo'
'Sodium Dichromate' --> 'ichromSo'
'Calcium Oxide'     --> 'xideCa'

Transformamos isso em um índice de pesquisa analisando-o na base-35 e aplicando um módulo 1325 seguido por um módulo 508 (valores de força bruta):

parseInt(key, 35) % 1325 % 508

Compactação da tabela de pesquisa

Como existem pares significativamente mais solúveis que os insolúveis , preenchemos todas as entradas não utilizadas na pesquisa com solúvel .

Ao codificar solúvel com 1 e insolúvel com 0 , nossa tabela de pesquisa consiste essencialmente em cadeias longas de 1 's seguidas por um 0 :

11101110011111111111111111111101111111110111111111111111111111101111111111111101111111011111
11111111111011111111111111111111011111111111001111111111111111111111111111111111111111111111
11111111111111111111111111111111011111111111111111111111111011100111111110111111111111111111
11111111111111111111011111111110011111111111111111111111111111111111110110111111111111111011
11011111111111111111111111111101111110111111111111101101111111111111110110111111111111111111
11111011111101110111111111111110111110

Nós o compactamos armazenando os comprimentos das seqüências de caracteres de 1 como caracteres ASCII no intervalo [32-126] .

Arnauld
fonte
8

Ruby -n , 96 92 75 70 69 65 bytes

p /ra|[SPm]o|^[^C]*F|h.*D/?1:/Le|[MAIZ].*y|[OPDFbv]|[tr]i.*S/?0:1

Experimente online!

Como não sou muito bom em gerar hashes e tabelas de pesquisa, optei por aproveitar todos esses curingas de ponto de interrogação para simplificar a estrutura lógica da tabela e, em seguida, aplicar alguma mágica pura do Regex.

Atualização : atribuição alterada de alguns pontos de interrogação e simplificou ainda mais a lógica da correspondência.

Atualização 2 : Apenas 2 meses depois, criei outra reformulação da tabela para economizar mais alguns bytes.

A tabela que vamos produzir tem a seguinte aparência:

Lithium    111101111110011
Sodium     111111111111111
Potassium  111111111111111
Ammonium   111111111111111
Beryllium  111101111110010
Magnesium  111101000010010
Calcium    011101111110010
Strontium  111101111110000
Barium     111101111110000
Zinc       111101000010010
Iron(II)   111101000010010
Copper(II) 011101000010010
Aluminium  111101000010010
Iron(III)  111101000010010
Lead(II)   100001000010000
Silver     100001000010000

Agora, os seguintes compostos podem ser considerados solúveis:

  • raNit ra te, Chlo ra te
  • [SPm]o Então dium, Po tassium, Am mo nium
  • ^[^C]*F F luoreto, mas não C alcium ou C opper
  • h.*DLit h io D ichromate

Dos compostos restantes, os seguintes são insolúveis:

  • Le Le ad
  • [MAIZ]i.*y H agnesium, Um Luminium, eu ron (e outros catiões com carga indicada), Z compostos inc com bloco de aniões contendo y(H y droxide-Thioc y anate)
  • [OPDFbv] O hidróxido O, P hosphate, D ichromate, F luoride, Car b onato, Sil v er
  • [tr]i.*SStron ti e Ba ri um S ulfates

Tudo o resto é solúvel.

Kirill L.
fonte
4

Python 2 , 166 161 131 bytes

lambda n:chr(hash(n)%1482%737%388%310%295%262%254)not in'gwQFCAkOExUWHJ0gJyicLLKviDK3PEDDxslKztFUV1ja4ukdbe7x9Xd5'.decode('base64')

Experimente online!

ovs
fonte
Como você encontrou tantos números de mod?
AlexRacer
1
@AlexRacer Eu escrevi um script Python que tenta números inteiros até um certo limite, de forma que o cálculo do módulo não produz os mesmos resultados para uma entrada solúvel e insolúvel. Executando repetidamente este script. Eu tenho todos esses números.
ovs 13/08/18
@AlexRacer Eu usei esse script várias vezes antes deste desafio, por exemplo: codegolf.stackexchange.com/a/115706/64121 . Normalmente essas cadeias de módulos são um pouco mais curtas.
ovs 13/08/18
3

Python 2 , 180 177 151 149 147 147 bytes

def f(s):a,b=s.split();return bin(int('7YNQYE3M7HE5OU3HHE71UMXBVRATPSZTSCV0O4WI84X5KTNE92TMLA',36))[(int(a[1:4],35)|int(b[2:6],35))%3419%529%277-6]

Experimente online!

TFeld
fonte
Não pode 17*(b%91%61%17)%272ser b%91%61%17*17%272?
11138 Jonathan Frech
2

Pascal (FPC) , 387 358 353 348 341 319 297 bytes

var s,t:string;j:word;c:array[0..14]of word=(5055,8191,8191,8191,93,63,4143,175,4271,63,127,31,95,3,67);begin read(s);t:=copy(s,pos(' ',s)+1,6);j:=pos(t[1..2],'OxCyCaPhThDiHyFlIoSuBrChChNi')div 2;if'a'=t[6]then j:=12;write(c[pos(s[1..2],'LiSoPoAmBeMaCaStBaZiIrCoAlLeSi')div 2]shr(13-j)mod 2>0)end.

Experimente online!

Explicação:

var a:string='LiSoPoAmBeMaCaStBaZiIrCoAlLeSi'; //string containing first 2 letters of cations (can also be const)
                                               //luckily, Iron(II) and Iron(III) are compatible, they can have the same outputs
    b:string='OxCyCaPhThDiHyFlIoSuBrChChNi'; //string containing first 2 letters of anions (can also be const)
                                             //the order is different from the Wikipedia chart;
                                             //Chloride and Chlorate are next to each other to find the right index easier
                                             //Cyanide and Cyanate are compatible - 1 column less
                                             //overall, they are ordered to minimize the numbers in c
    s,t:string;
    i,j:word;
    c:array[0..14]of word=(5055,8191,8191,8191,93,63,4143,175,4271,63,127,31,95,3,67);
      //One number for each cation; one bit for solubility of particular combination; the bit for input combination will be found using i and j
begin
  read(s); //put input into s
  t:=copy(s,pos(' ',s)+1,6); //find the 2nd word in s (characters after space), take first 6 letters and copy them into t (6th letter is needed later)
  i:=pos(s[1..2],a)div 2; //position of first 2 letters of cation in a
                          //divided by 2 to get index for c
                          //*in golfed code, expression for i is inserted directly into write function
  j:=pos(t[1..2],b)div 2; //position of first 2 letters of anion in b
                          //divided by 2 to get the particular bit of c[i]
  if(j=11)and(t[6]='a')then j:=j+1; //if the anion is Chlorate, j is wrong and needs to be increased (specifically to 12);
                                    //only Chlorate has 'a' as 6th character, j doesn't need to be checked, but it's here for easier understanding
  writeln((c[i]shr(13-j))mod 2>0); //take i-th element of c, shift it right to put the correct bit at last position,
                                   //extract that bit, check if greater than 0
end.
AlexRacer
fonte
1

Geléia ,  67 61 60 50 47  44 bytes

OḌ%⁽Ƭ%⁽£ṇ%⁽¡ẹ%249ḟ“ıA¬ɲḃẏCċtȯƁƤçȤċŒḲOƲ’D‘Ĥ

Um link monádico retornando uma lista vazia Ie não vazia S(no Jelly, as listas vazias são falsey e as não vazias são verdadeiras).

Experimente online! (rodapé”S”IÇ?éif LastLink(x) is Truthy then "S" else "I")

Ou veja todos os casos formatados como uma grade que corresponde à ordem da grade no OP.

Quão?

Depois de criar conjuntos de entradas que devem ser Se Iavaliar essas entradas como base dez (Python:) dec=lambda s:sum(10**i*ord(c) for i, c in enumerate(s[::d]))e usar alguns loops de valores modulares e verificar a configuração, o hash usado aqui foi encontrado.

Os números inteiros chave insolúveis são criados no código, avaliando um número inteiro codificado na base 250, convertendo-o em base  25 ... 16  * ... 10 e somando cumulativamente o resultado ...

* as reduções de base foram alcançadas adicionando algumas chaves redundantes

OḌ%⁽Ƭ%⁽£ṇ%⁽¡ẹ%249ḟ“...’D‘Ĥ - Main Link: list of characters   e.g. "Calcium Carbonate"
O                            - cast to a list of ordinals      [67,97,108,99,105,117,109,32,67,97,114,98,111,110,97,116,101]
 Ḍ                           - convert from base ten           778907829795030961
   ⁽Ƭ                       - base 250 literal = 4258
  %                          - modulo                          625
       ⁽£ṇ                   - base 250 literal = 1721
      %                      - modulo                          625
           ⁽¡ẹ               - base 250 literal = 1215
          %                  - modulo                          625
               249           - literal 249
              %              - modulo                          127
                           ¤ - nilad followed by link(s) as a nilad:
                   “...’     -   literal in base 250    = 382193517807860310905428231939605402667395154
                        D    -   convert to decimal     = [3,8,2,1,9,3,5,1,7,8,0,7,8,6,0,3,1,0,9,0,5,4,2,8,2,3,1,9,3,9,6,0,5,4,0,2,6,6,7,3,9,5,1,5,4]
                         ‘   -   increment (vectorises) = [4,9,3,2,10,4,6,2,8,9,1,8,9,7,1,4,2,1,10,1,6,5,3,9,3,4,2,10,4,10,7,1,6,5,1,3,7,7,8,4,10,6,2,6,5]
                          Ä  -   cumulative sum         = [4,13,16,18,28,32,38,40,48,57,58,66,75,82,83,87,89,90,100,101,107,112,115,124,127,131,133,143,147,157,164,165,171,176,177,180,187,194,202,206,216,222,224,230,235]
                             -     ...note the redundant keys are --->            48       66 75                                115                                                     187             216
                  ḟ          - filter discard (implicit wrap)  [] (if 127 was not in the list above this would've been [127])
Jonathan Allan
fonte