Повернутися до уроку хімії


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, так, вам не доведеться турбуватися про недійсні формули
Аднан

"послідовно використовувати пробіли" - чи буде послідовно використовувати кількість пробілів?
Мего

1
@Mego, ні. Використання пробілів взагалі не використовується пробілами, тому правило не застосовується
Adnan

Відповіді:



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.


4

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

Іноді я замислююся, чи просто я не шкода собі Java.

Дякуємо @TNT та @TFeld за гоління 20-ти байт!

клас 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);}}

Досить просто. В основному, я скорочую вхідні дані Cдо Hі отримую цю підрядку. Якщо це нічого, я встановлюю nодин. В іншому випадку я встановлю його на число між Cі H. Наступний код просто роздруковує його і ставить у відповідне позначення.

Безголівки:

клас А {
    загальнодоступна статична недійсна головна (String [] a) {
         Рядок s = a [0]. Підряд (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" у своєму операторі друку, а після нього якесь значення або змінну, яка буде надрукована замість цього. Це може бути корисно в ситуаціях, коли у вас є багато змінних для друку, наприклад .
ТНТ

І те, що замість 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)

3

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

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

Подібно до моєї відповіді ESMin.


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 використовується для зберігання кількості Н у молекулярній формулі молекули.

Спробуйте тут


Ви витрачаєте шість байтів на проміжки, але отримуєте лише п'ять байт від бонусу, тому цього не варто.
lirtosiast


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!

@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

Негольфіровані:

#!/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 * .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

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"

Спробуйте тут


Вам не потрібно простір між printі "характер, і CO2змінна може бути названий що - то коротше :)
undergroundmonorail

@undergroundmonorail дякую
TanMath

Оскільки i[1]вам гарантовано дорівнює "H"або цифра, ви можете зберегти ще один байт з if i[1]>"9"(або замінити "9"будь-який інший символ зі значенням ascii від 58 до 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 байт

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, якщо між С та 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. Я не можу придумати коротший спосіб її виведення.

Безумовно

#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 байт

#(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").


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"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.