Desafío
Dada la fórmula de una sustancia química, genera el M r del compuesto.
Ecuación
Cada elemento en el compuesto es seguido por un número que denota el número de dicho átomo en el compuesto. Si no hay un número, solo hay uno de ese átomo en el compuesto.
Algunos ejemplos son:
- El etanol (C 2 H 6 O) sería
C2H6O
donde hay dos átomos de carbono, 6 átomos de hidrógeno y 1 átomo de oxígeno. - El hidróxido de magnesio (MgO 2 H 2 ) sería
MgO2H2
donde hay un átomo de magnesio, dos átomos de oxígeno y dos átomos de hidrógeno.
Tenga en cuenta que nunca tendrá que manejar paréntesis y cada elemento se incluye solo una vez en la fórmula.
Si bien la mayoría de las personas probablemente se apegará al orden con el que se sienta más cómoda, no existe un sistema de pedido estricto. Por ejemplo, el agua puede administrarse como H2O
o OH2
.
M r
Nota: Aquí, suponga que la masa de la fórmula es igual a la masa molecular
La MR de un compuesto, la masa molecular, es la suma de los pesos atómicos de los átomos en la molécula.
Los únicos elementos y sus pesos atómicos a 1 decimal que debe soportar (hidrógeno a calcio, sin incluir gases nobles) son los siguientes. También se pueden encontrar aquí.
H - 1.0 Li - 6.9 Be - 9.0
B - 10.8 C - 12.0 N - 14.0
O - 16.0 F - 19.0 Na - 23.0
Mg - 24.3 Al - 27.0 Si - 28.1
P - 31.0 S - 32.1 Cl - 35.5
K - 39.1 Ca - 40.1
Siempre debe dar la salida a un decimal.
Por ejemplo, etanol ( C2H6O
) tiene un M r de, 46.0
ya que es la suma de los pesos atómicos de los elementos que contiene :
12.0 + 12.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 16.0
(2*C + 6*H + 1*O)
Entrada
Una sola cadena en el formato anterior. Puede garantizar que los elementos incluidos en la ecuación serán símbolos elementales reales.
No se garantiza que el compuesto dado exista en la realidad.
Salida
El total de Rm del compuesto, a 1 decimal.
Reglas
Las incorporaciones que tienen acceso a elementos o datos químicos no están permitidas (lo siento, Mathematica)
Ejemplos
Input > Output
CaCO3 > 100.1
H2SO4 > 98.1
SF6 > 146.1
C100H202O53 > 2250.0
Victorioso
El código más corto en bytes gana.
Esta publicación fue adoptada con permiso de caird coinheringaahing . (Publicación ahora eliminada)
fuente
2H2O
:?NumberForm[#&@@#~ChemicalData~"MolecularMass",{9,1}]&
Respuestas:
Jalea , 63 bytes
Un enlace monádico que acepta una lista de caracteres y devuelve un número.
Pruébalo en línea!
¿Cómo?
fuente
Python 3 ,
189182168bytes-14 bytes utilizando el hash de la respuesta JavaScript de Justin Mariner (ES6) .
Pruébalo en línea!
A continuación se muestra la versión de 182 bytes, dejaré la explicación para esta: lo anterior solo cambia el orden de los pesos, se usa
int
para convertir el nombre del elemento de la base29
y usa diferentes dividendos para comprimir el rango de enteros hacia abajo: vea Justin La respuesta del marinero .Una función sin nombre que acepta una cadena
s
, y devuelve un número.Pruébalo en línea!
¿Cómo?
Utiliza una expresión regular para dividir la entrada,
s
en los elementos y sus cuentas usando:re.findall("(\D[a-z]?)(\d*)",s)
\D
coincide exactamente con un no dígito y[a-z]?
coincide con 0 o 1 letra minúscula, juntos elementos coincidentes.\d*
coincide con 0 o más dígitos. Los paréntesis hacen éstos en dos grupos, y como tal,findall("...",s)
devuelve una lista de tuplas de cadenas,[(element, number),...]
.El número es fácil de extraer, la única cosa a la manija es que un medio de cadena vacía 1, esto se logra con una lógica
or
ya que las cadenas de Python son Falsey-:int(n or 1)
.La cadena de elementos recibe un número único tomando el producto de los ordinales de su primer y último carácter (generalmente son los mismos, por ejemplo, S o C, pero necesitamos diferenciar entre Cl, C, Ca y Na, por lo que no podemos usar uno personaje).
Estos números se dividen en hash para cubrir un rango mucho menor de [0,18], que se encuentra mediante una búsqueda del espacio del módulo que resulta en
%1135%98%19
. Por ejemplo,"Cl"
tiene ordinales67
y108
, que se multiplican para dar7736
, cuál, módulo1135
es426
, qué módulo98
es34
, qué módulo19
es15
; este número se usa para indexar en una lista de enteros: el valor 15 (indexado en 0) en la lista:[16,31,40.1,32.1,0,24.3,12,39.1,28.1,19,0,9,10.8,23,27,35.5,6.9,14,1]
es
35.5
el peso atómico de Cl, que luego se multiplica por el número de tales elementos (como se encontró anteriormente).Estos productos se agregan juntos usando
sum(...)
.fuente
PHP , 235 bytes
Pruébalo en línea!
En lugar de
array_combine([H,Li,Be,B,C,N,O,F,Na,Mg,Al,Si,P,S,Cl,K,Ca],[1,6.9,9,10.8,12,14,16,19,23,24.3,27,28.1,31,32.1,35.5,39.1,40.1])
que pueda usar[H=>1,Li=>6.9,Be=>9,B=>10.8,C=>12,N=>14,O=>16,F=>19,Na=>23,Mg=>24.3,Al=>27,Si=>28.1,P=>31,S=>32.1,Cl=>35.5,K=>39.1,Ca=>40.1]
con el mismo recuento de bytesfuente
JavaScript (ES6), 150 bytes
Inspirado por la respuesta de Python de Jonathan Allan , donde explicó dar a cada elemento un número único y dividir esos números para que estén en un rango más pequeño.
Los elementos se convirtieron en números únicos al interpretarlos como base-29 (0-9 y AS). Luego descubrí que
%633%35%18
reduce los valores al rango de[0, 17]
mientras se mantiene la unicidad.Fragmento de prueba
fuente
Clojure,
198194 bytesActualización: mejor
for
quereduce
.Original:
Me pregunto si hay una forma más compacta de codificar la tabla de búsqueda.
fuente
Python 3 , 253 bytes
Pruébalo en línea!
fuente
Mathematica,
390338329 BytesGuarde 9 bytes debido a que ahora estoy despierto y a usar el acortamiento que pretendía.
Versión 2.1:
Explicación: Encuentre la posición de todos los caracteres en mayúscula. Pon un punto antes de cada uno. Divide la cuerda en cada punto. Para esta lista de subcadenas, haga lo siguiente, divídalo en letras y divídalo en dígitos. Para los divididos por letras, convierta la cadena en números. Para los divididos por dígitos, reemplace cada químico con su peso molecular. Para cualquiera con un peso molecular y un conteo de átomos, reemplácelo con el producto de ellos. Ellos encuentran el total.
Versión 1:
Estoy seguro de que esto puede ser mucho golf (o simplemente reescrito por completo). Solo quería descubrir cómo hacerlo. (Se reflexionará sobre ello en la mañana).
Explicación: Primero divide la cadena en caracteres. Luego dobla sobre la matriz uniendo caracteres en minúscula y números de regreso a su capital. A continuación, agregue un 1 a cualquier químico sin un número al final. Luego haga dos divisiones de los términos en la matriz: una división en todos los números y una división en todas las letras. Para el primero, reemplace las letras con sus masas molares y luego encuentre el producto escalar de estas dos listas.
fuente
Python 3 - 408 bytes
Esta es principalmente la solución de @ovs, ya que la redujo en más de 120 bytes ... Vea la solución inicial a continuación.
Pruébalo en línea!
Python 3 -
550 548535 bytes (perdió la cuenta con sangría)Guardado 10 bytes gracias a @cairdcoinheringaahing y 3 guardados gracias a ovs
Tenía un objetivo personal de no usar ninguna expresión regular y hacerlo de la manera divertida y tradicional ... Resultó ser 350 bytes más largo que la solución de expresiones regulares, pero solo usa la biblioteca estándar de Python ...
Pruébalo en línea!
Si alguien está dispuesto a jugar golf (con correcciones de sangría y otros trucos ...), será 100% bien recibido, sintiendo que hay una mejor manera de hacerlo ...
fuente
for y in g: if str(y[0])==h[i][:h[i].index('-')]:x+=y[1]
confor y in g:x+=y[1]*(str(y[0])==h[i][:h[i].index('-')])
if/for/while
en la siguiente línea. Como este es el caso en cada línea con sangría, no puede guardar bytes con esto.