Powrót do klasy chemii

15

Wprowadzenie

Jedną z pierwszych rzeczy, których nauczyłem się w chemii, było podanie wzoru na spalanie alkanów. Najbardziej podstawowym przykładem: 2CH4 + 4O2 > 4H2O + 2CO2. Zauważmy, że równanie można by uprościć, dzieląc każdy współczynnik przez 2, otrzymalibyśmy CH4 + 2O2 > 2H2O + CO2 . Aby to ułatwić, zignorujemy ten krok .

Widać, że przy spalaniu dowolnego alkanu wykorzystywany jest tlen. Po reakcji powstają tylko CO2 i H2O.

Zadanie:

Podaj kompletny program, który pobiera dane wejściowe ze STDIN lub najbliższego możliwego równoważnika i wysyła całkowitą reakcję za pomocą STDOUT lub najbliższego możliwego równoważnika.

Dane wejściowe zawsze będą miały postać C(n)H(2n+2), z n > 0. Oto kilka przykładowych danych wejściowych:

CH4
C2H6
C3H8
C4H10
C5H12
C6H14

etc.

Przydatna wskazówka:

Każdy alkan ma standardowy wzór w reakcji spalania:

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

na przykład

C4H10daje następujące równanie: 2C(4)H(2*4+2) + (3*4+1)O2 > (2*4+2)H2O + (2*4)CO2. Po obliczeniu wszystkiego otrzymujemy końcowe równanie:2C4H10 + 13O2 > 10H2O + 8CO2

Przykłady:

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

Zasady:

  • Musisz podać pełny program.
  • Twój program musi pobierać dane ze STDIN lub najbliższego odpowiednika, jeśli nie jest to możliwe.
  • Twój program musi generować dane wyjściowe przy użyciu STDOUT lub najbliższego odpowiednika, jeśli nie jest to możliwe.
  • Zauważ, że użyłem spacji w przykładach, aby zwiększyć czytelność, nie są one konieczne . 2CH4 + 4O2 > 4H2O + 2CO2i 2CH4+4O2>4H2O+2CO2oba są prawidłowymi danymi wyjściowymi. Jeśli jednak konsekwentnie używasz spacji na wyjściu, zyskujesz premię -10%
  • To jest , więc wygrywa program z najmniejszą liczbą bajtów!
Adnan
źródło
zupełnie inne, ale powiązane: Rysowanie struktur Lewisa alkanów
nie to, że Charles
Możemy więc założyć, że dane wejściowe będą prawidłowe formuły?
TanMath,
@TanMath, tak, nie musisz się martwić o nieprawidłowe formuły
Adnan
„konsekwentnie używaj spacji” - czy konsekwentnie użyjesz 0 spacji?
Mego,
1
@Mego, no. Używanie 0 spacji wcale nie używa spacji, więc reguła nie ma zastosowania
Adnan

Odpowiedzi:

7

Python 3, 86 * 0,9 = 77,4 bajtów

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

Wyodrębnia liczbę danych wejściowych Hzamiast liczby C. Zapobiega to specjalnemu umieszczaniu CH4i upraszcza wyrażenia wyjściowe pod względemN=2n+2 .

Dane wyjściowe mają parametry podłączone za pomocą formatowania łańcucha. Pierwszy summand jest tylko ciągiem wejściowym, a reszta ma podłączone liczby obliczeniowe. Zauważ, że N*1.5-2(tak samo jak N*3/2-2) daje liczbę zmiennoprzecinkową, ale formatowanie łańcucha przekształca go w liczbę całkowitą.

xnor
źródło
4

Java, 0,9 * 202 = 181,8 bajtów

Czasami zastanawiam się, czy po prostu krzywdzę się Javą.

Dzięki @TNT i @TFeld za wygaszenie dobrych 20 bajtów!

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

Dość proste. Zasadniczo odcinam dane wejściowe od Cdo Hi otrzymuję ten podciąg. Jeśli to nic, wybrałem njeden. W przeciwnym razie ustawię go na liczbę pomiędzy Ci H. Poniższy kod po prostu drukuje go i umieszcza we właściwej notacji.

Nie golfowany:

klasa A{
    public static void main (String [] a) {
         Ciąg 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
źródło
2
Dobra odpowiedź, ale musisz użyć STDIN, a nie argumentów wiersza poleceń. Chociaż możesz go skrócić, używając printfzamiast +(-11 z surowego wyniku, jeśli poprawnie policzyłem).
TNT
Powiedziano mi, że użycie argumentów wiersza poleceń jest akceptowalną alternatywą dla STDIN. Czy możesz również wyjaśnić, co masz na myśli dla mnie, aby użyć printf? (Trochę wybredny, nie używał tego wcześniej.: D)
Addison Crump
printfużywa mechaniki z java.util.Formatter. Możesz mieć ciąg do wydrukowania, taki jak „% d” w instrukcji print, a po nim pewną wartość lub zmienną, która zostanie wydrukowana. Może to być przydatne w sytuacjach, gdy masz dużo zmiennych do drukowania, na przykład .
TNT
A fakt, że argumenty wiersza poleceń są dopuszczalne zamiast STDIN, to dla mnie nowa (i raczej pomocna) wiadomość. :)
TNT
1
@VoteToClose Tak, ranisz się w Javie.
Kritixi Lithos
4

Python 2, 122 91 * 0,9 = 81,9 bajtów

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
źródło
3

JavaScript ES6, 63 * .9 = 56,7 bajtów

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

Podobne do mojej odpowiedzi ESMin.

Mama Fun Roll
źródło
3

Pyth, 69 bajtów * 0,9 = 62 63 * 0,9 = 57 56 * 0,9 = 50 53 * 0,9 = 48 bajtów

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

To jest tak jak z odpowiedzią xnor, gdzie używam wartości H. Zmienna J służy do przechowywania ilości H we wzorze cząsteczkowym cząsteczki.

Wypróbuj tutaj

TanMath
źródło
Wydajesz sześć bajtów na odstępy, ale zyskujesz tylko pięć bajtów z premii, więc nie warto.
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`
Dendrobium
źródło
2

CJam, 45 44 bajtów

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

Wypróbuj online

Aby uniknąć specjalnej obudowy CH4, nie używam w ogóle pierwszej liczby, a tylko ją wypisuję poH . Daje to wartość 2n+2. Na tej podstawie obliczane są pozostałe wartości i formatowane.

Wyjaśnienie:

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
źródło
2r_[[~]W=_2/(3*)\_2-]"+%dO2>%dH2O+%dCO2"e%zapisuje bajt.
Dennis
2

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

(+1 znak za bieganie z -nflagą)

Mój pierwszy golf Perl!

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

Ważne jest, aby STDIN nie zawierał nowej linii końcowej. Przykładowe użycie:

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

Niegolfowane:

#!/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";

Linie

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

są tutaj dość interesujące. $#xreprezentuje „ostatni wypełniony indeks” @x(a wyróżnianie składni SE uważa, że ​​jest to komentarz, ponieważ jest głupi), więc $x[$#x]wybierze przechwyconą część C(\d)wyrażenia regularnego, jeśli istnieje, lub w 1inny sposób. (Perl nie dba o to, że będzie to ciąg znaków we wszystkich innych przypadkach, z wyjątkiem 1; w Perlu możesz używać operatorów numerycznych.)

Klamka
źródło
1

JS, 118 (106) bajtów

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");
Łodzik
źródło
1

𝔼𝕊𝕄𝕚𝕟, 51 * .9 = 45,9 znaków / 64 * .9 = 57,6 bajtów

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

Try it here (Firefox only).

Wyjaśnienie

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
źródło
Ktokolwiek głosował za moją odpowiedzią, czy mógłbym otrzymać wyjaśnienie?
Mama Fun Roll
1

Python, 0,9 * 195 = 175 0,9 * 190 = 171 0,9 * 148 = 133 bajty

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"

Wypróbuj tutaj

TanMath
źródło
Nie trzeba przestrzeń pomiędzy printi "charakter, a CO2zmienna może być nazwany coś krótszego :)
undergroundmonorail
@undergroundmonorail dzięki
TanMath
Ponieważ i[1]gwarantowana jest jedna "H"lub cyfra, możesz zapisać kolejny bajt za pomocą if i[1]>"9"(lub zastąpić "9"dowolnym innym znakiem o wartości ascii od 58 do 71)
metro
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
źródło
1

MATLAB, 96 * 0,9 = 86,4 bajtów

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)

Dość oczywiste. Pobiera ciąg wejściowy (trzeba zawinąć go w cudzysłów, aby MATLAB nie próbował go wykonać!). Następnie konwertuje liczbę między C i H na wejściu na dziesiętne. Wartość 1 jest dołączana jako tablica do danych wyjściowych sscanf, dzięki czemu w przypadku, CH4gdy wyodrębniamy pierwszy indeks z tablicy don , otrzymujemy 1, jeśli między C i H. nie było liczby, a następnie drukujemy ze spacjami zgodnie ze wzorem w pytaniu.

Powinno to również działać z Octave przy użyciu internetowego tłumacza tutaj .

Tom Carpenter
źródło
1

C ++, 160 * 0,9 = 144 bajtów

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

Trochę więcej, niż się spodziewałem. Odczytuje pierwszy znak i odrzuca go, a następnie odczytuje liczbę całkowitą i wyświetla wynik. Problem jest zn byciu 1. Nie mogę wymyślić krótszego sposobu, aby go wydrukować.

Nie golfił

#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
źródło
1

Clojure / ClojureScript, 98 * 0,9 = 88,2 bajtów

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

Tworzy anonimową funkcję. Wypróbuj go, przechodząc tutaj i wprowadzania (def f #(let...)), a następnie (f "C3H8").

MattPutnam
źródło
1

Excel, 123 * 0,9 = 110,7 bajtów

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

Gdybyśmy mogli przyjąć wejście CH4 jako C1H4, można je zmniejszyć do 122 * 0,9 = 109,8 bajtów

="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
źródło
0

Galaretka , 33 bajty

ṣ”HṪVµ2³”+2⁸_©+H“O2>”⁸“H2O+”®“CO2

Wypróbuj online!

Bonus tu nie pomaga.

Erik the Outgolfer
źródło