Derivar as unidades

10

Desafio

Dada uma lista de unidades base do SI, uma lista de equações e um alvo, você deve derivar as unidades do alvo usando apenas as unidades base.

Unidades Derivadas

Da Wikipedia:

O Sistema Internacional de Unidades (SI) especifica um conjunto de sete unidades base das quais todas as outras unidades de medida SI são derivadas. Cada uma dessas outras unidades (unidades derivadas do SI) é adimensional ou pode ser expressa como um produto das potências de uma ou mais unidades básicas.

Por exemplo, a unidade de área derivada do SI é o metro quadrado (m 2 ) e a unidade de densidade derivada do SI é o quilograma por metro cúbico (kg / m 3 ou kg m -3 ).

As sete unidades básicas do SI são:

  • Ampère, A
  • Candela, cd
  • Kelvin, K
  • Quilograma, kg
  • Medidor, m
  • Mole, mol
  • Segundo, s

Exemplo

Entrada

Unidades base:

d [m]
m [kg]
t [s]

Equações:

v = d/t
a = v/t
F = m*a
E = F*d

Alvo:

E

Resultado

E [kg*m*m/s/s]

Entrada

Unidades base:

G [cd]
L [m]
y [A]
a [K]

Equações:

T = y*y/L
A = T*G

Alvo:

A

Resultado

A [cd*A*A/m]

Regras

As unidades serão sempre dadas na forma

a [b]

Onde aserá uma única letra alfabética maiúscula ou minúscula e bserá uma unidade (um ou mais caracteres).

A equação estará na forma

a = c

Onde chaverá uma expressão que somente usará unidades definidas anteriormente e os operadores *e /.

Os poderes devem ser expandidos. Por exemplo, a unidade de área é oficialmente m^2, mas você deve representar isso como m*m. O mesmo aplica-se para os poderes negativos, tais como a velocidade ( m*s^-1), que devem ser representados como uma divisão: m/s. Da mesma forma, as unidades de aceleração, m/s^2ou m*s^-2, devem ser representadas comom/s/s .

Você não precisa fazer nenhum cancelamento. Por exemplo, uma saída C*s/kg/sé válida mesmo que possa ser cancelada até C/kg.

Não há nenhuma ordem específica para a multiplicação: kg*s/m, s/m*kg, s*kg/msão todos válidos (mas /m*s*kgé inválido).

Nota: Você nunca precisará dividir por uma unidade derivada.

Ganhando

O código mais curto em bytes vence

Beta Decay
fonte
Relacionado.
Martin Ender
A entrada (saída) precisa ser tomada (dada) como uma sequência ou outros tipos / estruturas, por exemplo , símbolos, são aceitáveis?
Julian Lobo
@JulianWolf Não, a E / S tem que ser como cadeias de caracteres
Beta Decay

Respostas:

12

Retina , 50 48 bytes

 =

+`((.) (.+)\D*)\2(?!\w*])
$1$3
A-2`
](.).
$1

Experimente online!

Explicação

 =

Remova todos os sinais de igual junto com o espaço na frente deles. Quem precisa disso de qualquer maneira ...

+`((.) (.+)\D*)\2(?!\w*])
$1$3

Isso realiza as substituições de quantidades conhecidas. Corresponde repetidamente a uma definição de quantidade (a quantidade é qualquer caractere na frente de um espaço e a definição a sequência após ele), bem como em algum lugar após a definição em que essa quantidade é usada e insira a definição para o uso. Excluímos unidades desses jogos (ao assegurar que não existe ]após a partida), para que não substitua [m]com [[kg]]por exemplo. Essa substituição é repetida até que a regex não corresponda mais (o que significa que não há uso de uma quantidade restante e todas as linhas foram transformadas em expressões de unidades).

A-2`

Descarte tudo, exceto a última linha.

](.).
$1

Por fim, remova colchetes estranhos. Basicamente, queremos manter o primeiro [e o último, ]mas descartar todos os outros. Os outros sempre aparecem com um operador no meio, como ]*[ou como ]/[. Mais importante, porém, esses são os únicos casos em que a ]é seguido por mais dois caracteres. Então, combinamos todos ]com dois caracteres após eles e substituímos pelo segundo desses três caracteres para manter o operador.

Martin Ender
fonte
1

JavaScript (ES6), 155 153 152 bytes

(U,E,T)=>(u={},U.map(x=>u[x[0]]=x.slice(3,-1)),e={},E.map(x=>e[x[0]]=x.slice(4)).map(_=>s=s.replace(r=/[A-z]/g,m=>e[m]||m),s=e[T]),s.replace(r,m=>u[m]))

Toma unidades básicas e equações como matrizes de strings.

Explicação

// Base Units, Equations, Target
(U,E,T)=>(
    // Map variable names to SI units
    u={},
    U.map(x=>u[x[0]]=x.slice(3,-1)), // x[0] is the variable name,
                                     // x.slice(3,-1) is the unit

    // Map variable names to equations
    e={},
    E.map(x=>e[x[0]]=x.slice(4)) // x[0] is the variable name,
                                 // x.slice(4) is the unit

    // (Initialize return string to the target variable's equation
    // using the (useless) second argument to .map() below)
    // s=e[T]

    // For as many times as there are equations (chained from above),
    .map(_=>
        // Substitute each variable with its equivalent expression
        // if there is one.
        s=s.replace(
            r=/[A-z]/g, // Save this regex for final step.
            m=>e[m]||m
        ),

        // The working string variable is initialized here.
        s=e[T]
    ),

    // Substitute remaining variables with SI units and return. 
    s.replace(r,m=>u[m])
)
darrylyeo
fonte