Codeium Golfide

28

Dans ce défi, votre tâche consiste à prendre un anion et un cation et à produire la formule chimique du composé. L'entrée suit ces règles:

  • Prendre en 2 chaînes (dans un ordre quelconque) représentant l'anion et cation, par exemple F, NH_4ou Al.
  • Pour prendre en charge chaque ion, vous pouvez soit l'avoir dans le cadre de la chaîne séparée par un caret (par exemple F^-1) ou prendre des arguments numériques supplémentaires.
    • Remarque: Tant que votre type d'entrée numérique est signé, la charge de l'anion sera transmise sous forme de nombre négatif.
  • Les symboles seront toujours réels et les charges précises.

La sortie doit suivre ces règles:

  • Utilisation _pour les indices: Fe 2 O 3 serait Fe_2O_3.
  • Cation d'abord: NaCl, pas ClNa.
  • Molécule neutre: Li 2 O, pas LiO ou LiO - .
  • Coefficients les plus bas possibles: Fe 2 O 3 , pas Fe 4 O 6 .
  • Aucun indice: NaCl, pas Na 1 Cl 1 .
  • Pas de décalage: NH 4 OH, pas NH 5 O.
  • Parenthèses conditionnelles:
    • N'utilisez pas de parenthèses sur un ion à un seul atome: MgCl 2 , pas Mg (Cl) 2 .
    • N'utilisez pas de parenthèses s'il n'y a qu'un seul des ions par molécule: KClO 3 , pas K (ClO 3 ).
    • UTILISER des parenthèses s'il y a deux ou plus d'un ion polyatomique: être 3 (PO 4 ) 2 , pas être 3 PO 4 2 ou être 3 P 2 O 8 .

Voici quelques exemples d'entrées et de sorties supplémentaires:

Input               Output
Fe^+3, O^-2         Fe_2O_3
Fe^+2, O^-2         FeO
H^+1, SO_4^-2       H_2SO_4
Al^+3, SO_4^-2      Al_2(SO_4)_3
NH_4^+1, SO_4^-2    (NH_4)_2SO_4
Hg_2^+2, PO_4^-3    (Hg_2)_3(PO_4)_2
NH_4^+1, OH^-1      NH_4OH
Hg_2^+2, O_2^-2     Hg_2O_2

Puisqu'il s'agit de , la réponse la plus courte en octets l'emporte.

Nissa
la source
3
Cas de test recommandé: Fe^+2, OH^-1: Fe(OH)_2pour un ion polyatomique avec 1 de chaque élément ( OH^-1).
pizzapants184
1
@ Adám second ion est chargé: NO_3^-1. Un autre cas de test devrait également être le premier couplé avec un ^-2, donc cela ferait l'affaire (C(NH_2)_3)_2.... Ou un cas où l'ion dont vous avez besoin plus d'une fois commence par un support.
Heimdall
1
@ Adám Fe_4(Fe(CN)_6)_3pour le bleu de Prusse.
Colera Su
3
C'est peut-être le titre de défi le plus drôle que j'ai vu sur ce site jusqu'à présent, et cela en dit long pour une question ppcg. Merci pour le bon rire
osuka_
1
@osuka_ Avez-vous vu "quel est le moyen le plus rapide de tuer ma famille" sur Arqade? Ou mon autre défi PPCG, "confirmer les Illuminati"?
Nissa

Réponses:

4

APL (Dyalog) , 60 59 61 octets

+2 car les charges doivent être données signées.

Fonction d'infixation anonyme. Prend la liste des ions (anion, cation) comme argument de gauche et la liste des charges correspondantes comme argument de droite.

{∊(⍺{⍵∧1<≢⍺∩⎕D,⎕A:1')(',⍺⋄⍺}¨m),¨(ms1)/¨'_',∘⍕¨s←⍵÷⍨∧/⍵}∘|

Essayez-le en ligne!

{}∘| Fonction où est l'argument gauche et la magnitude de l'argument droit:

∧/⍵ LCM des charges

⍵÷⍨ diviser les frais par celui

s← stocker dans s(pour les scripts)

'_',∘⍕¨ formater (stringify) et ajouter une barre inférieure à chaque

()/ Reproduisez chaque lettre de chacune avec la valeur correspondante de:

  s≠1 Est sdifférent de 1? (donne 1 ou 0)

  m← stocker dans m(pour m ultiple)

(),¨ Ajouter respectivement à ceux-ci:

  ⍺{}¨m Pour chacun, appelez cette fonction avec des ions et mcomme arguments:

   ⎕D,⎕AD igits suivie par les majuscules A lphabet

   ⍺∩ intersection d'ions et que

    compter le nombre de caractères dans ce

   1< Est-ce un de moins que ça? (c.-à-d. avons-nous un ion multi-éléments?)

   ⍵∧ et avons-nous besoin de multiples de cet ion?

   : si oui, alors:

    ')(',⍺ ajouter la chaîne à l'ion

    1⌽ faire pivoter cycliquement un pas vers la gauche (place )à droite)

    autre

     retourner l'ion non modifié

ϵ nlist (aplatir)

Adam
la source
6

C, 208 205 175 169 169 octets

argv[1]: cation
argv[2]: anion Les
charges d'ions sont prises sur stdin.

#define z(b)for(i=*++v;*++i>95;);printf(b>1?*i?"(%s)_%d":"%s_%d":"%s",*v,b);
main(c,v,d,e,g,h,i)char**v,*i;{scanf("%d%d",&c,&d);for(e=c,h=-d;g=h;e=g)h=e%g;z(-d/e)z(c/e)}
Colera Su
la source
OP a précisé que les ions peuvent être donnés dans n'importe quel ordre.
Heimdall
6

Rétine , 86 80 octets

Merci à Neil d'avoir économisé 6 octets.

^
(
\^.+
)_$&$*
(1+)(\1|¶.+)+_(\1)+$
$#3$2_$#2
_1$

m)T`()``.+\)$|\(.[a-z]?\)
¶

Essayez-le en ligne!

L'entrée est séparée par un saut de ligne (la suite de tests utilise la séparation par virgule pour plus de commodité).

Explication

^
(

Nous commençons par ajouter un (à chaque molécule. Les ^correspondances commencent en ligne car m)vers la fin du programme définit le mode multiligne pour toutes les étapes précédentes.

\^.+
)_$&$*

Nous remplaçons la ^[-+]npartie par )_, suivie de ncopies de 1(c'est-à-dire que nous convertissons les frais en unaire, en laissant tomber les signes).

(1+)(\1|¶.+)+_(\1)+$
$#3$2_$#2

Cette étape fait trois choses: elle divise les deux charges par leur GCD, les reconvertit en décimales et les échange. Le GCD peut être trouvé assez facilement dans l'expression régulière, en faisant correspondre le plus long 1+qui nous permet de faire correspondre les deux charges en utilisant uniquement la référence arrière \1. Pour diviser par ceci, nous utilisons la fonction "nombre de captures" de Retina, qui nous indique combien de fois un groupe a été utilisé. Il en $#2est de même de la première charge divisée par le GCD et de $#3la deuxième charge divisée par le GCD (tous les deux en décimal).

_1$

Nous retirons les _1s des extrémités des deux parties.

m)T`()``.+\)$|\(.[a-z]?\)

Et nous supprimons les parenthèses des lignes qui se terminent par un )(c'est-à-dire celles qui en avaient un _1), ainsi que des lignes qui ne contiennent qu'un seul atome.

Enfin, nous concaténons les deux molécules en supprimant le saut de ligne.

Martin Ender
la source
3

Haskell , 101 97 octets

(s#t)n m|let x#i|j<-div(lcm n m)i=l$x:[l(x:['(':x++")"|l x<':'])++'_':show j|j>1]=s#n++t#m
l=last

Essayez-le en ligne! Exemple d'utilisation: Fe^+3, O^-2est pris comme ("Fe"#"O")3 2.

Laikoni
la source
2

Python 3 , 131 octets

lambda c,a,C,A:g(c,A/gcd(C,A))+g(a,C/gcd(C,A))
from math import*
g=lambda s,n:[s,[s,'(%s)'%s][sum(c<'`'for c in s)>1]+'_%d'%n][n>1]

Essayez-le en ligne!

Python 2 , 196 174 174 170 155 149 140 136 octets

lambda c,a,C,A:g(c,A/gcd(C,A))+g(a,C/gcd(C,A))
from fractions import*
g=lambda s,n:[s,[s,'(%s)'%s][sum(c<'`'for c in s)>1]+'_'+`n`][n>1]

Essayez-le en ligne!

TFeld
la source
Python 3 pour 131 octets
pizzapants184
2

Python 3 , 129 octets

lambda E,e,I,i,m=lambda e,i:(len(e)>2<=i)*"("+e+(len(e)>2<=i)*")"+"_%d"%i*(i>1):m(E,i/gcd(i,I))+m(e,I/gcd(i,I))
from math import*

Essayez-le en ligne!


Si nous devons gérer des charges négatives des anions, alors 153 octets:

lambda E,e,I,i,a=abs,m=lambda e,i:(len(e)>2<=i)*"("+e+(len(e)>2<=i)*")"+"_%d"%i*(i>1):m(E,a(i)/gcd(a(i),a(I)))+m(e,a(I)/gcd(a(i),a(I)))
from math import*

Essayez-le en ligne!

M. Xcoder
la source
2

RPL (HP48 S / SX), 294,5 octets

Oui, une soumission ridiculement grande, je ne sais pas à quel point elle sera compétitive ...

DIR
  M
    « S ROT S SWAP ABS 4 PICK ABS
      DUP2 WHILE DUP2 REPEAT MOD SWAP END DROP2
      SWAP OVER / 4 ROLL J 3 ROLLD / ROT J
      ROT 0 > IF THEN SWAP END + »
  S
    « DUP "^" POS DUP2 1 + OVER SIZE SUB OBJ🡢
      3 ROLLD 1 - 1 SWAP SUB »
  J
    IF OVER 1 ==
    THEN SWAP DROP
    ELSE DUP SIZE DUP2 DUP SUB "Z" > - 1 >
      IF
      THEN "(" SWAP + ")" +
      END
      "_" + SWAP +
    END
END

3 routines soigneusement emballées dans un répertoire. Mest le principal. Il attend 2 chaînes sur la pile au format ion et pousse une chaîne de molécules sur la pile.

Sdivise l'ion en charge sous forme de nombre et la formule de l'élément sous forme de chaîne. Par exemple, "PO_4^-3"serait pris de la pile -3et "PO_4"poussé sur la pile.

Jjoint le nombre d'ions à la formule et décide d'envelopper ou non la formule entre parenthèses. Le bit précédent ELSEconcerne 1 ion, laissant la chaîne telle quelle. Par exemple, si 1et se "PO_4"trouvent sur la pile, ils sont remplacés par "PO_4". 1et "H"donne "H".

Le reste concerne plusieurs ions; si c'est un seul atome, ce n'est pas entre parenthèses, sinon c'est le cas. Pour décider si c'est le cas, je vérifie la longueur de la chaîne et vérifie si le dernier caractère est >"Z". Les expressions booléennes renvoient 1 pour vrai et 0 pour faux. En soustrayant le résultat de cette comparaison de la longueur de la chaîne, j'obtiens 1 ou moins quand c'est un seul atome, sinon plus: la longueur 1 est un seul atome; la longueur 2 aura une lettre comme dernier caractère; pour un seul atome, il est en minuscules, ce >"Z"qui donne le résultat 1, sinon 2; longueur 3 ou plus signifie plus de 1 atome et avec 0 ou 1 soustrait de la longueur, le résultat sera au moins 2. Par exemple, 3et "PO_4"donne "(PO_4)_3". 3et "Al"donne "Al_3".

Mdivise d'abord chaque ion en utilisant S. Après la première ligne, le niveau 5 de la pile (donc l'objet le plus profondément enfoui) contient la charge du deuxième ion, la formule du deuxième ion de niveau 4, la formule du premier ion de niveau 3, la valeur absolue de niveau 2 de la charge du premier ion et la valeur absolue de niveau 1 de la charge du second ion à nouveau. Par exemple, si des ions donnés sur la pile sont "Al^+3", "SO_4^-2"nous obtenons -2, "SO_4", "Al", 3, 2.

La deuxième ligne calcule le pgcd des 2 charges (en laissant les charges intactes).

La troisième ligne divise chaque charge par le pgcd (pour calculer les multiples) et la joint à la formule de l'ion en utilisant J. Nous avons donc deux cordes chacune avec un ion donné sans charge (ou un multiple) et une charge de la seconde enfouie derrière eux. Par exemple, -2, "Al_2", "(SO_4)_3"(-2 est la charge de SO_4).

La quatrième ligne décharge la charge et si elle est positive, elle échange les deux chaînes (de sorte que le cation vient en premier) avant de les rejoindre. Ainsi , dans l' exemple ci - dessus, parce qu'il est négatif, ils sont rejoints dans l'ordre qu'ils sont: "Al_2(SO_4)_3".

Heimdall
la source
1

JavaScript, 145 octets

(c,a,p,n,g=(a,b)=>b?g(b,a%b):a)=>`(${c})_${n/-g(p,-n)}(${a})_${p/g(p,-n)}`.replace(/\(((\w+)\)(?=_1)|([A-Z][a-z]*)\))/g,"$2$3").replace(/_1/g,"")

Prend des arguments cest un cation, aest un anion, pest une charge positive, nest une charge négative.

ericw31415
la source