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


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.