Вернуться на урок химии

15

Вступление

Одной из первых вещей, которые я узнал в химии, была разработка формулы для сжигания алканов. Самый простой пример был: 2CH4 + 4O2 > 4H2O + 2CO2. Обратите внимание, что уравнение можно было бы упростить, поделив каждый коэффициент на 2, мы бы получили CH4 + 2O2 > 2H2O + CO2 . Чтобы упростить ситуацию, мы будем игнорировать этот шаг .

Вы можете видеть, что при сжигании любого алкана используется кислород. После реакции получают только CO2 и H2O.

Задание:

Дайте полную программу, которая принимает входные данные из STDIN или ближайшего возможного эквивалента и выводит общую реакцию, используя STDOUT или ближайший возможный эквивалент.

Ввод всегда будет в форме C(n)H(2n+2), с n > 0. Вот некоторые примеры входных данных:

CH4
C2H6
C3H8
C4H10
C5H12
C6H14

etc.

Полезный совет:

Каждый алкан имеет стандартную схему реакции сгорания:

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

например

C4H10дает следующее уравнение: 2C(4)H(2*4+2) + (3*4+1)O2 > (2*4+2)H2O + (2*4)CO2. После расчета всего, мы получаем это окончательное уравнение:2C4H10 + 13O2 > 10H2O + 8CO2

Примеры:

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

Правила:

  • Вам необходимо предоставить полную программу.
  • Ваша программа должна принимать данные из STDIN или ближайшего аналога, если это невозможно.
  • Ваша программа должна выводить с использованием STDOUT или ближайшего аналога, если это невозможно.
  • Обратите внимание, что я использовал пробелы в примерах для повышения читабельности, они не обязательны . 2CH4 + 4O2 > 4H2O + 2CO2и 2CH4+4O2>4H2O+2CO2оба являются действительными выходами. Однако, если вы постоянно используете пробелы для вывода, вы получите бонус -10%
  • Это , поэтому выигрывает программа с наименьшим количеством байтов!
Аднан
источник
совершенно другое, но связанное: рисование структур Льюиса из Алканов
не то, что Чарльз
Таким образом, мы можем предположить, что на входе будут правильные формулы?
TanMath
@TanMath, да, вам не нужно беспокоиться о неправильных формулах
Аднан
«последовательно использовать пробелы» - будет последовательно использовать 0 пробелов?
Мего
1
@ Мего, нет. Использование 0 пробелов вообще не использует пробелы, поэтому правило не применяется
Аднан

Ответы:

7

Python 3, 86 * 0,9 = 77,4 байта

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

Извлекает число H's, а не число C' s из ввода. Это позволяет избежать использования специального регистра CH4и упрощает выходные выражения в терминах N=2n+2.

Вывод имеет параметры, подключенные через форматирование строки. Первое слагаемое является просто входной строкой, а остальные содержат вычисленные числа. Обратите внимание, что N*1.5-2(так же, как N*3/2-2) дает число с плавающей запятой, но форматирование строки преобразует его в int.

XNOR
источник
4

Java, 0,9 * 202 = 181,8 байта

Иногда я задаюсь вопросом, причиняю ли я себе боль только с помощью Java.

Спасибо @TNT и @TFeld за сокращение 20 байт!

класс A {открытый статический 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 * п);}}

Довольно просто В принципе, я разрезал входной сигнал от Cдо H, и получить эту подстроку. Если это ничего, я установил nодин. В противном случае я устанавливаю это число между Cи H. Следующий код просто распечатывает его и помещает в правильную запись.

Ungolfed:

класс А {
    public static void main (String [] a) {
         Строка 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
Хороший ответ, но вы должны использовать STDIN, а не аргументы командной строки. Хотя вы можете сократить его, используя printfвместо +(-11 от вашего необработанного счета, если я посчитал правильно).
ТНТ
Мне сказали, что использование аргументов командной строки является приемлемой альтернативой STDIN. Кроме того, не могли бы вы уточнить, как вы собираетесь использовать меня printf? (Немного привередлив в этом, раньше не использовал его.: D)
Аддисон Крамп
printfиспользует механику от java.util.Formatter. У вас может быть строка для печати, такая как «% d» в вашем операторе печати, а после нее будет напечатано некоторое значение или переменная. Это может быть полезно в ситуациях , когда у вас есть много переменных для печати, например .
TNT
И тот факт, что аргументы командной строки приемлемы вместо STDIN, является для меня новой (и довольно полезной) новостью. :)
ТНТ
1
@VoteToClose Да, вы вредите себе с помощью Java.
Kritixi Lithos
4

Python 2, 122 91 * 0,9 = 81,9 байта

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
источник
3

Javascript ES6, 63 * .9 = 56,7 байта

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

Похоже на мой ответ ESMin.

Mama Fun Roll
источник
3

Pyth, 69 байтов * 0,9 = 62 63 * 0,9 = 57 56 * 0,9 = 50 53 * 0,9 = 48 байтов

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

Это похоже на ответ xnor, где я использую значения H. Переменная J используется для хранения количества H в молекулярной формуле молекулы.

Попробуй здесь

TanMath
источник
Вы тратите шесть байтов на интервал, но получаете только пять байтов от бонуса, так что это того не стоит.
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
источник
2

CJam, 45 44 байта

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

Попробуйте онлайн

Чтобы избежать использования специального регистра CH4, я вообще не использую первое число, а извлекаю только число после H. Это дает ценность2n+2 . Остальные значения затем рассчитываются на основе этого и форматируются.

Объяснение:

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%сохраняет байт.
Деннис
2

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

(+1 символ за бег с -nфлагом)

Мой первый Perl Golf!

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

Важно, чтобы STDIN не содержал завершающий перевод строки. Пример использования:

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

Ungolfed-иш:

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

Линии

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

здесь довольно интересно $#xпредставляет «последний заполненный индекс» из @x(и подсветка синтаксиса SE думает, что это комментарий, потому что он тупой), поэтому $x[$#x]выберет захваченную часть C(\d)регулярного выражения, если он существует, или 1иначе. (Perl не волнует, что это будет строка во всех других случаях, кроме 1; вы можете использовать числовые операторы для строк просто отлично в Perl.)

Дверная ручка
источник
1

JS, 118 (106) байт

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, 51 * .9 = 45,9 символа / 64 * .9 = 57,6 байта

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

Try it here (Firefox only).

объяснение

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
источник
Кто бы ни отрицал мой ответ, могу ли я получить объяснение?
Mama Fun Roll
1

Python, 0,9 * 195 = 175, 0,9 * 190 = 171, 0,9 * 148 = 133 байта

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"

Попробуй здесь

TanMath
источник
Вам не нужно пространство между printи "характер, и CO2переменная может быть назван что - то короче :)
undergroundmonorail
@undergroundmonorail спасибо
TanMath
Поскольку i[1]гарантированно будет либо "H"цифра, либо цифра, вы можете сохранить еще один байт if i[1]>"9"(или заменить его "9"любым другим символом со значением ascii от 58 до 71)
подземный
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
источник
1

MATLAB, 96 * 0,9 = 86,4 байта

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)

Довольно понятно, Принимает входную строку (необходимо заключить ее в кавычки, чтобы MATLAB не пытался ее выполнить!). Затем преобразует число между C и H на входе в десятичное. Значение 1 добавляется как массив к выводу sscanf, так что в случае, CH4когда мы извлекаем первый индекс в массиве вn мы получаем 1, если между C и H не было числа. Затем просто печатается с пробелами следуя формуле в вопросе.

Это также должно работать с Octave, используя онлайн переводчика здесь .

Том Карпентер
источник
1

C ++, 160 * 0,9 = 144 байта

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

Чуть больше, чем я ожидал. Сначала читает char и отбрасывает его, затем читает int и выводит результат. Проблема сn чтобы быть 1. Я не могу придумать более короткий путь для его вывода.

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);
}
Zereges
источник
1

Clojure / ClojureScript, 98 * 0,9 = 88,2 байта

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

Создает анонимную функцию. Попробуйте, зайдя сюда и войдя (def f #(let...)), тогда (f "C3H8").

MattPutnam
источник
1

Excel, 123 * 0,9 = 110,7 байта

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

Если бы мы могли принять вход CH4 как C1H4, может быть уменьшен до 122 * 0,9 = 109,8 байтов

="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
источник