Zurück zum Chemieunterricht


15

Einführung

Eines der ersten Dinge, die ich in der Chemie gelernt habe, war die Angabe der Formel für die Verbrennung von Alkanen. Das grundlegendste Beispiel war: 2CH4 + 4O2 > 4H2O + 2CO2. Beachten Sie, dass die Gleichung vereinfacht werden könnte, indem jeder Koeffizient durch 2 geteilt wird CH4 + 2O2 > 2H2O + CO2 . Um die Sache zu vereinfachen, werden wir diesen Schritt ignorieren .

Sie können sehen, dass bei der Verbrennung eines Alkans Sauerstoff verwendet wird. Nach der Reaktion entstehen nur CO2 und H2O.

Die Aufgabe:

Geben Sie ein vollständiges Programm an, das Eingaben von STDIN oder dem nächstmöglichen Äquivalent annimmt und die Gesamtreaktion mit STDOUT oder dem nächstmöglichen Äquivalent ausgibt.

Die Eingabe erfolgt immer in der Form C(n)H(2n+2)mit n > 0. Dies sind einige Beispieleingaben:

CH4
C2H6
C3H8
C4H10
C5H12
C6H14

etc.

Ein nützlicher Tipp:

Jedes Alkan hat ein Standardmuster in der Verbrennungsreaktion:

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

z.B

C4H10gibt die folgende Gleichung: 2C(4)H(2*4+2) + (3*4+1)O2 > (2*4+2)H2O + (2*4)CO2. Nachdem wir alles berechnet haben, erhalten wir diese endgültige Gleichung:2C4H10 + 13O2 > 10H2O + 8CO2

Beispiele:

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

Regeln:

  • Sie müssen ein vollständiges Programm bereitstellen.
  • Ihr Programm muss Eingaben von STDIN oder dem nächstgelegenen Äquivalent erhalten, wenn dies nicht möglich ist.
  • Ihr Programm muss mit STDOUT oder dem nächstgelegenen Äquivalent ausgegeben werden, falls dies nicht möglich ist.
  • Beachten Sie, dass ich Leerzeichen für die Beispiele verwendet habe, um die Lesbarkeit zu verbessern. Diese sind nicht erforderlich . 2CH4 + 4O2 > 4H2O + 2CO2und 2CH4+4O2>4H2O+2CO2sind beide gültige Ausgaben. Wenn Sie jedoch konsequent Leerzeichen für die Ausgabe verwenden, erhalten Sie einen Bonus von -10%
  • Das ist , also gewinnt das Programm mit der geringsten Anzahl von Bytes!


Können wir also davon ausgehen, dass die Eingabe korrekte Formeln sein wird?
TanMath,

@ TanMath, ja, Sie müssen sich keine Sorgen über ungültige Formeln machen
Adnan

"durchgängig Leerzeichen verwenden" - würde durchgängig die Verwendung von 0 Leerzeichen zählen?
Mego

1
@ Mego, nein. Bei der Verwendung von 0 Leerzeichen werden überhaupt keine Leerzeichen verwendet, daher gilt die Regel nicht
Adnan,

Antworten:



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

Extrahiert die Anzahl von Hstatt der Anzahl von Caus der Eingabe. Dies vermeidet Sonderfälle CH4und vereinfacht die Ausgabe von Ausdrücken in Bezug auf N=2n+2.

Die Ausgabe enthält Parameter, die über die Formatierung von Zeichenfolgen eingefügt werden. Der erste Summand ist nur die Eingabezeichenfolge, und der Rest hat die eingesteckten Zahlen berechnet. Beachten Sie, dass N*1.5-2(dasselbe wie N*3/2-2) ein Gleitkomma ergibt, die Zeichenfolgenformatierung es jedoch in ein int umwandelt.


4

Java, 0,9 * 202 = 181,8 Bytes

Manchmal frage ich mich, ob ich mich nur mit Java verletzt habe.

Danke an @TNT und @TFeld für die 20 Bytes!

Klasse A {public static void main (String [] a) {String s = a [0] .substring (1, a [0] .indexOf ("H")); long n = Long.parseLong ((s.length ()> 0) & spplus; s: "1"); System.out.printf ("2% s +% dO & sub2;>% dH & sub2; O +% dCO & sub2;", a [0], 3 · n + 1,2 · n + 2 , 2 * n);}}

Ziemlich einfach. Grundsätzlich schneide ich die Eingabe von Cbis ab Hund erhalte diese Teilzeichenfolge. Wenn es nichts ist, setze ich nauf eins. Ansonsten setze ich es auf die Zahl zwischen Cund H. Der folgende Code druckt ihn einfach aus und bringt ihn in die richtige Schreibweise.

Ungolfed:

Klasse 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
Gute Antwort, aber Sie müssen STDIN und keine Befehlszeilenargumente verwenden. Sie können es aber auch kürzen, indem Sie printfanstelle von +(-11 aus Ihrer Rohpunktzahl, wenn ich richtig gezählt habe) verwenden.
TNT

Mir wurde gesagt, dass die Verwendung von Befehlszeilenargumenten eine akzeptable Alternative zu STDIN ist. Könnten Sie auch klarstellen, wie Sie meinen, dass ich es verwende printf? (Ein bisschen pingelig, habe es noch nie benutzt.: D)
Addison Crump

printfnutzt mechanik aus java.util.Formatter. Sie können in Ihrer print-Anweisung eine Zeichenfolge wie "% d" und anschließend einen Wert oder eine Variable angeben, die stattdessen gedruckt wird. Es kann in Situationen nützlich sein , wo Sie eine Menge von Variablen zu drucken, zum Beispiel .
TNT

Und die Tatsache, dass Befehlszeilenargumente anstelle von STDIN akzeptabel sind, ist eine neue (und ziemlich hilfreiche) Nachricht für mich. :)
TNT

1
@VoteToClose Ja, Sie verletzen sich mit 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)

3

Javascript ES6, 63 * .9 = 56,7 Byte

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

Ähnlich wie bei meiner ESMin-Antwort.


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 ist genau wie die Antwort von xnor, bei der ich die H-Werte verwende. Eine Variable J wird verwendet, um die Menge an H in der Molekülformel zu speichern.

Probieren Sie es hier aus


Sie geben sechs Bytes für den Abstand aus, erhalten aber nur fünf Bytes für den Bonus, es lohnt sich also nicht.
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 Bytes

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

Probieren Sie es online aus

Um Sonderfälle zu vermeiden CH4, verwende ich die erste Nummer überhaupt nicht und extrahiere die Nummer erst nach demH . Dies ergibt den Wert von 2n+2. Die verbleibenden Werte werden darauf basierend berechnet und formatiert.

Erläuterung:

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%Speichert ein Byte.
Dennis

2

Perl, (84 + 1) * 0,9 = 76,5

(+1 Zeichen für das Laufen mit der -nFlagge)

Mein erster Perl Golf!

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

Es ist wichtig, dass STDIN keinen abschließenden Zeilenumbruch enthält. Anwendungsbeispiel:

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

Die Linien

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

sind hier ziemlich interessant. $#xStellt den "zuletzt ausgefüllten Index" von dar @x(und SEs Syntaxhervorhebung denkt, dass es sich um einen Kommentar handelt, weil er dumm ist), $x[$#x]und wählt daher den erfassten Teil des C(\d)regulären Ausdrucks aus, falls vorhanden, oder auf 1andere Weise. (Perl ist es egal, dass es sich in allen anderen Fällen um eine Zeichenfolge handelt 1. Sie können in Perl auch numerische Operatoren für Zeichenfolgen verwenden.)


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

1

51 * .9 = 45,9 Zeichen / 64 * .9 = 57,6 Bytes

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

Try it here (Firefox only).

Erläuterung

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

Wer auch immer meine Antwort abgelehnt hat, könnte ich bitte eine Erklärung bekommen?
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"

Probieren Sie es hier aus


Sie brauchen kein Leerzeichen zwischen printund ein "Zeichen, und die CO2Variable könnte etwas kürzer benannt werden :)
undergroundmonorail

@undergroundmonorail danke
TanMath

Da i[1]es sich garantiert um "H"eine Ziffer handelt, können Sie ein weiteres Byte mit if i[1]>"9"(oder durch ein "9"beliebiges anderes Zeichen mit einem ASCII-Wert von 58 bis 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 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)

Ziemlich selbsterklärend. Nimmt eine Eingabezeichenfolge (muss in Anführungszeichen gesetzt werden, damit MATLAB nicht versucht, sie auszuführen!). Konvertiert dann die Zahl zwischen C und H in der Eingabe in eine Dezimalzahl. Der Wert 1 wird als Array an die Ausgabe von sscanf angehängt, damit in dem Fall, in dem CH4wir den ersten Index im Array extrahieren,n , eine 1 erhalten, wenn zwischen C und H keine Zahl vorhanden ist. Dann wird nur mit den Leerzeichen gedruckt nach der Formel in der Frage.

Dies sollte auch mit Octave funktionieren, wenn Sie hier den Online-Interpreter verwenden .


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

Ein bisschen mehr, als ich erwartet hatte. Liest zuerst char und verwirft es, liest dann int und gibt das Ergebnis aus. Das Problem ist, ndass ich 1 bin. Ich kann mir keinen kürzeren Weg vorstellen, es auszugeben.

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

Erzeugt eine anonyme Funktion. Versuchen Sie es , indem Sie hier und geben Sie (def f #(let...))dann (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"

Wenn wir CH4-Eingang als C1H4 nehmen könnten, kann auf 122 * 0,9 = 109,8 Bytes reduziert werden

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.