Codeium Golfide

28

En este desafío, su tarea es tomar un anión y un catión, y generar la fórmula química del compuesto. La entrada sigue estas reglas:

  • Tome en 2 cadenas (en cualquier orden) que representa el anión y catión, por ejemplo F, NH_4o Al.
  • Para asumir la carga de cada ion, puede tenerlo como parte de la cadena separada por un cursor (p F^-1. Ej. ) O tomar argumentos numéricos adicionales.
    • Nota: Mientras su tipo de entrada numérica esté firmado, la carga del anión se pasará como un número negativo.
  • Los símbolos siempre serán reales y los cargos serán precisos.

El resultado debe seguir estas reglas:

  • Uso _para subíndices: Fe 2 O 3 sería Fe_2O_3.
  • Cation primero: NaCl, no ClNa.
  • Molécula neutra: Li 2 O, no LiO o LiO - .
  • Coeficientes más bajos posibles: Fe 2 O 3 , no Fe 4 O 6 .
  • Sin subíndices: NaCl, no Na 1 Cl 1 .
  • Sin desplazamiento: NH 4 OH, no NH 5 O.
  • Paréntesis condicionales:
    • No use paréntesis en un ion de un solo átomo: MgCl 2 , no Mg (Cl) 2 .
    • No use paréntesis si solo hay uno de los iones por molécula: KClO 3 , no K (ClO 3 ).
    • SÍ use paréntesis si hay dos o más iones poliatómicos: Be 3 (PO 4 ) 2 , no Be 3 PO 4 2 o Be 3 P 2 O 8 .

Aquí hay algunas entradas y salidas de muestra adicionales:

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

Como se trata de , gana la respuesta más corta en bytes.

Nissa
fuente
3
Caso de prueba recomendado: Fe^+2, OH^-1: Fe(OH)_2para un ion poliatómico con 1 de cada elemento ( OH^-1).
pizzapants184
1
@ Adám segundo ion está cargado: NO_3^-1. También otro caso de prueba debería ser el primero emparejado con un ^-2, por lo que sería (C(NH_2)_3)_2.... O un caso donde el ion que se necesita más de una vez comienza con un soporte.
Heimdall el
1
@ Adám Fe_4(Fe(CN)_6)_3para el azul de Prusia.
Colera Su
3
Este podría ser el título de desafío más divertido que he visto en este sitio web hasta ahora, y eso dice mucho para una pregunta de ppcg. Gracias por la buena risa
osuka_
1
@osuka_ ¿Has visto "cuál es la forma más rápida de matar a mi familia" en Arqade? ¿O mi otro desafío PPCG, "confirmar los Illuminati"?
Nissa

Respuestas:

4

APL (Dyalog) , 60 59 61 bytes

+2 ya que los cargos deben entregarse firmados.

Función de infijo anónimo. Toma la lista de iones (anión, catión) como argumento izquierdo y la lista de cargas correspondientes como argumento derecho.

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

Pruébalo en línea!

{}∘| Funcionan donde está el argumento izquierdo y es la magnitud del argumento correcto:

∧/⍵ LCM de los cargos

⍵÷⍨ dividir los cargos por eso

s← almacenar en s(para s ubscripts)

'_',∘⍕¨ formatear (stringify) y anteponer barra inferior a cada

()/ Replica cada letra de cada una con el valor correspondiente de:

  s≠1 Es sdiferente de 1? (da 1 o 0)

  m← almacenar en m(por m ultiple)

(),¨ Anteponer lo siguiente respectivamente a aquellos:

  ⍺{... }¨m para cada uno, llame a esta función con iones y mcomo argumentos:

   ⎕D,⎕AD igits seguida por letras mayúsculas A lphabet

   ⍺∩ intersección de iones y que

    cuenta el número de caracteres en ese

   1< ¿Es uno menos que eso? (es decir, ¿tenemos un ion multielemento?)

   ⍵∧ y necesitamos múltiplos de ese ion?

   : si es así, entonces:

    ')(',⍺ anteponer la cuerda al ion

    1⌽ gire cíclicamente un paso hacia la izquierda (se coloca )a la derecha)

    más

     devolver el ion sin modificar

ϵ nlist (aplanar)

Adán
fuente
6

C, 208 205 175 169 bytes

argv[1]: catión
argv[2]: anión Las
cargas de iones se toman en 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
fuente
OP especificó que los iones se pueden administrar en cualquier orden.
Heimdall
6

Retina , 86 80 bytes

Gracias a Neil por guardar 6 bytes.

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

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

Pruébalo en línea!

La entrada está separada por salto de línea (el conjunto de pruebas usa separación por comas para mayor comodidad)

Explicación

^
(

Comenzamos anteponiendo a (a cada molécula. Los ^partidos se inician en línea porque m)hacia el final del programa establece el modo multilínea para todas las etapas anteriores.

\^.+
)_$&$*

Reemplazamos la ^[-+]nparte con )_, seguida de ncopias de 1(es decir, convertimos los cargos a unarios, dejando caer los signos).

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

Esta etapa hace tres cosas: divide ambas cargas por su MCD, las convierte de nuevo a decimales y las intercambia. El GCD se puede encontrar con bastante facilidad en expresiones regulares, haciendo coincidir el más largo 1+que nos permite igualar ambas cargas utilizando solo la referencia inversa \1. Para dividir por esto, hacemos uso de la función "conteo de captura" de Retina, que nos dice con qué frecuencia se ha utilizado un grupo. Entonces, $#2es la primera carga dividida por el MCD y $#3es la segunda carga dividida por el MCD (ambos en decimal).

_1$

Eliminamos _1s de los extremos de ambas partes.

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

Y eliminamos los paréntesis de las líneas que terminan en a )(es decir, las que tenían un _1allí), así como las líneas que solo contienen un átomo.

Finalmente, concatenamos las dos moléculas dejando caer el salto de línea.

Martin Ender
fuente
3

Haskell , 101 97 bytes

(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

Pruébalo en línea! Ejemplo de uso: Fe^+3, O^-2se toma como ("Fe"#"O")3 2.

Laikoni
fuente
2

Python 3 , 131 bytes

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]

Pruébalo en línea!

Python 2 , 196 174 170 155 149 140 136 bytes

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]

Pruébalo en línea!

TFeld
fuente
Python 3 para 131 bytes
pizzapants184
2

Python 3 , 129 bytes

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*

Pruébalo en línea!


Si necesitamos manejar cargas negativas de los aniones, 153 bytes:

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*

Pruébalo en línea!

Sr. Xcoder
fuente
2

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

Sí, sumisión ridículamente grande, no estoy seguro de cuán competitivo será ...

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 rutinas perfectamente empaquetadas en un directorio. MEs el principal. Espera 2 cadenas en la pila formateadas como iones y empuja una cadena de molécula en la pila.

Sdivide el ion en carga como un número y la fórmula del elemento como una cadena. Por ejemplo, "PO_4^-3"se tomaría de la pila -3y se "PO_4"empujaría hacia la pila.

June el número de iones con la fórmula y decide si envolver la fórmula entre paréntesis. El bit anterior ELSEtrata con 1 ion, dejando la cadena como está. Por ejemplo, si 1y "PO_4"están en la pila, se reemplazan por "PO_4". 1y "H"da "H".

El resto trata con múltiples iones; si es un átomo único, no está entre paréntesis, de lo contrario lo está. Para decidir si es así, verifico la longitud de la cadena y compruebo si el último carácter es >"Z". Las expresiones booleanas devuelven 1 para verdadero y 0 para falso. Al restar el resultado de esta comparación de la longitud de la cadena, obtengo 1 o menos cuando es un solo átomo; de lo contrario, más: la longitud 1 es un solo átomo; la longitud 2 tendrá una letra como último carácter; para un solo átomo es minúscula, entonces >"Z", haciendo el resultado 1, de lo contrario 2; longitud 3 o más significa más de 1 átomo y con 0 o 1 restado de la longitud el resultado será al menos 2. Por ejemplo, 3y "PO_4"da "(PO_4)_3". 3y "Al"da "Al_3".

Mprimero divide cada ion usando S. Después de la primera línea, el nivel 5 de la pila (por lo que el objeto enterrado más profundo) contiene la carga del segundo ion, la fórmula del segundo ion del nivel 4, la fórmula del primer ion del nivel 3, el valor absoluto del nivel 2 de la carga del primer ion y el valor absoluto del nivel 1 de la carga del segundo ion nuevamente. Por ejemplo, si los iones dados en la pila son "Al^+3", "SO_4^-2"obtenemos -2, "SO_4", "Al", 3, 2.

La segunda línea calcula mcd de los 2 cargos (dejando los cargos intactos)

La tercera línea divide cada carga por el mcd (para calcular los múltiplos) y lo une con la fórmula del ion usando J. Entonces tenemos dos cadenas cada una con un ion dado con carga eliminada (o un múltiplo de ella) y una carga de la segunda enterrada detrás de ellas. Por ejemplo, -2, "Al_2", "(SO_4)_3"(-2 es la carga de SO_4).

La cuarta línea libera la carga y, si es positiva, intercambia las dos cadenas (para que el catión aparezca primero) antes de unirlas. Así en el ejemplo anterior, porque es negativo, se unen en el orden en que son: "Al_2(SO_4)_3".

Heimdall
fuente
1

JavaScript, 145 bytes

(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,"")

Toma argumentos ces catión, aes anión, pes carga positiva, nes carga negativa.

ericw31415
fuente