Обчисліть підказку


16

Ви з другом заходите в бар. Бармен ставиться до тебе добре, тож ти вирішиш надати йому пораду. Таким чином, ви витягуєте свій надійний кишеньковий комп'ютер і пишете швидку програму, щоб обчислити підказку для вас, оскільки в ній немає вбудованого калькулятора. Але зачекайте! Ваші операторські ключі зламані! Ваше завдання - обчислити 20-відсоткову підказку для будь-якої заданої суми введення. Тестові входи будуть у формі xx.xx, наприклад, 20.96. Ось правила:

  • Немає використання наступних операторів у математичній формі: + - * / %(Спасибі Уоллі Вест)
  • Немає використання вбудованих відсотків функцій або API
  • Немає доступу до мережі
  • Немає використання evalчи подібного
  • Немає калькулятора Windows (так люди відповіли на це раніше)
  • Немає вбудованих функцій наконечників (Не те, щоб будь-яка мова була)

Вихід має бути округлений до двох знаків після коми.

Оцінка базується на довжині в байтах.

-20%, якщо ваша програма може прийняти будь-яку суму чайових. Введення для суми буде подано у вигляді xx, наприклад 35, а не 0,35


5
@mniip: Порада - це химерна додаткова сума грошей, яку ви повинні заплатити в ресторані, який не входить до офіційної ціни. Я не знаю, чи роблять вони це в Росії.
— user2357112 підтримує Моніку

5
О, це нове покоління ... Я б скоріше використовував папір і ручку, якщо не можу подумки розділити число на 5.
— VisioN

4
@VisioN Примітка: ділення на п'ять еквівалентно діленню на 10, а помноженню на 2, і обидва повинні бути дуже легкими розумовими операціями.
— користувач12205

1
Чи може хтось уточнити правила: чи дозволяється використання заборонених операцій, якщо ви не використовуєте ці оператори? Чи дозволено множення, якщо ви не використовуєте *?
— Ypnypn

2
@TheDoctor це справді дублікат? Тому що це не додавання.
— Міло-

Відповіді:


18

Javascript 81

EDIT : Результат тепер справжнє округлення, а не усічення.

Тут не використовуйте БУДЬ-яку математику, а лише обробку рядків та побітові оператори.
Усі +символи є об'єднанням рядків або перетворенням на рядки .
Працює для будь-яких входів і виходів xx.xx у форматі (x) x.xx

s='00'+(prompt().replace('.','')<<1);(+s.replace(/(.*)(...)/,'$1.$2')).toFixed(2)

Трюк пояснив: 20% ділиться на 10 і помножується на 2.

  • Зробіть поділ на 10, перемістивши крапку вліво (маніпуляція з рядком)
  • Помножте кожну частину на 2, переміщаючи біти вліво (побізна операція)

Коли введення є 99.99, це повертається 19.998, тому воно не "округляється до двох знаків після коми", як зазначено в ОП.
— Геобіц

2
Умм, це довге рішення, але воно має 12 нагород. Що відбувається з голосуванням за кодом-гольф?
— Джастін

@Quincunx Так, ви праві, що це не популярність!
— Мукул Кумар

Оскільки це кодовий гольф, я, мабуть, не виграю, але це зовсім не означає, що людям не подобається моє рішення ... Часто переможці з кодового гольфу - це не ті, хто має найбільшу суму.
— Майкл М.

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳, абсолютно! Дякую, що вказали на це. Виправлено зараз :)
— Майкл М.

6

J (9 символів)

Коротка відповідь у J:

^.(^.2)^~ 32

1
... а я не говорю Дж. Що це говорить?
— CousinCocaine

Він говорить: обчислити 32, підняті до журналу потужності (2); Зазвичай експонент знаходиться праворуч, ^але тут ~вказується, що порядок повинен бути перетворений; (^.2)є log (.2), ​​а початковий, ^.який виконується останнім, є логарифмом всього обчисленого достеменно: таким чином log (32 ^ log (.2))
— Thomas Baruchel

4

Чистий баш, 50 43 символів

Досить впевнений, що це буде бито, але ось початок:

a=$[10#${1/.}<<1]
echo ${a%???}.${a: -3:2}

Відповідно до коментарів:

  • /тут не є оператором поділу, він є частиною розширення параметра заміни шаблону
  • % тут не є оператором модуля, це частина розширення параметра
  • - тут не оператор віднімання, це заперечення, яке було дозволено відповідно до коментарів

Вихід:

$ ./20pct.sh 0,96
.19
$ ./20pct.sh 20,96
4.19
$ ./20pct.sh 1020,96
204.19
$ 

Я думаю, що я бачу нахил вперед.
— Міло-

@Milo, що /є частиною розширення параметра bash, а не оператором поділу. Дозволено чи ні?
— Цифрова травма

1
Я б дозволю, це не математичний оператор в цьому випадку ...
— WallyWest

1
-3 діє як заперечення, а не віднімання ... @Milo, вам потрібно врахувати заперечення та інші способи, якими ці оператори можуть бути використані окрім їх математичних еквівалентів ... наприклад + можна використовувати як конкатенатор у JavaScript. .. Чи можу я зробити пропозицію? Змініть "Не використовуйте наступних операторів: + - * /%" на "Не використовуйте наступних операторів у їх математичній формі: + - * /%"
— WallyWest

2
@WallyWest Щоб грати в захисника диявола, заперечення тут все ще є математичним оператором. Можливо, "Немає використання наступних операторів у їхній неонарній математичній формі: + - * /%" ;-)
— Digital Trauma

4

Пітон 98 * 0,8 = 78,4

d=`len('X'*int("{}{:>02}".format(*(raw_input()+".0").split('.')))*2)`;print'%s.%s'%(d[:-3],d[-3:])

Python 74 (без бонусу)

d=len('X'*int(raw_input().replace('.',''))*2);print'%s.%s'%(d[:-3],d[-3:])

Примітка

  • + використовується для конкатенації рядків
  • * використовується для створення копій рядка

Безумовно

def tip():
    amount = raw_input()
    #Add an extra decimal point so that we can accept integer
    #amount
    amount += ".0"
    #Split the integer and decimal part
    whole, frac = amount.split('.')
    #Multiply amount by 100 :-)
    amount = "{}{:>02}".format(whole, frac)
    #Create amount copies of a character
    st = 'X'*amount
    #Double it
    st *= 2
    #Calculate the Length
    d = len(st)
    #Display the result as 3 decimal fraction
    print'%s.%s'%(d[:-3],d[-3:])

Примітка

В дусі питання, я вважаю, що наступне рішення, хоча дотримується всіх правил питання, - це зловживання

Пітон 41

print __import__("operator")(input(),0.2)

Нарешті

Якщо ви наполягаєте на тому, що математичні символи заборонені, це рішення на 90 символів

Python 90 (без жодного математичного символу)

print' '.join(str(int(raw_input().replace(".",""))<<1)).replace(' ','.',1).replace(' ','')

1
Як уже було сказано, *і +вони порушені KEYS (для чого б ви їх не використовували).
— Томас Баручель

2
@ ברוכאל: No use of the following in mathematical form operators: + - * / % (Thanks Wally West). Іншими словами, питання потрібно перефразувати. І я не використовував їх у математичній формі
— Абхіджіт

Гаразд, але в цьому випадку голосування рішення APL було насправді справедливим, оскільки жодне інше рішення не було скасовано з цієї причини.
— Томас Баручель

Ваша відповідь матиме проблеми з незначною сумою грошей, наприклад 0.05.
— n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Ви можете використовувати `input`(backticks включено) замість raw_input.
— nyuszika7h

4

APL (9 символів, новий код із 7 символами, зафіксований 13 символами)

Обчисліть 20% від даної суми.

{⍟⍵*⍨*.2} 32

В APL * - експоненціальний оператор.

Спробуй це Інтернеті .

Але навіщо використовувати для цього функцію? Дивіться цю нову версію:

⍟(*.2)* 32

Спробуй це Інтернеті .

Будь ласка, перед тим, як скасовувати, * не заборонено як КЛЮЧ, і це не означає множення.

Гаразд, ось версія округлення до 2 десяткових знаків (Dyalog APL):

⎕PP←2⋄⍟(*.2)* 32.01

2
Експоненціація все ще є математичною операцією і *заборонена в будь-якій математичній формі відповідно до правил завдання.
— Тоні Елліс

Експоненціація тут не затьмарена, і інші рішення насправді використовують її, але ви маєте рацію щодо того, що *заборонено як ключовий, а не як його математичне значення.
— Томас Баручель

@ Тоні Х. Будь ласка, ви можете вилучити свій запис, оскільки, очевидно, всі коментарі в інших рішеннях, нарешті, нарешті приймають такі KEYS, доки вони не використовуються для заборонених математичних операцій у початковому списку.
— Томас Баручель

1
@ ברוכאל Я розумію, що використання зірочки будь-яким способом, що стосується математичного значення, заборонено, що включає експоненцію. Будь-яка інша відповідь, поки що використовується експонентами, є мовою, яка використовує caret ( ^) для такого оператора, або використовується функція виклику. Не існує специфікації в ОП, яка *заборонена, лише якщо вона використовується в контексті множення. Я підозрюю, що було б корисно, якби ОП вирішило це, вирішити, хто з нас неправильно трактує правила виклику, та усунути плутанину.
— Тоні Елліс

1
Можливо, ×і ÷вони дозволені, ті не вказані.
— marinus

4

R, 30 27 36 34

Оновлено до круглих знаків до 2 знаків після коми

Збережено 2 символи завдяки планнапусу

Створює вектор від 0 до х і займає 2-й елемент.

a=function(x)round(seq(0,x,l=6)[2],2)

Приклад:

> a(20.36)
[1] 4.07

Подальше пояснення:

seq(0,x,len=6)

створює вектор довжиною 6 від 0 до вхідного значення x зі значеннями між рівними відстанями.

> seq(0,5,len=6)
[1] 0 1 2 3 4 5

Перше значення - 0%, друге - 20%, третє - 40% тощо.


Чекати, що ? Будь ласка, розкажіть більше про те, як це працює для тих (як я), які не знають Р.
— Майкл М.

@Michael оновив мою відповідь, щоб пояснити код
— Rift

Ваше рішення не робить округлення.
— n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ви праві (але більшість рішень нічого не округляють). 9 додаткових символів зробили б "нормальне" округлення. Тільки округлення було б набагато складніше ...
— Ріфт

@Rift: Я перевірив декілька відповідей (переважно Python, JS та Perl, оскільки вони легко доступні), і більшість з них робить округлення. Хоча жоден із тих, кого я перевірив, не обходиться.
— n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

3

DC + sed + труби (44 символи)

Моя третя відповідь (одна APL, одна J, а тепер одна зі старим і поважним DC).

dc -e 5o?p|sed -e 's/\(.\)$/.\1/'|dc -e 5i?p

Він попросить ввести INTEGER і обчислити 20% складним способом. Вхід перетворюється на базу 5 (це легко зробити з багатьма іншими інструментами, але зачекати ...); крапка додається перед останньою цифрою з sed (на жаль, dc не може дуже добре обробляти рядки), а потім, dc перетворює назад з бази 5 на число з плаваючим числом (не всі інструменти можуть це зробити).


1
"Вхід INTEGER" не відповідає специфікації. Я думаю , що ви можете це виправити, змінивши вираз патча в : dc -e 5o?p|sed 's/\(.\)\./.\1/'|dc -e 5i?p. З цим і вилученням seds -es, це 42. Але результат все ще не специфічний (не 2 знаки після коми)
— Digital Trauma

@DigitalTrauma. Ти правий. Але це рішення насправді було доволі доказом концепції, і мене більше цікавила незвичайна властивість перетворення бази в dc (а також у bc). Дякуємо за ваш коментар та виправлення в sed.
— Томас Баручель

2

Пітона, 88

Це зовсім недалеко, але це демонструє, як слід робити нормальний розумовий поділ на п'ятьох. Це передбачає, що вхід повинен мати вигляд xx.xx

import math
a,b=raw_input().split('.')
print'%.2f'%math.ldexp(float(a[0]+'.'+a[1]+b),1)

Або для введення будь-якої довжини потрібно додати 3 символи.

import math
a,b=raw_input().split('.')
print'%.2f'%math.ldexp(float(a[:-1]+'.'+a[-1]+b),1)

Пояснення: Ми приймаємо введення як рядок, після чого рухаємо десяткову точку на одне місце вперед (ділимо на 10). Потім ми кидаємо його на поплавок і використовуємоldexp функцію, щоб помножити його на 2.

Зауважте, що у цій відповіді +оператори конкатенації рядків %є і використовуються для форматуванняprint .

Якщо ви наполягаєте на тому, щоб не використовувати жодного з цих символів, ось 159 символьних рішень:

import math
a,b=raw_input().split('.')
l=[a[0]]
l.append('.')
l.append(a[1])
l.append(b)
c=str(math.ldexp(float(''.join(l)),1))
print ''.join([c[0:2],c[2:4]])

Вже сказано для багатьох інших відповідей, але я дійсно не думаю , що +і -дозволяється оскільки КЛЮЧІ зламані (то , що вони означають у вашій частині коду).
— Томас Баручель

@ ברוכאל: Дивіться мою відповідь на ваш коментар у моїй відповіді
— Абхіджіт

Використовував свою відповідь .split('.')у своїй відповіді, рубав одну
— таблицю

2

dc + sed - 45 * 0,8 = 36

(Натхненний відповіддю від ברוכאל )

  • Обробляє будь-яку кількість наконечників (цілий чи плаваючий)

Приклади виконання (введення приймається через STDIN):

$ dc -e 5o?.0+p|sed 's/\(.\)\./.\1/'|dc -e 5i?p
42
8.400
$ dc -e 5o?.0+p|sed 's/\(.\)\./.\1/'|dc -e 5i?p
20.96
4.1920

.0+Ідея велика; Я проголосував за ваше рішення, натхнене моїм, але деякі можуть сказати, що ви використовуєте додаток; можливо, якесь вирішення? Я спробував, dc -e 9k5o?v2^pале це на 2 символи більше.
— Томас Баручель

@ ברוכאל Я не усвідомлював, що + навіть у цьому контексті може кваліфікуватися як доповнення.
— devnull

@ ברוכאל Я видалю цю. Попросіть вас змінити так, щоб він міг обробляти поплавці та мати право на отримання -20%!
— devnull

2

Математика, 19

Log[(E^.2)^Input[]]

Немає використання математичних операторів +, -, *, /, або %. Для обчислення відповіді використовує властивості логарифмів; коли ви спростите вираз, ви отримаєте.2*Input[]

З бонусом ( 30 * 0,8 = 24 ):

Log[((E^.01)^Input[])^Input[]]

Спочатку введіть відсоток, потім суму.

Коли ви спростите вираз, ви отримаєте Input[]*Input[]*.01.

Дякуємо ברוכאל за допомогу зі скороченням коду.


3
Ви справді впевнені, що його не можна спростити? Мені Log[E^2]або Log[E^Input[]]можна написати коротше. Навіть 10^-1можна писати .01(хоча я не використовую Mathematica, але я впевнений, що може). Весь вираз (E^10^-1)^Log[E^2]здається чимось схожим E^.2, чи не так?
— Томас Баручель

1

TI-89 Basic - 39 * 0,8 = 31,2

Input y:Input x:Disp ln(((e^y)^.01)^x))

Працює, вводячи два числа, потім використовуючи властивості логарифму для обчислення x * y / 100.

Якщо я можу припустити вклад з розміщення в глобальних змінних, xі yце набагато коротше, для оцінки 17 * 0,8 = 13,6 :

ln(((e^y)^.01)^x)

Без бонусу ( 12 ):

ln((e^.2)^x)

Але якщо його потрібно загорнути у функцію, то це працює ( 38 символів, за 30,4 ):

:f(x,y):Func:ln(((e^y)^.01)^x):EndFunc

Будь ласка, дивіться мої коментарі до вашого іншого рішення (в Mathematica); цей код справді можна значно спростити.
— Томас Баручель

Input x,y??? Працює в 83/84.
— Timtech

@Timtech Не працює в 89, але, можливо, я можу зробити щось на кшталт Input{x,y}(чи має 83/84 ln?)
— Джастін

@Quincunx Так, дивіться мою нову відповідь.
— Тімтех

žr¹msmžr.n- безсоромний порт цього коду в 05AB1E.
— Magic Octopus Urn

1

PHP 107 * .8 = 85.6

Не можу реально працювати за кодом-гольф з PHP, але принаймні я можу працювати на струнах. приймає обидва числа як аргументи командного рядка.

<? @$r=strrev;unset($argv[0]);echo$r(substr_replace($r(str_replace('.','',array_product($argv)))),'.',2,0);

довелося перевернути його двічі, оскільки я не можу використовувати -2 :(


1

Пітон, 81 80 89 символів

a,b=map(str,raw_input().split('.'));c=str(int(a+b)<<1).zfill(4);print c[:-3]+'.'+c[-3:-1]

Пояснення

x = raw_input()       # say 20.96
a , b = x.split('.')  # a = 20 , b = 96
c = a + b             # c = '2096'      # string concatenation , multiplying by 100
d = int(c)<<1         # multiply by 2 by bitshift left , c = 4096
e = str(d).zfill(4)   # zfill pads 0's making the string 
                      # atleast 4 chars which is required 
                      # for decimal notation next

#     divide by 1000 (4) + . (4.) + fraction rounded to 2 decimals (4.09)
print        e[:-3]      +   '.'  +              e[-3:-1]

Технічно це обман, оскільки він скорочується до двох десяткових знаків, а не округлює його, але я можу стверджувати, що він кругляє вниз (краще для вас, менше чайових).


Я думаю, що ти можеш зробити [-3:]замість цього[-3:-1]
— Джастін

@Quincunx Не можу, -1 - це скорочення до двох десяткових знаків.
— користувач80551

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Так, виправити це.
— user80551

1

JavaScript 251 (примусове обмеження: немає +, -, *,? Або% будь-яким чином)

Хоча я знаю, що це не виграє, я подумав, що спробую отримати очки брауні, використовуючи дуже суворий підхід і навіть не замислюючись про те, щоб використовувати обмежені оператори в будь-якій формі або формі ... як результат, я придумав ця краса ...

A=(x,y)=>{for(;x;)b=x^y,x=(a=x&y)<<1,y=b;return y};D=(x,y,i=x,j=0)=>{for(;i>=y;)i=A(i,A(~y,1)),j=A(j,1);return j};alert(parseFloat((x="00".concat(String(D(prompt().replace(".",""),5)))).substr(0,A(x.length,y=A(~2,1))).concat(".").concat(x.substr(y))))

Я використовував побізні операції для створення функції Add A, а потім почав зв'язати звідти:

Функція поділу на цілі числа Dвикористовувала серію Негічене додавання (віднімання у формі A(x,A(~y,1)над циклом; решта - це маніпулювання рядками та конкатенація, щоб уникнути використання +операторів конкатенації ...

Цифру потрібно надати у десятковій формі з двома десятковими знаками, щоб це працювало ...


Ага, тепер буде ... хоча якщо мені доведеться дотримуватися нових правил, я повинен був би розширити його ... 251 байт зараз ...
— WallyWest

1

Perl, 50 60 байт

$_=<>;s|\.||;$_<<=1;$_="00$_";m|\d{3}$|;printf'%.2f',"$`.$&"

Вхід очікується на рівні STDIN. Він повинен містити десятковий роздільник з двома десятковими цифрами. Вихід записується в STDOUT.

Оновлення: крок $_<<=1видаляє провідні нулі. Тому m|\d{3}$|не відповідатиме рахункам <1. Тому десять байтів $_="00$додано, тепер навіть0.00 працює.

Приклади:

  • Вхід:, 20.96вихід:4.19
  • Вхід:, 12.34вихід:2.47

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

$_=<>;
s|\.||; # multiply by 100
$_ <<= 1; # multiply by 2
$_="00$_";
m|\d{3}$|; # divide by 1000
printf '%.2f'," $`.$&"

Спочатку номер читається з STDIN. Потім десяткова крапка видаляється, тобто помножується на 100. Потім сума подвоюється оператором зсуву. Потім десяткова крапка вставляється і результат друкується і округляється до двох десяткових цифр.

50 байт, якщо вексель ≥ 1:

Якщо x.xxбільше або дорівнює 1.00, то 10 байт можна видалити:

$_=<>;s|\.||;$_<<=1;m|\d{3}$|;printf'%.2f',"$`.$&"

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳: Дякую, виправлено зараз.
— Хайко Обердік

1

JavaScript (ES6) (Regex) 142

Регекс - це чудово, і він може зробити багато речей. Це навіть може робити математику!

a=('x'.repeat(prompt().replace('.', ''))+'xxxx').match(/^((x*)\2{99}(x{0,99}))\1{4}x{0,4}$/);c=a[3].length;alert(a[2].length+'.'+(c<10?'0'+c:c))

Читаема версія:

function tip(m) {
    var s = 'x'.repeat(m.replace('.', '')) + 'xxxx';
    var a = s.match(/^((x*)\2{99}(x{0,99}))\1{4}x{0,4}$/);
    var c = a[3].length;
    if (c < 10) c = '0' + c;
    return a[2].length + '.' + c;
}

tip()Функція очікує рядки аргументу, а не номер.

Всі екземпляри *, /, +які не пов'язані з математичними операціями.

  • + - це об'єднання рядків у всіх випадках, коли воно використовується.
  • * є частиною синтаксису RegExp
  • / є роздільником літералу RegExp

Вхід повинен використовуватись .як десяткова крапка, а після десяткової крапки має бути 2 цифри.

Фрагмент стека

<button onclick = "a=('x'.repeat(prompt().replace('.', ''))+'xxxx').match(/^((x*)\2{99}(x{0,99}))\1{4}x{0,4}$/);c=a[3].length;alert(a[2].length+'.'+(c<10?'0'+c:c))">Try it out</button>


0

Haskell 32 Chars -20% = 25.6 Chars

t y x=log $(^x)$(**0.01)$ exp y

Зловживає тим, що експоненти перетворюються на множення в логарифми.

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