Torna alla lezione di chimica


15

introduzione

Una delle prime cose che ho imparato in chimica è stata la formula per la combustione degli alcani. L'esempio più semplice è: 2CH4 + 4O2 > 4H2O + 2CO2. Si noti che l'equazione avrebbe potuto essere semplificata dividendo ogni coefficiente per 2, otterremmo CH4 + 2O2 > 2H2O + CO2 . Per semplificare le cose, ignoreremo questo passaggio .

Puoi vedere che con la combustione di qualsiasi alcano viene utilizzato ossigeno. Dopo la reazione, vengono prodotti solo CO2 e H2O.

L'obiettivo:

Fornire un programma completo che prende input da STDIN o dall'equivalente più vicino possibile e produce la reazione totale usando STDOUT o l'equivalente possibile più vicino.

L'input sarà sempre nella forma C(n)H(2n+2), con n > 0. Questi sono alcuni input di esempio:

CH4
C2H6
C3H8
C4H10
C5H12
C6H14

etc.

Un consiglio utile:

Ogni alcano ha uno schema standard nella reazione di combustione:

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

per esempio

C4H10 fornisce la seguente equazione: 2C(4)H(2*4+2) + (3*4+1)O2 > (2*4+2)H2O + (2*4)CO2 . Dopo aver calcolato tutto, otteniamo questa equazione finale:2C4H10 + 13O2 > 10H2O + 8CO2

Esempi:

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

Regole:

  • Devi fornire un programma completo.
  • Il tuo programma deve ricevere input da STDIN, o l'equivalente più vicino se non è possibile.
  • Il tuo programma deve essere emesso usando STDOUT o l'equivalente più vicino se non è possibile.
  • Si noti che ho usato spazi per gli esempi per aumentare la leggibilità, questi non sono necessari . 2CH4 + 4O2 > 4H2O + 2CO2e 2CH4+4O2>4H2O+2CO2sono entrambi output validi. Tuttavia, se usi costantemente spazi per l'output, otterrai un bonus del -10%
  • Questo è , quindi vince il programma con il minor numero di byte!

totalmente diverso ma correlato: Disegnare Lewis Structures of Alkanes
Non che Charles il

Quindi possiamo supporre che l'input sarà formule corrette?
TanMath,

@TanMath, sì, non devi preoccuparti di formule non valide
Adnan,

"usa coerentemente gli spazi" - conterebbe costantemente 0 spazi?
Mego

1
@Mego, no. L'uso di 0 spazi non utilizza affatto gli spazi, quindi la regola non si applica
Adnan,

Risposte:



7

Python 3, 86 * 0.9 = 77,4 byte

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

Estrae il numero di H"anziché il numero di C" dall'input. Questo evita involucri specialiCH4 e semplifica le espressioni di output in termini di N=2n+2.

L'output ha parametri collegati tramite la formattazione della stringa. Il primo summand è solo la stringa di input e gli altri hanno calcolato i numeri collegati. Nota che N*1.5-2(uguale a N*3/2-2) fornisce un float, ma la formattazione della stringa lo converte in un int.


4

Java, 0.9 * 202 = 181.8 byte

A volte, mi chiedo se mi sto solo facendo del male con Java.

Grazie a @TNT e @TFeld per aver rasato ben 20 byte!

class A {vuoto statico pubblico 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);}}

Abbastanza semplice. Fondamentalmente, ho tagliato l'input da Ca He ho ottenuto quella sottostringa. Se non è niente, ho impostato nsu uno. Altrimenti, l'ho impostato sul numero tra Ce H. Il codice seguente lo stampa e lo mette in notazione corretta.

Ungolfed:

classe 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);
    }
}

2
Buona risposta, ma è necessario utilizzare STDIN e non args da riga di comando. Anche se potresti accorciarlo usando printfinvece di +(-11 dal tuo punteggio grezzo se contassi correttamente).
TNT,

Mi è stato detto che l'uso degli argomenti della riga di comando è un'alternativa accettabile a STDIN. Inoltre, potresti chiarire come intendi per me usare printf? (Un po 'schizzinoso, non l'ho mai usato prima.: D)
Addison Crump,

printfusa la meccanica di java.util.Formatter. Puoi avere una stringa da stampare come "% d" nella tua dichiarazione di stampa e successivamente un valore o una variabile che verrà invece stampata. Può essere utile in situazioni in cui hai molte variabili da stampare, per esempio .
TNT,

E il fatto che gli argomenti della riga di comando siano accettabili al posto di STDIN è una novità (e piuttosto utile) per me. :)
TNT,

1
@VotoToChiudi Sì, ti stai facendo del male con Java.
Kritixi Lithos,

4

Python 2, 122 91 * 0,9 = 81,9 byte

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)

3

Javascript ES6, 63 * .9 = 56.7 byte

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

Simile alla mia risposta ESMin.


3

Pyth, 69 byte * 0,9 = 62 63 * 0,9 = 57 56 * 0,9 = 50 53 * 0,9 = 48 byte

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

È proprio come la risposta di xnor, dove uso i valori H. Una variabile J viene utilizzata per memorizzare la quantità di H nella formula molecolare della molecola.

Provalo qui


Spendi sei byte per la spaziatura, ma guadagni solo cinque byte dal bonus, quindi non ne vale la pena.
lirtosiast

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`

2

CJam, 45 44 byte

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

Provalo online

Per evitare un involucro speciale CH4, non uso affatto il primo numero ed estraggo il numero solo dopo il H. Questo dà il valore di 2n+2. I valori rimanenti vengono quindi calcolati in base a quello e formattati.

Spiegazione:

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.

2r_[[~]W=_2/(3*)\_2-]"+%dO2>%dH2O+%dCO2"e%salva un byte.
Dennis,

2

Perl, (84 + 1) * 0.9 = 76.5

(+1 carattere per correre con la -nbandiera)

Il mio primo golf Perl!

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

È importante che STDIN non contenga una nuova riga finale. Esempio di utilizzo:

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";

Le linee

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

sono abbastanza interessanti qui. $#xrappresenta l '"ultimo indice popolato" di @x(e l'evidenziazione della sintassi di SE pensa che sia un commento perché è stupido), quindi $x[$#x]selezionerà la parte catturata del C(\d)regex se esiste, o 1altrimenti. (A Perl non importa che sarà una stringa in tutti gli altri casi tranne 1; puoi usare operatori numerici su stringhe bene in Perl.)


1

JS, 118 (106) byte

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");

1

𝔼𝕊𝕄𝕚𝕟, 51 * .9 = 45,9 caratteri / 64 * .9 = 57,6 byte

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

Try it here (Firefox only).

Spiegazione

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

Chiunque abbia retrocesso la mia risposta, potrebbe per favore ottenere una spiegazione?
Mama Fun Roll,

1

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

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"

Provalo qui


Non è necessario uno spazio tra printe un "personaggio e la CO2variabile potrebbe essere denominata in modo più breve :)
undergroundmonorail

@undergroundmonorail ringrazia
TanMath il

Poiché i[1]è garantito che sia uno "H"o una cifra, puoi salvare un altro byte con if i[1]>"9"(o sostituirlo "9"con qualsiasi altro carattere con un valore ASCII compreso tra 58 e 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.

1

MATLAB, 96 * 0,9 = 86,4 byte

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)

Abbastanza autoesplicativo. Accetta una stringa di input (è necessario racchiuderla tra virgolette in modo che MATLAB non tenti di eseguirla!). Quindi converte il numero tra C e H nell'input in decimale. Il valore 1 viene aggiunto come array all'output di sscanf in modo che nel caso in CH4cui estraiamo il primo indice dell'array in notteniamo un 1 se non ci fosse un numero tra C e H. Quindi stampa solo con gli spazi seguendo la formula nella domanda.

Questo dovrebbe funzionare anche con Octave usando qui l' interprete online .


1

C ++, 160 * 0.9 = 144 byte

#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 po 'di più di quanto mi aspettassi. Legge il primo carattere e lo scarta, quindi legge int e genera il risultato. Il problema è con l' nessere 1. Non riesco a pensare a un modo più breve per produrlo.

Ungolfed

#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);
}

1

Clojure / ClojureScript, 98 * 0.9 = 88.2 byte

#(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 funzione anonima. Provalo andando qui ed entrando (def f #(let...)), quindi (f "C3H8").


1

Excel, 123 * 0.9 = 110.7 byte

=="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"

Se potessimo prendere l'input CH4 come C1H4, può essere ridotto a 122 * 0,9 = 109,8 byte

="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"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.