De vuelta a la clase de química

15

Introducción

Una de las primeras cosas que aprendí en química fue dar la fórmula para la combustión de alcanos. El ejemplo más básico era: 2CH4 + 4O2 > 4H2O + 2CO2. Tenga en cuenta que la ecuación podría haberse simplificado dividiendo cada coeficiente por 2, obtendríamos CH4 + 2O2 > 2H2O + CO2 . Para facilitar las cosas, vamos a ignorar este paso .

Puede ver que con la combustión de cualquier alcano, se usa oxígeno. Después de la reacción, solo se producen CO2 y H2O.

La tarea:

Proporcione un programa completo que reciba información de STDIN o el equivalente más cercano posible, y genere la reacción total usando STDOUT o el equivalente más cercano posible.

La entrada siempre estará en la forma C(n)H(2n+2), con n > 0. Estas son algunas entradas de ejemplo:

CH4
C2H6
C3H8
C4H10
C5H12
C6H14

etc.

Un consejo útil:

Cada alcano tiene un patrón estándar en la reacción de combustión:

2C(n)H(2n+2) + (3n+1)O2 > (2n+2)H2O + (2n)CO2

p.ej

C4H10dicta la siguiente ecuación: 2C(4)H(2*4+2) + (3*4+1)O2 > (2*4+2)H2O + (2*4)CO2. Después de calcular todo, obtenemos esta ecuación final:2C4H10 + 13O2 > 10H2O + 8CO2

Ejemplos:

input:  CH4
output: 2CH4 + 4O2 > 4H2O + 2CO2

input:  C3H8
output: 2C3H8 + 10O2 > 8H2O + 6CO2

input:  C4H10
output: 2C4H10 + 13O2 > 10H2O + 8CO2

input:  C12H26
output: 2C12H26 + 37O2 > 26H2O + 24CO2

Reglas:

  • Necesita proporcionar un programa completo.
  • Su programa necesita recibir información de STDIN, o el equivalente más cercano si no es posible.
  • Su programa necesita salir usando STDOUT, o el equivalente más cercano si no es posible.
  • Tenga en cuenta que usé espacios para los ejemplos para aumentar la legibilidad, estos no son necesarios . 2CH4 + 4O2 > 4H2O + 2CO2y 2CH4+4O2>4H2O+2CO2son ambas salidas válidas. Sin embargo, si usa espacios consistentemente para la salida, obtendrá un bono de -10%
  • Este es el , por lo que gana el programa con la menor cantidad de bytes.
Adnan
fuente
totalmente diferente pero relacionado: Dibujo de estructuras de alcanos de Lewis
No es que Charles el
Entonces, ¿podemos suponer que la entrada será la fórmula correcta?
TanMath
@TanMath, sí, no tienes que preocuparte por fórmulas inválidas
Adnan
"usar espacios de manera consistente": ¿usaría consistentemente el uso de 0 espacios?
Mego
1
@Mego, no. Usar 0 espacios no es usar espacios en absoluto, por lo que la regla no se aplica
Adnan

Respuestas:

7

Python 3, 86 * 0.9 = 77.4 bytes

s=input()
N=int(s.split('H')[1])
print("2%s + %dO2 > %dH20 + %dCO2"%(s,N*1.5-2,N,N-2))

Extrae el número de H's en lugar del número de C' s de la entrada. Esto evita las mayúsculas especiales CH4y simplifica las expresiones de salida en términos de N=2n+2.

La salida tiene parámetros conectados mediante formato de cadena. El primer sumando es solo la cadena de entrada, y el resto tiene números calculados conectados. Tenga en cuenta que N*1.5-2(igual que N*3/2-2) da un flotador, pero el formato de cadena lo convierte en un int.

xnor
fuente
4

Java, 0.9 * 202 = 181.8 bytes

A veces, me pregunto si me estoy lastimando con Java.

¡Gracias a @TNT y @TFeld por reducir unos 20 bytes!

clase A {public static void main (String [] a) {String s = a [0] .substring (1, a [0] .indexOf ("H")); long n = Long.parseLong ((s.length ()> 0)? S: "1"); System.out.printf ("2% s +% dO2>% dH2O +% dCO2", a [0], 3 * n + 1,2 * n + 2 , 2 * n);}}

Bastante simple. Básicamente, corto la entrada de Ca H, y obtengo esa subcadena. Si no es nada, me puse na uno. De lo contrario, lo configuro en el número entre Cy H. El siguiente código simplemente lo imprime y lo pone en notación adecuada.

Sin golf:

clase A{
    public static void main (Cadena [] a) {
         Cadena s = a [0] .substring (1, a [0] .indexOf ("H"));
         long n = Long.parseLong ((s.length ()> 0)? s: "1");
         System.out.printf ("2% s +% dO2>% dH2O +% dCO2", a [0], 3 * n + 1,2 * n + 2,2 * n);
    }
}
Addison Crump
fuente
2
Buena respuesta, pero debe usar STDIN y no argumentos de línea de comando. Aunque podría acortarlo usando en printflugar de +(-11 de su puntaje bruto si contaba correctamente).
TNT
Me han dicho que usar argumentos de línea de comandos es una alternativa aceptable a STDIN. Además, ¿podría aclarar cómo quiere que lo use printf? (Un poco quisquilloso con eso, no lo he usado antes.: D)
Addison Crump
printfutiliza mecánica de java.util.Formatter. Puede tener una cadena para imprimir como "% d" en su declaración de impresión y después de ella algún valor o variable que se imprimirá en su lugar. Puede ser útil en situaciones donde tiene muchas variables para imprimir, por ejemplo .
TNT
Y el hecho de que los argumentos de la línea de comandos sean aceptables en lugar de STDIN es una noticia nueva (y bastante útil) para mí. :)
TNT
1
@VoteToClose Sí, te estás haciendo daño con Java.
Kritixi Lithos
4

Python 2, 122 91 * 0.9 = 81.9 bytes

i=input()
n=2*int(i[1:i.find('H')]or 1)
print'2%s + %dO2 > %dH2O + %dCO2'%(i,n*3/2+1,n+2,n)
TFeld
fuente
3

Javascript ES6, 63 * .9 = 56.7 bytes

_=>`2${_} + ${$=_.split`H`[1],$*1.5-2}O2 > ${$}H2O + ${$-2}CO2`

Similar a mi respuesta de ESMin.

Mama Fun Roll
fuente
3

Pyth, 69 bytes * 0.9 = 62 63 * 0.9 = 57 56 * 0.9 = 50 53 * 0.9 = 48 bytes

Js>z+xz\H1s[\2z%" + %dO2 > %dH2O + %dCO2"[-*1.5J2J-J2

Es como la respuesta de xnor, donde uso los valores de H. Una variable J se usa para almacenar la cantidad de H en la fórmula molecular de la molécula.

Pruébalo aquí

TanMath
fuente
Gastas seis bytes en el espaciado, pero obtienes solo cinco bytes del bono, por lo que no vale la pena.
lirtosiast el
2

Javascript ES6, 96 * 0.9 = 86.4

f=s=>`2C${(n=(s.match(/\d+(?!.*\d)/)[0]-2))>2?n/2:''}H${n+2} + ${1.5*n+1}O2 > ${n+2}H2O + ${n}CO2`
Dendrobium
fuente
2

CJam, 45 44 bytes

2r_'H/1=[i_((_2/1$+)@@]"+%dO2>%dH2O+%dCO2"e%

Pruébalo en línea

Para evitar una carcasa especial CH4, no uso el primer número en absoluto, y solo extraigo el número después del H. Esto le da el valor de 2n+2. Los valores restantes se calculan en función de eso y se formatean.

Explicación:

2       Push leading 2 for output.
r       Get input.
_'H/    Copy and split at 'H.
1=      Take second part after split, this is 2n+2.
[       Start list.
  i       Convert string value to integer.
  _((     Copy and decrement twice, giving 2n.
  _2/     Copy and divide by 2, giving n.
  1$      Copy the 2n to the top.
  +       Add, to get 3n.
  )       Increment, giving 3n+1. We now have 2n+2, 2n, 3n+1 on stack.
  @@      Rotate top 3 entries twice, to get 3n+1, 2n+2, 2n.
]       Close list.
"+%dO2>%dH2O+%dCO2"
        Format string for output.
e%      "printf" operator.
Reto Koradi
fuente
2r_[[~]W=_2/(3*)\_2-]"+%dO2>%dH2O+%dCO2"e%Guarda un byte.
Dennis
2

Perl, (84 + 1) * 0.9 = 76.5

(+1 caracteres por correr con la -nbandera)

Mi primer golf Perl!

@x=(1,m/C(\d)/g);$n=$x[$#x];say"2$_ + ".(3*$n+1)."O2 > ".(($n*=2)+2)."H20 + ${n}CO2"

Es importante que STDIN no contenga una nueva línea final. Ejemplo de uso:

llama@llama:...code/perl/ppcg64412chemistry$ printf CH4 | perl -n chemistry.pl
2CH4 + 4O2 > 4H20 + 2CO2

Ungolfed-ish:

#!/usr/bin/perl
use 5.10.0;

$_ = 'C3H8';
my @x = (1, m/C(\d)/g);
my $n = $x[$#x];
say "2$_ + ".(3*$n+1)."O2 > ".(($n*=2)+2)."H20 + ${n}CO2";

Las líneas

my @x = (1, m/C(\d)/g);
my $n = $x[$#x];

son bastante interesantes aquí $#xrepresenta el "último índice poblado" de @x(y el resaltado de sintaxis de SE cree que es un comentario porque es tonto), por $x[$#x]lo que seleccionará la parte capturada de la C(\d)expresión regular si existe, o de lo 1contrario. (A Perl no le importa que sea una cadena en todos los demás casos, excepto 1; puede usar operadores numéricos en cadenas muy bien en Perl).

Pomo de la puerta
fuente
1

JS, 118 (106) bytes

x=prompt();y=x.replace("CH","C1H").match(/\d{1,}/g)[0];alert(2+x+" + "+(3*y+1)+"O2 > "+(2*y+2)+"H2O + "+(2*y)+"CO2");
Nautilo
fuente
1

51, 51 * .9 = 45.9 caracteres / 64 * .9 = 57.6 bytes

a=ïČ`H”[1],`2⦃ï} + ⦃a*1.5-2}O2 > ⦃a}H2O + ⦃a-2}CO2`

Try it here (Firefox only).

Explicación

a=ïČ`H”[1],      // split input along H to get 2n+2
`  2⦃ï}          // 2C(n)H(2n+2) – this is the same as 2[input alkane's formula]
   + ⦃a*1.5-2}O2 // + 2(3n+1)O2
   > ⦃a}H2O      // > (2n+2)H2O
   + ⦃a-2}CO2    // + (2n)O2
`                // implicitly output the template string above
Mama Fun Roll
fuente
Quien haya rechazado mi respuesta, ¿podría obtener una explicación?
Mama Fun Roll
1

Python, 0.9 * 195 = 175 0.9 * 190 = 171 0.9 * 148 = 133 bytes

i=raw_input()
O=3*int(i[1:i.find('H')]or 1)+1;C=2*int(i[1:i.find('H')]or 1);print"2"+i+" + "+`O`+"O2"+" > "+i[i.find('H')+1:]+"H2O"+ " + "+`C`+"CO2"

Pruébalo aquí

TanMath
fuente
No necesita un espacio entre printy un "carácter, y la CO2variable podría llamarse algo más corto :)
undergroundmonorail
@undergroundmonorail gracias
TanMath
Como i[1]se garantiza que sea uno "H"o un dígito, puede guardar otro byte con if i[1]>"9"(o reemplazarlo "9"con cualquier otro carácter con un valor ascii de 58 a 71)
undergroundmonorail
1

F #, 113

let s=stdin.ReadLine()
float s.[1+s.IndexOf 'H'..]|>fun f->printf"2%s + %gO2 > %gH2O + %gCO2"s<|f*1.5-2.<|f<|f-2.
Sehnsucht
fuente
1

MATLAB, 96 * 0.9 = 86.4 bytes

s=input('');i=[sscanf(s,'C%dH'),1];n=i(1);fprintf('%s + %dO2 > %dH2O + %dCO2',s,3*n+1,2*n+2,2*n)

Bastante autoexplicativo. Toma una cadena de entrada (necesita incluirla entre comillas para que MATLAB no intente ejecutarla). Luego convierte el número entre C y H en la entrada a decimal. El valor 1 se agrega como una matriz a la salida de sscanf para que, en el casoCH4 que extraigamos el primer índice de la matriz n, obtengamos un 1 si no había un número entre la C y la H. Luego se imprime con los espacios siguiendo la fórmula en la pregunta.

Esto también debería funcionar con Octave usando el intérprete en línea aquí .

Tom Carpenter
fuente
1

C ++, 160 * 0.9 = 144 bytes

#include<iostream>
int main(){int n=1,t;std::cin.get();std::cin>>n;t=2*n;printf("2C");n-1&&printf("%i",n);printf("H%i + %iO2 > %iH2O + %iCO2",t+2,t+n+1,t+2,t);}

Un poco más de lo que esperaba. Lee primero char y lo descarta, luego lee int y genera el resultado. El problema es conn ser 1. No se me ocurre una forma más corta de generarlo.

Sin golf

#include <iostream>
int main()
{
    int n = 1, t;
    std::cin.get();
    std::cin >> n;
    t = 2 * n;
    printf("2C");
    n - 1 && printf("%i", n);
    printf("H%i + %iO2 > %iH2O + %iCO2", t + 2, t + n + 1, t + 2, t);
}
Zereges
fuente
1

Clojure / ClojureScript, 98 * 0.9 = 88.2 bytes

#(let[n(max 1(int((re-find #"C(.*)H"%)1)))m(* 2 n)](str "2"%" + "(inc(* 3 n))"O2 > "(+ 2 m)"H2O + "m"CO2"))

Crea una función anónima. Pruébalo yendo aquí y entrando (def f #(let...)), entonces (f "C3H8").

MattPutnam
fuente
1

Excel, 123 * 0.9 = 110.7 bytes

=="2"&A1&" + "&(3*MID(A1,FIND("H",A1)+1,9)/2-2)&"O2 > "&MID(A1,FIND("H",A1)+1,9)&"H2O + "&(MID(A1,FIND("H",A1)+1,9)-2)&"CO2"

Si pudiéramos tomar la entrada CH4 como C1H4, se puede reducir a 122 * 0.9 = 109.8 bytes

="2"&A1&" + "&3*MID(A1,2,FIND("H",A1)-2)+1&"O2"&" > "&MID(A1,FIND("H",A1)+1,9)&"H2O + "&(MID(A1,FIND("H",A1)+1,9)-2)&"CO2"
Wernisch
fuente