Golf una tabla de solubilidad


12

Dado el nombre de un catión y anión, salida "S" (soluble) o "I" (insoluble). La tabla que utilizaremos es de wikipedia: https://en.wikipedia.org/wiki/Solubility_chart . Se copia al final de la pregunta para referencia futura.

Entrada : El catión, seguido del anión, separado por un espacio. El catión será uno de los siguientes:

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

y el anión será uno de los siguientes:

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

Cada uno tendrá su primera letra en mayúscula.

Entrada de ejemplo: Sodium Chloride

Salida : un valor verdadero o S, si es soluble, falsey o de Iotra manera. Si la página de wikipedia enumera cualquier otra cosa (por ejemplo, ligeramente soluble o reacciona con agua) o si la entrada no tiene la forma de "anión catiónico", su programa puede hacer cualquier cosa (comportamiento indefinido), por lo que puede generar 'S', ' Yo 'o cualquier otra cosa.

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

Las filas son cationes en el orden mencionado anteriormente y las columnas son aniones. Por ejemplo, dado que el yoduro de magnesio es soluble, y el magnesio era el sexto catión y el yoduro era el 4to anión, la 6ta fila y la 4ta columna tienen el carácter 'S'. El ?indica comportamiento indefinido.


1
Me gusta esto porque el comportamiento indefinido de ?s da mucha libertad en los algoritmos que uno puede usar.
Jo King

1
@FryAmTheEggman A pesar de la kolmogorov-complexityetiqueta, el desafío no pide generar la tabla, sino el valor correcto para un par dado (catión, anión).
Arnauld

44
Eliminé la etiqueta de complejidad de kolmogorov y agregué la etiqueta de problema de decisión, ya que no se trata de crear una salida fija (o parcialmente fija), sino de determinar si una determinada entrada cumple con algunos criterios.
Stewie Griffin

¿Consideraría permitir la salida de 2 valores consistentes distintos en lugar de solo truthy/ 'S'o falsy/ 'I'?
Arnauld

Sugeriría descartar la especificación "separado por un espacio" y, en lugar de decir algo similar a "además de los valores predeterminados del sitio, las dos entradas pueden aceptarse como una sola entrada separada por un carácter coherente no utilizado (por ejemplo, un espacio) ". Dos entradas pueden permitir más creatividad en el golf aquí (por ejemplo, funciones curry).
Jonathan Allan

Respuestas:


8

JavaScript (Node.js) , 143 bytes

Devuelve 1 para soluble, 0 para insoluble.

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]

Pruébalo en línea!

¿Cómo?

Conversión de la cadena de entrada a un índice de búsqueda

Primero construimos una clave extrayendo los caracteres segundo a séptimo del anión y agregando los dos primeros caracteres del catión:

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

Ejemplos:

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

Convertimos esto en un índice de búsqueda analizándolo en base-35 y aplicando un módulo 1325 seguido de un módulo 508 (valores de fuerza bruta):

parseInt(key, 35) % 1325 % 508

Compresión de la tabla de búsqueda.

Debido a que hay significativamente más pares solubles que insolubles , llenamos todas las entradas no utilizadas en la búsqueda con soluble .

Al codificar soluble con 1 e insoluble con 0 , nuestra tabla de búsqueda consiste esencialmente en largas cadenas de 1 seguidas de un 0 :

11101110011111111111111111111101111111110111111111111111111111101111111111111101111111011111
11111111111011111111111111111111011111111111001111111111111111111111111111111111111111111111
11111111111111111111111111111111011111111111111111111111111011100111111110111111111111111111
11111111111111111111011111111110011111111111111111111111111111111111110110111111111111111011
11011111111111111111111111111101111110111111111111101101111111111111110110111111111111111111
11111011111101110111111111111110111110

Lo comprimimos almacenando las longitudes de las cadenas de 1 como caracteres ASCII en el rango [32-126] .


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

Pruébalo en línea!

No soy muy bueno para generar hashes y tablas de búsqueda, por lo que opté por aprovechar todos esos comodines de signo de interrogación para simplificar la estructura lógica de la tabla y luego aplicar un poco de magia Regex pura.

Actualización : Alteración de la asignación de algunos signos de interrogación y simplificó aún más la lógica de la correspondencia.

Actualización 2 : solo 2 meses después, se me ocurrió otra actualización de la tabla para guardar algunos bytes más.

La tabla que vamos a producir se ve así:

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

Ahora, los siguientes compuestos pueden considerarse solubles:

  • raNit ra te, Chlo ra te
  • [SPm]o Así dium, Po tassium, Am mo nium
  • ^[^C]*F F luoruro, pero no C alcium o C opper
  • h.*DLit h io D ichromate

De los compuestos restantes, los siguientes son insolubles:

  • Le Le ad
  • [MAIZ]i.*y M agnesio, A luminio, I ron (y otros cationes con carga indicada), Z inc compuestos con bloque de aniones que contiene y(H y droxido de tioc y anato)
  • [OPDFbv] O xide, P hosfate, D icromate, F luoride, Car b onate, Sil v er
  • [tr]i.*SStron ti um y Ba ri um S ulfates

Todo lo demás es soluble.


4

Python 2 , 166 161 131 bytes

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

Pruébalo en línea!


¿Cómo encontraste tantos números mod?
AlexRacer

1
@AlexRacer He escrito un script de Python que prueba números enteros hasta cierto límite, de tal manera que calcular el módulo no produce los mismos resultados para una entrada soluble e insoluble. Al ejecutar repetidamente este script. Tengo todos estos números.
ovs

@AlexRacer He usado ese script muchas veces antes de este desafío, por ejemplo: codegolf.stackexchange.com/a/115706/64121 . Normalmente estas cadenas de módulos son un poco más cortas.
ovs

3

Python 2 , 180 177 151 149 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]

Pruébalo en línea!


No 17*(b%91%61%17)%272puede ser b%91%61%17*17%272?
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.

Pruébalo en línea!

Explicación:

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.

1

Gelatina ,  67 61 60 50 47  44 bytes

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

Un enlace monádico que devuelve una lista que está vacía Iy no vacía S(en Jelly las listas vacías son falsas, mientras que las no vacías son verdaderas).

Pruébalo en línea! (pie de página”S”IÇ?esif LastLink(x) is Truthy then "S" else "I")

O vea todos los casos formateados como una cuadrícula que coincida con el orden de la cuadrícula en el OP.

¿Cómo?

Después de crear conjuntos de entradas que deben ser Sy Ievaluar estas entradas como base diez (Python:) dec=lambda s:sum(10**i*ord(c) for i, c in enumerate(s[::d]))y utilizando algunos bucles de valores de modulación y comprobación de conjuntos, se encontró el hash utilizado aquí.

Los enteros clave insolubles se crean en el código evaluando un entero codificado en base 250, convirtiéndolo en base  25 ... 16  * ... 10 y sumando acumulativamente el resultado ...

* las reducciones básicas se lograron agregando algunas claves 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])
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.