Golf eine Löslichkeitstabelle

12

Geben Sie unter der Bezeichnung eines Kations und Anions "S" (löslich) oder "I" (unlöslich) aus. Die Tabelle, die wir verwenden werden, stammt aus Wikipedia: https://en.wikipedia.org/wiki/Solubility_chart . Es wird zum späteren Nachschlagen am Ende der Frage kopiert.

Eingabe : Das Kation, gefolgt vom Anion, durch ein Leerzeichen getrennt. Das Kation wird eines der folgenden sein:

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

und das Anion wird eines der folgenden sein:

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

Bei jedem wird der erste Buchstabe groß geschrieben.

Beispiel Eingabe: Sodium Chloride

Ausgabe : Ein wahrer Wert oder S, wenn er löslich ist, falsch oder auf Iandere Weise. Wenn die Wikipedia-Seite etwas anderes auflistet (z. B. schwer löslich oder mit Wasser reagierend) oder wenn die Eingabe nicht in der Form "Kationenanion" vorliegt, kann Ihr Programm alles tun (undefiniertes Verhalten), sodass möglicherweise "S" ausgegeben wird. Ich 'oder irgendetwas anderes.

Tabelle:

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

Die Zeilen sind Kationen in der oben angegebenen Reihenfolge und die Spalten sind Anionen. Da beispielsweise Magnesiumiodid löslich ist und Magnesium das 6. Kation und Iodid das 4. Anion war, haben die 6. Reihe und 4. Spalte den Buchstaben "S". Das ?zeigt undefiniertes Verhalten an.

soktinpk
quelle
1
Ich mag das, weil das undefinierte Verhalten von ?s viel Freiheit in den Algorithmen gibt, die man verwenden kann.
Jo King
1
@FryAmTheEggman Trotz des kolmogorov-complexityTags fordert die Challenge nicht zur Ausgabe der Tabelle auf, sondern zum korrekten Wert für ein bestimmtes (Kation, Anion) Paar.
Arnauld
4
Ich habe das Kolmogorov-Komplexitäts-Tag entfernt und das Entscheidungsproblem-Tag hinzugefügt, da es nicht darum geht, eine feste (oder teilweise feste) Ausgabe zu erstellen, sondern zu bestimmen, ob eine bestimmte Eingabe einige Kriterien erfüllt.
Stewie Griffin
Würden Sie in Betracht ziehen, 2 unterschiedliche konsistente Werte anstatt nur truthy/ 'S'oder falsy/ auszugeben 'I'?
Arnauld
Ich würde vorschlagen, die Angabe "durch ein Leerzeichen getrennt" zu löschen und stattdessen zusätzlich zu den Site-Standardwerten etwas in der Art von "zu sagen. Die beiden Eingaben werden möglicherweise als eine einzige Eingabe akzeptiert, die durch ein konsistentes nicht verwendetes Zeichen (z. B. ein Leerzeichen) getrennt ist. ". Zwei Eingänge können hier mehr Kreativität beim Golfen ermöglichen (z. B. Curry-Funktionen).
Jonathan Allan

Antworten:

8

JavaScript (Node.js) , 143 Byte

Gibt 1 für löslich, 0 für unlöslich zurück.

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]

Probieren Sie es online!

Wie?

Konvertierung der Eingabezeichenfolge in einen Nachschlageindex

Wir erstellen zunächst einen Schlüssel, indem wir die 2. bis 7. Stelle des Anions extrahieren und die beiden ersten Stellen des Kations hinzufügen:

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

Beispiele:

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

Wir machen daraus einen Lookup-Index, indem wir ihn in base-35 analysieren und ein Modulo 1325 gefolgt von einem Modulo 508 (Brute-Forced-Werte) anwenden:

parseInt(key, 35) % 1325 % 508

Komprimierung der Nachschlagetabelle

Da es deutlich mehr lösliche Paare als unlösliche gibt, füllen wir alle nicht verwendeten Einträge in der Suche mit löslich .

Durch Kodierung von löslich mit 1 und unlöslich mit 0 besteht unsere Nachschlagetabelle im Wesentlichen aus langen Zeichenfolgen von 1 , gefolgt von einer 0 :

11101110011111111111111111111101111111110111111111111111111111101111111111111101111111011111
11111111111011111111111111111111011111111111001111111111111111111111111111111111111111111111
11111111111111111111111111111111011111111111111111111111111011100111111110111111111111111111
11111111111111111111011111111110011111111111111111111111111111111111110110111111111111111011
11011111111111111111111111111101111110111111111111101101111111111111110110111111111111111111
11111011111101110111111111111110111110

Wir komprimieren es durch die Längen der Saiten des Speicherns 1 ‚s als ASCII - Zeichen im Bereich [32-126] .

Arnauld
quelle
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

Probieren Sie es online!

Ich bin nicht sehr gut darin, Hashes und Nachschlagetabellen zu generieren, und habe mich stattdessen dafür entschieden, alle diese Fragezeichen-Platzhalter zu nutzen, um die logische Struktur der Tabelle zu vereinfachen und dann etwas pure Regex-Magie anzuwenden.

Update : Die Zuweisung einiger Fragezeichen wurde geändert und die Logik des Abgleichs weiter vereinfacht.

Update 2 : Nur 2 Monate später habe ich mir eine weitere Überarbeitung der Tabelle ausgedacht, um ein paar Bytes mehr zu sparen.

Der Tisch, den wir produzieren werden, sieht folgendermaßen aus:

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

Nun können die folgenden Verbindungen als löslich angesehen werden:

  • raNit ra te, Chlo ra te
  • [SPm]o So dium, Po tassium, Am mo nium
  • ^[^C]*F F luoride, aber nicht C alcium oder C opper
  • h.*DLit h ium D ichromate

Von den übrigen Verbindungen sind die folgenden unlöslich:

  • Le Le ad
  • [MAIZ]i.*y M agnesium, A luminium, I ron (und andere Kationen mit der angegebenen Gebühr), Z inc Verbindungen mit Block von Anionen y(H y droxide-ThioC y anate)
  • [OPDFbv] O Xide, P hosphate, D ichromate, F luoride, Car b Onate, Sil v ER
  • [tr]i.*SStron ti um und Ba ri um S ulfates

Alles andere ist löslich.

Kirill L.
quelle
4

Python 2 , 166 161 131 Bytes

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

Probieren Sie es online!

ovs
quelle
Wie hast du so viele Mod-Nummern gefunden?
AlexRacer
1
@AlexRacer Ich habe ein Python-Skript geschrieben, das Ganzzahlen bis zu einem bestimmten Grenzwert ausprobiert, sodass die Berechnung des Modulos für lösliche und unlösliche Eingaben nicht die gleichen Ergebnisse liefert. Indem Sie dieses Skript wiederholt ausführen. Ich habe all diese Zahlen.
OVS
@AlexRacer Ich habe dieses Skript viele Male vor dieser Herausforderung verwendet, z . B . : codegolf.stackexchange.com/a/115706/64121 . Normalerweise sind diese Moduloketten etwas kürzer.
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]

Probieren Sie es online!

TFeld
quelle
Kann 17*(b%91%61%17)%272nicht sein 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.

Probieren Sie es online!

Erläuterung:

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
quelle
1

Jelly ,  67 61 60 50 47  44 Bytes

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

Ein monadischer Link, der eine Liste zurückgibt, für die leer Iund für die nicht leer ist S(in Jelly sind leere Listen falsch, während nicht leere wahr sind).

Probieren Sie es online! Fußzeile”S”IÇ?istif LastLink(x) is Truthy then "S" else "I" )

Oder sehen Sie alle Fälle als Raster formatiert mit der Reihenfolge des Gitters im OP übereinstimmt.

Wie?

Nach Sätze von Eingängen zu schaffen , die sein müssen Sund Iund Auswertung dieser Eingänge als Basis zehn (Python: dec=lambda s:sum(10**i*ord(c) for i, c in enumerate(s[::d]))) und mit ein paar Schleifen von Modulo-ing Werte und Satz hier die Überprüfung der verwendeten Hash wurde gefunden.

Die unlöslichen Ganzzahlen werden im Code erzeugt, indem eine für die Basis 250 codierte Ganzzahl ausgewertet und in die Basis  25 ... 16  konvertiert wird * ... 10 und das Ergebnis kumuliert wird ...

* Die Basisreduzierungen wurden durch Hinzufügen einiger redundanter Schlüssel erreicht

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
quelle