Фредовий рахунок за воду


9

Фред - квазі-дружелюбний хлопець, але насправді він підлий.

Через це Фред живе один в маленькій квартирі в Лос-Альтосі, Каліфорнія. Фред настільки злий, тому що він дуже особливо стосується води. Тому він потребує вашої допомоги, щоб з'ясувати, яка його рахунок на воду.

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

Споживання води відбувається в ярусах. Це означає, що існують діапазони цін залежно від кількості води.

Це рівні, їхні ціни та кількість води, яким вони відповідають:

Tier I
   First 10 Ccf: $3.8476/Ccf
Tier II
   Next 17 Ccf: $4.0932/Ccf
Tier III
   All subsequent water: $4.9118/Ccf

За п ять сотень кубічних футів (Ccf) передбачені такі додаткові збори:

CPUC fee: 1.5% of above charges
LIRA quantity surcharge: $0.047*n
PBOP amoritization surcharge: $0.004*n

Сума плати за рівень І, ІІ рівня, ІІІ рівня, CPUC, LIRA та PBOP - загальна сума води. Цю суму вам слід повернути або надрукувати на консолі, округленій до двох знаків після коми.

Ось два приклади:

Input: 15
... Calculations which you do not need to output but here to help explain:
Tier I: 10*3.8476 = 38.476
Tier II: (15-10)*4.0932 = 20.466
Tier III: 0*4.9118 = 0
Tiers sum: 58.942
CPUC: 1.5% of 58.942 = 0.88413
LIRA: 0.047*15 = 0.705
PBOP: 0.004*15 = 0.06
Total sum: 58.942 + 0.88413 + 0.705 + 0.06 = 60.59113
...
Output: 60.59

Input: 100
... Calculations which you do not need to output but here to help explain:
Tier I: 10*3.8476 = 38.476
Tier II: 17*4.0932 = 69.5844
Tier III: (100-10-17)*4.9118 = 358.5614
Tiers sum: 466.6218
CPUC: 1.5% of  = 6.999327
LIRA: 0.047*100 = 4.7
PBOP: 0.004*100 = 0.4
Total sum: 478.721127
...
Output: 478.72

Це код гольфу, тому найкоротший код у байтах виграє!


Перевірте, чи відповідає моє редагування вашим намірам.
msh210

Так, дякую @ msh210, це набагато зрозуміліше, ніж у мене
Даніель,

Якщо ви готові марнувати репутацію на голосування, чи можете ви, принаймні, поясніть чому?
Даніель

@Dopapp Деяким людям просто не сподобається виклик. Нічого, що ти можеш там зробити. Оскільки це варте, заборона на виклики не віднімається від репутації поточного гравця - лише відповіді.
Мего

Чи потрібно обробляти не цілі числа n?
PurkkaKoodari

Відповіді:


1

Pyth, 55 41 байт

.R+s*Vv.",9t¬®Ï0NwÝ"lMcUQ,T27*.051Q2

Код містить недруковані символи, тож ось xxdшестнадцятковий.

00000000: 2e52 2b73 2a56 762e 222c 3904 1874 c2ac  .R+s*Vv.",9..t..
00000010: c2ae c280 c293 c38f 301c 4e77 c39d 226c  ........0.Nw.."l
00000020: 4d63 5551 2c54 3237 2a2e 3035 3151 32    McUQ,T27*.051Q2

Пояснення

  1. ."…"це упакований рядок, який містить 3.8476,4.0932,4.9118.
  2. vоцінює це до кортежу (3.8476, 4.0932, 4.9118). Це ціни на рівні, помножені на додану CPUC.
  3. UQгенерує діапазон 0n-1.
  4. c,T27Розбиває цей діапазон за індексами 10 і 27, з додатковими порожніми списками в кінці, якщо діапазон занадто короткий.
  5. lM знаходить довжину кожної частини, даючи кількість води для кожного ярусу.
  6. *V множиться на кортеж із кроку 2, щоб отримати ціни на рівні.
  7. s підсумовує результати.
  8. +*Q.051Додає вхід, помножений на 0,051, тобто LIRA + PBOP.
  9. .R2Округляє результат до 2 десяткових знаків.

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


2

Математика, 83 76 69 байт

1.015{3.8476,.2456(b=Boole)[#>10],.8186b[#>27],51/1015}&~Array~#~Total~2~Round~.01&

Анонімна функція, яка будує масив з трьох ярусів у першому стовпчику плюс LIRA та PBOP, представлені у вигляді довільної точності в четвертому стовпці. Вся справа множиться на, 1.015а всі елементи масиву підсумовуються та округлюються до .01. Оскільки 51/1015*1.015буде бажаним, 0.051то результат такий же точний, як і специфікація в ОП.

Коротше рішення, у 76 байт , як я запропонував у своєму коментарі під рішенням Perl

{3.956314,.249284(b=Boole)[#>10],.830879b[#>27]}&~Array~#~Total~2~Round~.01&

де 1.015враховується ціни від початку, а потім LIRA та PBOP додаються поверх першого рівня.

73 байти (але я не бажаю оновлювати свій підрахунок байтів, оскільки це досить близько до прямого рішення Perl):

69 байт - ах, чорт, гольф теж взяв певні зусилля.

.01Round[395.6314#+{24.9284,83.0879}.(UnitStep[#-1]#&/@{#-10,#-27})]&

EDIT щодо помилки з плаваючою комою
. Перші три повторення моєї відповіді дійсно точні в десятковому поданні, оскільки всі задіяні коефіцієнти мають кінцеві десяткові подання. Однак, оскільки коефіцієнти явно плавають, зберігаються у двійковій формі і мають незакінчені бінарні подання, досить великі входи почнуть накопичувати помилки в найменш значущих цифрах двійкового подання. Я б припустив, що коли поплавок настільки великий, що він підходить лише до 3-4 цифр праворуч від десяткової крапки, ми можемо очікувати помилок приблизно в 1 цент. Точну відповідь див. Нижче .

72 байти, дещо несприйнятливі до плаваючих неточностей

.01Round[{3956314,249284,830879}.(UnitStep[#-1]#&)/@(#-{0,10,27})/10^4]&

Множення на ведучі .01робиться на самому останньому кроці. До цього моменту всі обчислення робляться цілими числами. Це означає, що якщо .01пропущено, буде точний результат, але виражений у центах, а не в доларах. Звичайно, множення на поплавок перетворює всю річ на поплавок, і, як уже згадувалося, вона повинна бути достатньо маленькою, щоб вміститися в 64 біти і все ще бути точною .01.


2

05AB1E, 64 58 51 байт

0T27¹)vy¹‚ï{0è})¥•_ÄÄ™wu24@•2'.:7ô)ø€PO¹"5.1"*+ïTn/

Пояснив

0T27¹)                                               # list of price brackets
      vy¹‚ï{0è})                                     # min of each with input
                ¥                                    # calculate deltas to get amounts within each bracket
                 •_ÄÄ™wu24@•2'.:7ô                   # list of price rates with CPUC included
                                  )ø                 # zip with amounts for each rate
                                    €PO              # multiply amounts by their rates and sum
                                       ¹"5.1"*+      # add LIRA/PBOP
                                               ïTn/  # round to 2 decimals

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


1

Perl 5, 73 байти

Очевидне рішення. 72 байти, плюс 1 для -neзамість -e.

printf'%.2f',$_*3.956314+($_-10)*($_>10)*.249284+($_-27)*($_>27)*.830879

Збережено 5 байт завдяки LLlAMnYP . Дякую!


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

@LLlAMnYP, безумовно, будь-яке наближення повинно мати помилку при досить високому значенні вводу. Сподіваємось, що ця межа досить висока, що ОП не піклується (адже це нерозумна кількість води для проживання однієї людини).
msh210

@ msh210 Ви не знаєте історію Фреда !!
кіт

Ні, тому що ви множите і додаєте числа з кінцевим десятковим поданням. Звичайно, коли ви представляєте їх як поплавці, вони можуть мати не дуже велике бінарне представлення. Потім можна очікувати помилок, коли представлення поплавця допускає лише 3-4 цифри праворуч від десяткової. Моя "бонусна відповідь" внизу моєї публікації долає це, використовуючи цілі числа до останнього кроку (який конвертує центи в долари). Якби я пропустив множення на .01, воно залишалося б точним, доки ціле число можна зберігати.
LLlAMnYP

1

Oracle SQL 11.2, 151 байт

SELECT ((DECODE(SIGN(:1-10),1,10,:1)*3.8476)+(DECODE(SIGN(:1-27),1,17,:1-10)*4.0932)+(DECODE(SIGN(:1-27),-1,0,:1-27)*4.9118))*1.015+:1*0.051 FROM DUAL;

Без гольфу

SELECT ((DECODE(SIGN(:1-10),1,10,:1)*3.8476)+
       (DECODE(SIGN(:1-27),1,17,:1-10)*4.0932)+
       (DECODE(SIGN(:1-27),-1,0,:1-27)*4.9118))*1.015+
       :1*0.051
FROM DUAL

Позбудьтесь місця між SELECTі ((DECODEзбережіть один байт. Збережіть більше 10 байт за допомогою названої таблиці! 7, видаливши колонки та використовуючи одну колонку з ім'ям плюс три, використовуючи одну назву таблиці таблиці char.
Джакомо Гарабелло

@Giacomo Garabello: вилучення простору завжди повертає null з жабою та повертає помилку з SQLDeveloper. Сценарій створення таблиці додає більше 10 байт.
Jeto

вам не доведеться додавати сценарій створення ... дивіться тут
Джакомо Гарабелло

1

JavaScript ES6, 77 байт

x=>(x>27?(x-27)*4.985477+109.681:(x>10?(x-10)*4.1546+39.053:x*3.9053))+.051*x

Без гольфу

f = x => {
  if (x > 27) {
    res = (x - 27) * 4.985477 + 109.681306
  } else if (x > 10) {
    res = (x - 10) * 4.154598 + 39.05314
  } else {
    res = x * 3.905314
  }
  return res + 0.051 * x
}

Я враховував коефіцієнти LIRA та PBOP. Додаткові 1,5% додаються наприкінці.

Мабуть, не найефективніше рішення з точки зору гольфу, але дещо відрізняється від першого.

Помилка з плаваючою комою повинна виникати з більшими числами і може бути виправлена ​​шляхом додавання 1 або 2 зайвих байтів до кожного коефіцієнта.

f=x=>(x>27?(x-27)*4.985477+109.681:(x>10?(x-10)*4.1546+39.053:x*3.9053))+.051*x

console.log(f(15))
console.log(f(100))
console.log(f(200000))


Вам не потрібні місця ()навколо x>10?:, ?:асоційовані праворуч ліворуч. Я думаю , ви можете також зберегти деякі байти шляху множення поза круглих дужок , наприклад , (x-10)*4.154598+39.05314так само x*4.154598-41.54598+39.05314рівних x*4.154598-2.49284.
Ніл

1

R , 52 байти

approxfun(c(0,10,27,10^6),c(0,39.56,111.06,5036475))

Спробуйте в Інтернеті!

Породжує функцію лінійного наближення, грунтуючись на значеннях моєї попередньої відповіді на 0,10,27 та 10 ^ 6. Захоплення: верхня межа на вході - 10 ^ 6.

approxfunecdf, stepfun, splinefunі т.д.) є одним з багатьох особливостей симпатичних з R.


0

VBA, 88 байт

Function W(V):W=Round(.051*V+.203*(V*19.238-(V-10)*(V>10)*1.228-(V-27)*(V>27)*4.093),2)
 

Базова ставка та диференційовані ставки вищого використання були помножені на 5, а множник плати CPUC поділений на 5 (0,203).

Редактор VB додасть End Functionрядок, через що додається кінцева лінія каналу.


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