Desafio
Dada a fórmula de um produto químico, produza o M r do composto.
Equação
Cada elemento do composto é seguido por um número que indica o número do referido átomo no composto. Se não houver um número, existe apenas um desse átomo no composto.
Alguns exemplos são:
- O etanol (C 2 H 6 O) seria
C2H6O
onde existem dois átomos de carbono, 6 átomos de hidrogênio e 1 átomo de oxigênio - Hidróxido de magnésio (MgO 2 H 2 ) seria
MgO2H2
onde existe um átomo de magnésio, dois átomos de oxigênio e dois átomos de hidrogênio.
Observe que você nunca precisará lidar com colchetes e cada elemento é incluído apenas uma vez na fórmula.
Embora a maioria das pessoas provavelmente atenha à ordem com a qual se sente mais confortável, não existe um sistema de pedidos rigoroso. Por exemplo, a água pode ser dada como H2O
ou OH2
.
M r
Nota: Aqui, suponha que a massa da fórmula seja igual à massa molecular
O Mr de um composto, a massa molecular, é a soma dos pesos atômicos dos átomos na molécula.
Os únicos elementos e seus pesos atômicos com uma casa decimal que você precisa suportar (hidrogênio e cálcio, sem incluir gases nobres) são os seguintes. Eles também podem ser encontrados aqui
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
Você sempre deve fornecer a saída com uma casa decimal.
Por exemplo, etanol ( C2H6O
) tem uma M r de 46.0
como é a soma das massas atómicas dos elementos nele:
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
Uma única sequência no formato acima. Você pode garantir que os elementos incluídos na equação sejam símbolos elementares reais.
Não é garantido que o composto fornecido exista na realidade.
Resultado
O total Mr do composto, com 1 casa decimal.
Regras
Construções que acessam elementos ou dados químicos não são permitidas (desculpe Mathematica)
Exemplos
Input > Output
CaCO3 > 100.1
H2SO4 > 98.1
SF6 > 146.1
C100H202O53 > 2250.0
Ganhando
O código mais curto em bytes vence.
Este post foi adotado com permissão de caird coinheringaahing . (Postagem excluída)
fonte
2H2O
:?NumberForm[#&@@#~ChemicalData~"MolecularMass",{9,1}]&
Respostas:
Geléia , 63 bytes
Um link monádico que aceita uma lista de caracteres e retorna um número.
Experimente online!
Quão?
fonte
Python 3 ,
189188168 bytes-14 bytes usando o hash da resposta JavaScript de Justin Mariner (ES6) .
Experimente online!
Abaixo está a versão de 182 bytes, deixarei a explicação para este - o acima apenas altera a ordem dos pesos, usa
int
para converter o nome do elemento da base29
e usa dividendos diferentes para compactar o intervalo de números inteiros - veja Justin Resposta de Mariner .Uma função sem nome que aceita uma sequência
s
e retorna um número.Experimente online!
Quão?
Usa um regex para dividir a entrada
s
,, nos elementos e suas contagens usando:re.findall("(\D[a-z]?)(\d*)",s)
\D
corresponde exatamente a um não dígito e[a-z]?
corresponde a 0 ou 1 letra minúscula, junto a elementos correspondentes.\d*
corresponde a 0 ou mais dígitos. Os parênteses os transformam em dois grupos e, como tal,findall("...",s)
retorna uma lista de tuplas de strings[(element, number),...]
.O número é simples de extrair, a única coisa a alça é que um meio de cordas vazias 1, isto é conseguido com uma lógica
or
desde cordas Python são Falsey:int(n or 1)
.A cadeia de elementos recebe um número único, obtendo o produto dos ordinais de seu primeiro e último caractere (geralmente são os mesmos, por exemplo, S ou C, mas precisamos diferenciar entre Cl, C, Ca e Na, para que não possamos usar apenas um personagem).
Esses números são então divididos em hash para cobrir um intervalo muito menor de [0,18], encontrado por uma pesquisa no espaço do módulo resultante
%1135%98%19
. Por exemplo,"Cl"
tem ordinais67
e108
, que se multiplicam para dar7736
, qual1135
é o módulo426
, qual98
é o módulo34
, qual19
é o módulo15
; esse número é usado para indexar em uma lista de números inteiros - o 15º valor (indexado em 0) da 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]
é
35.5
o peso atômico de Cl, que é então multiplicado pelo número de tais elementos (como encontrado acima).Esses produtos são então adicionados usando
sum(...)
.fonte
PHP , 235 bytes
Experimente online!
Em vez 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])
você pode 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]
com a mesma contagem de bytesfonte
JavaScript (ES6), 150 bytes
Inspirado na resposta Python de Jonathan Allan , onde ele explicou dar a cada elemento um número único e colocar esses números em um intervalo menor.
Os elementos foram transformados em números únicos, interpretando-os como base 29 (0-9 e AS). Descobri então que
%633%35%18
reduz os valores até o intervalo[0, 17]
, mantendo a exclusividade.Snippet de teste
fonte
Clojure,
198194 bytesAtualização: melhor
for
quereduce
.Original:
Gostaria de saber se existe uma maneira mais compacta de codificar a tabela de consulta.
fonte
Python 3 , 253 bytes
Experimente online!
fonte
Mathematica,
390338329 BytesEconomizei 9 bytes devido a estar realmente acordado agora e a usar o encurtamento pretendido.
Versão 2.1:
Explicação: Encontre a posição de todos os caracteres maiúsculos. Coloque um ponto antes de cada um. Divida a corda em cada ponto. Para esta lista de substrings, faça a seguinte divisão com base em letras e em dígitos. Para os que são divididos por letras, converta a sequência em números. Para os que são divididos por dígitos, substitua cada produto químico pelo seu peso molecular. Para aqueles com peso molecular e contagem de átomos, substitua-o pelo produto deles. Eles encontram o total.
Versão 1:
Tenho certeza de que isso pode ser um lote de golfe (ou apenas completamente reescrito). Eu só queria descobrir como fazê-lo. (Refletirá sobre isso de manhã.)
Explicação: Primeiro divida a sequência em caracteres. Em seguida, dobre a matriz juntando caracteres minúsculos e números de volta ao seu capital. Em seguida, acrescente 1 a qualquer produto químico sem um número no final. Em seguida, faça duas divisões dos termos na matriz - uma dividida em todos os números e uma dividida em todas as letras. Na primeira, substitua as letras pelas massas molares e encontre o produto escalar dessas duas listas.
fonte
Python 3-408 bytes
Esta é principalmente a solução do @ovs, já que ele reduziu em mais de 120 bytes ... Veja a solução inicial abaixo.
Experimente online!
Python 3 -
550 548535 bytes (perdeu a contagem com recuo)Guardou 10 bytes graças a @cairdcoinheringaahing e 3 guardou graças a ovs
Eu tinha um objetivo pessoal de não usar nenhum regex e fazê-lo da maneira divertida e antiga ... Acabou sendo 350 bytes a mais que a solução regex, mas ele usa apenas a biblioteca padrão do Python ...
Experimente online!
Se alguém quiser jogar golfe (com correções de indentação e outros truques ...), será 100% bem recebido, sentindo que há uma maneira melhor de fazer isso ...
fonte
for y in g: if str(y[0])==h[i][:h[i].index('-')]:x+=y[1]
porfor y in g:x+=y[1]*(str(y[0])==h[i][:h[i].index('-')])
if/for/while
na próxima linha. Como esse é o caso em todas as linhas recuadas, você não pode salvar bytes com isso.