Golf un graphique de solubilité

12

Compte tenu du nom d'un cation et d'un anion, sortie "S" (soluble) ou "I" (insoluble). Le tableau que nous utiliserons provient de wikipedia: https://en.wikipedia.org/wiki/Solubility_chart . Il est copié à la fin de la question pour référence future.

Entrée : Le cation, suivi de l'anion, séparé par un espace. Le cation sera l'un des suivants:

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

et l'anion sera l'un des suivants:

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

Chacun aura sa première lettre en majuscule.

Exemple d'entrée: Sodium Chloride

Sortie : une valeur véridique, ou S, si elle est soluble, falsey ou Iautre. Si la page wikipedia répertorie autre chose (par exemple, légèrement soluble, ou réagit avec l'eau) ou si l'entrée n'est pas sous la forme "cation anion", votre programme peut faire n'importe quoi (comportement indéfini), donc il peut afficher "S", " Je ', ou autre chose.

Table:

?,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

Les lignes sont des cations dans l'ordre indiqué ci-dessus et les colonnes sont des anions. Par exemple, puisque l'iodure de magnésium est soluble et que le magnésium était le 6e cation et l'iodure était le 4e anion, la 6e ligne et la 4e colonne ont le caractère «S». Le ?indique un comportement indéfini.

soktinpk
la source
1
J'aime cela parce que le comportement indéfini de ?s donne beaucoup de liberté dans les algorithmes que l'on peut utiliser.
Jo King
1
@FryAmTheEggman Malgré la kolmogorov-complexitybalise, le défi ne demande pas de sortir la table, mais la valeur correcte pour une paire donnée (cation, anion).
Arnauld
4
J'ai supprimé la balise kolmogorov-complexité et ajouté la balise decision-problem, car il ne s'agit pas de créer une sortie fixe (ou partiellement fixe), mais de déterminer si une certaine entrée répond à certains critères.
Stewie Griffin
Envisageriez-vous d'autoriser la sortie de 2 valeurs cohérentes distinctes plutôt que simplement truthy/ 'S'ou falsy/ 'I'?
Arnauld
Je suggérerais de supprimer la spécification «séparé par un espace» et de dire plutôt quelque chose du type «en plus des valeurs par défaut du site, les deux entrées peuvent être acceptées comme une seule entrée séparée par un caractère inutilisé cohérent (par exemple un espace) ". Deux entrées peuvent permettre plus de créativité au golf ici (par exemple, les fonctions au curry).
Jonathan Allan

Réponses:

8

JavaScript (Node.js) , 143 octets

Renvoie 1 pour soluble, 0 pour 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]

Essayez-le en ligne!

Comment?

Conversion de la chaîne d'entrée en un index de recherche

Nous construisons d'abord une clé en extrayant les 2e à 7e caractères de l'anion et en ajoutant les deux premiers caractères du cation:

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

Exemples:

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

Nous transformons cela en un index de recherche en l'analysant en base-35 et en appliquant un modulo 1325 suivi d'un modulo 508 (valeurs forcées par brute):

parseInt(key, 35) % 1325 % 508

Compression de la table de recherche

Parce qu'il y a beaucoup plus de paires solubles que de paires insolubles , nous remplissons toutes les entrées inutilisées de la recherche avec soluble .

En codant soluble avec 1 et insoluble avec 0 , notre table de correspondance se compose essentiellement de longues chaînes de 1 suivies d'un 0 :

11101110011111111111111111111101111111110111111111111111111111101111111111111101111111011111
11111111111011111111111111111111011111111111001111111111111111111111111111111111111111111111
11111111111111111111111111111111011111111111111111111111111011100111111110111111111111111111
11111111111111111111011111111110011111111111111111111111111111111111110110111111111111111011
11011111111111111111111111111101111110111111111111101101111111111111110110111111111111111111
11111011111101110111111111111110111110

Nous le compressons en stockant les longueurs des chaînes de 1 sous forme de caractères ASCII dans la plage [32-126] .

Arnauld
la source
8

Rubis -n , 96 92 75 70 69 65 octets

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

Essayez-le en ligne!

Je ne suis pas très bon pour générer des hachages et des tables de recherche, alors j'ai plutôt choisi de tirer parti de tous ces caractères génériques de point d'interrogation pour simplifier la structure logique de la table, puis d'appliquer de la magie Regex pure.

Mise à jour : modification de l'attribution de certains points d'interrogation et simplification de la logique de correspondance.

Mise à jour 2 : Juste 2 mois plus tard, j'ai trouvé une autre refonte de la table pour économiser quelques octets de plus.

Le tableau que nous allons produire ressemble à ceci:

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

Maintenant, les composés suivants peuvent être considérés comme solubles:

  • raNit ra te, Chlo ra te
  • [SPm]o So dium, Po tassium, Am mo nium
  • ^[^C]*F F luorure, mais pas C alcium ou C opper
  • h.*DLit h ium D ichromate

Parmi les composés restants, les suivants sont insolubles:

  • Le Le ad
  • [MAIZ]i.*y M agnesium, A luminium, I ron (et autres cations avec charge indiquée), Z inc composés avec bloc d'anions contenant y(H y droxide-Thioc y anate )
  • [OPDFbv] O xyde, P hosphate, D ichromate, F luoride, Voiture b onate, Sil v er
  • [tr]i.*SStron ti um et Ba ri um S ulfates

Tout le reste est soluble.

Kirill L.
la source
4

Python 2 , 166 161 131 131 octets

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

Essayez-le en ligne!

ovs
la source
Comment avez-vous trouvé autant de numéros de mod?
AlexRacer
1
@AlexRacer J'ai écrit un script Python qui essaie des entiers jusqu'à une certaine limite, de telle manière que le calcul du modulo ne donne pas les mêmes résultats pour une entrée soluble et insoluble. En exécutant ce script à plusieurs reprises. J'ai tous ces chiffres.
ovs
@AlexRacer J'ai utilisé ce script plusieurs fois avant ce défi, ex: codegolf.stackexchange.com/a/115706/64121 . Normalement, ces chaînes modulo sont un peu plus courtes.
ovs
3

Python 2 , 180 177 151 151 149 147 octets

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]

Essayez-le en ligne!

TFeld
la source
Ne peut 17*(b%91%61%17)%272pas l'être b%91%61%17*17%272?
Jonathan Frech
2

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

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.

Essayez-le en ligne!

Explication:

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
la source
1

Gelée ,  67 61 60 50 47  44 octets

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

Un lien monadique renvoyant une liste qui est vide pour Iet non vide pour S(dans Jelly les listes vides sont falsey tandis que celles non vides sont véridiques).

Essayez-le en ligne! (le pied de page”S”IÇ?estif LastLink(x) is Truthy then "S" else "I")

Ou voyez tous les cas formatés comme une grille correspondant à l'ordre de la grille dans l'OP.

Comment?

Après avoir créé des ensembles d'entrées qui doivent être Set Iet évalué ces entrées en base dix (Python:) dec=lambda s:sum(10**i*ord(c) for i, c in enumerate(s[::d]))et en utilisant quelques boucles de valeurs de modulation et en vérifiant l'ensemble, le hachage utilisé ici a été trouvé.

Les entiers clés insolubles sont créés dans le code en évaluant un entier codé en base 250, en le convertissant en base  25 ... 16  * ... 10 et en cumulant le résultat ...

* les réductions de base ont été obtenues en ajoutant des clés redondantes

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
la source