Bernd ist ein Gymnasiast, der Probleme mit der Chemie hat. In der Klasse muss er chemische Gleichungen für einige Experimente entwerfen, die sie durchführen, wie zum Beispiel die Verbrennung von Heptan:
C 7 H 16 + 11 O 2 → 7 CO 2 + 8 H 2 O
Da Mathematik nicht gerade das stärkste Fach von Bernd ist, fällt es ihm oft schwer, die genauen Verhältnisse zwischen Pro- und Edukten der Reaktion zu finden. Da Sie Bernd's Tutor sind, ist es Ihre Aufgabe, ihm zu helfen! Schreiben Sie ein Programm, das die Menge jeder Substanz berechnet, die benötigt wird, um eine gültige chemische Gleichung zu erhalten.
Eingang
Die Eingabe ist eine chemische Gleichung ohne Mengen. Um dies in reinem ASCII zu ermöglichen, schreiben wir alle Abonnements als normale Zahlen. Elementnamen beginnen immer mit einem Großbuchstaben und können von einem Minuszeichen gefolgt werden. Die Moleküle werden mit +
Vorzeichen getrennt , ein ASCII-Pfeil ->
wird zwischen beide Seiten der Gleichung eingefügt:
Al+Fe2O4->Fe+Al2O3
Die Eingabe wird mit einem Zeilenumbruch abgeschlossen und enthält keine Leerzeichen. Wenn die Eingabe ungültig ist, kann Ihr Programm tun, was Sie möchten.
Sie können davon ausgehen, dass die Eingabe niemals länger als 1024 Zeichen ist. Ihr Programm kann entweder die Eingabe von der Standardeingabe, vom ersten Argument oder auf eine durch die Implementierung definierte Weise zur Laufzeit lesen, wenn beides nicht möglich ist.
Ausgabe
Die Ausgabe Ihres Programms ist die Eingabegleichung, die mit zusätzlichen Zahlen ergänzt wird. Die Anzahl der Atome für jedes Element muss auf beiden Seiten des Pfeils gleich sein. Für das obige Beispiel ist eine gültige Ausgabe:
2Al+Fe2O3->2Fe+Al2O3
Wenn die Zahl für ein Molekül 1 ist, lassen Sie es fallen. Eine Zahl muss immer eine positive ganze Zahl sein. Ihr Programm muss Zahlen liefern, deren Summe minimal ist. Zum Beispiel ist Folgendes illegal:
40Al+20Fe2O3->40Fe+20Al2O3
Wenn es keine Lösung gibt, drucken Sie
Nope!
stattdessen. Eine Beispieleingabe, die keine Lösung hat, ist
Pb->Au
Regeln
- Das ist Code-Golf. Der kürzeste Code gewinnt.
- Ihr Programm muss für alle angemessenen Eingaben in angemessener Zeit beendet werden.
Testfälle
Jeder Testfall hat zwei Zeilen: Eine Eingabe und eine korrekte Ausgabe.
C7H16+O2->CO2+H2O
C7H16+11O2->7CO2+8H2O
Al+Fe2O3->Fe+Al2O3
2Al+Fe2O3->2Fe+Al2O3
Pb->Au
Nope!
solve(
Funktion verwendet undeval(
die Eingabe interpretiert habe :)Antworten:
C 442
505ZeichenRennen wie:
Ergebnisse:
quelle
Mathematica 507
Ich habe den Ansatz der erweiterten Matrix der chemischen Zusammensetzung angewendet, der in beschrieben ist
LRThorne, Ein innovativer Ansatz zum Ausgleich chemischer Reaktionsgleichungen: eine vereinfachte Matrix - Inverse - Technik zur Bestimmung des Matrix - Nullraums. Chem.Educator , 2010, 15, 304 - 308.
Eine kleine Änderung wurde hinzugefügt: Ich habe die Transponierte des Nullraumvektors durch den größten gemeinsamen Teiler der Elemente geteilt, um in allen Lösungen ganzzahlige Werte sicherzustellen. Meine Implementierung behandelt noch nicht Fälle, in denen es mehr als eine Lösung zum Ausgleichen der Gleichung gibt.
Tests
Analyse
Es funktioniert, indem die folgende Tabelle der chemischen Zusammensetzung erstellt wird, die aus chemischen Spezies nach Elementen besteht, zu denen ein Additionsnullitätsvektor hinzugefügt wird (der zur erweiterten Tabelle der chemischen Zusammensetzung wird):
Die inneren Zellen werden als Matrix entfernt und invertiert, was ergibt.
Die Spalte ganz rechts wird extrahiert und ergibt:
Jedes Element im Vektor wird durch die gcd der Elemente (1/8) geteilt, was ergibt:
wo die negativen Werte auf der linken Seite des Pfeils platziert werden. Die absoluten Werte von diesen sind die Zahlen, die benötigt werden, um die ursprüngliche Gleichung auszugleichen:
quelle
Python, 880 Zeichen
Tests:
Ausgabe:
Könnte viel weniger als 880 sein, aber meine Augen töten mich schon ...
quelle
Python 2, 635 Bytes
Bisherige Byteanzahl: 794, 776, 774, 765, 759, 747, 735, 734, 720, 683, 658, 655, 654, 653, 651, 638, 637, 636 Bytes.
Die zweite Einrückungsstufe ist nur ein Tabulator, die dritte ein Tabulator und dann ein Leerzeichen.
Um ehrlich zu sein, das ist die Antwort von jadkik94, aber so viele Bytes wurden rasiert, dass ich es tun musste. Sag mir, ob ich alle Bytes abschneiden kann!
quelle
''.join(map(chr,range(97,122)))
map(chr,range(97,123))
für 12 Bytes gespeichert.JavaScript, 682 Bytes
Dies ist eine sehr viel bessere Antwort von Kuilin (Jahrzehnte von Charakteren!). Könnte nicht konkurrieren, da bestimmte JS-Features die Herausforderung nachträglich veröffentlichen.
quelle
Javascript, 705 Bytes
(Nicht konkurrierend, einige Features geben die Herausforderung bekannt)
Andere Lösungen hatten alle Elemente der rohen Gewalt. Ich versuchte einen deterministischeren Ansatz, indem ich die chemische Gleichung als einen Satz linearer Gleichungen darstellte und dann mit dem Gauß-Jordan-Algorithmus löste, um die reduzierte Reihen-Staffel-Form dieser Matrix anzunehmen. Um den trivialen Fall zu isolieren, bei dem alles Null ist, gehe ich davon aus, dass eines der Elemente eine konstante Zahl ist - und diese Zahl wird nur durch alle Zahlen bestimmt, die miteinander multipliziert werden, um keine Brüche zu haben. Dann werden wir als letzten Schritt jedes durch den gcd dividieren, um die letzte Bedingung zu erfüllen.
Ungolfed:
Golf gespielt
quelle