Витрати на ресурси сітки живлення


14

Витрати на ресурси сітки живлення

Вступ

У настільній грі Power Grid невід’ємною частиною гри є акт купівлі ресурсів для підживлення електростанцій. У грі використовуються чотири типи ресурсів (п'ять, якщо ви включаєте відновлювану енергію, але, очевидно, ви не можете придбати ресурси для цього). Це вугілля, нафта, сміття та уран. Ринок ресурсів виглядає приблизно так:

Ілюстрація ринку ресурсів, взята з правил

1---- | 2---- | 3---- | 4---- | 5---- | 6---- | 7---- | 8---- | 10  | 12
CCC   | CCC   | CCC   | CCC   | CCC   | CCC   | CCC   | CCC   |  U  |  U
OOO U | OOO U | OOO U | OOO U | OOO U | OOO U | OOO U | OOO U | 14  | 16
GGG   | GGG   | GGG   | GGG   | GGG   | GGG   | GGG   | GGG   |  U  |  U

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

Вугілля, олія та сміття збільшуються у вартості з однаковою швидкістю, а уран масштабується набагато швидше. Одинична одиниця витрат, що не є урановими 8 - floor((<units available> - 1) / 3). Одинична одиниця урану коштує, 13 - <units available>якщо є 5 і більше одиниць, 18 - (2 * <units available>)інакше.

Наприклад, на початку гри є всі 24 одиниці вугілля, які можна придбати. Якщо перший гравець хотів би придбати 4 одиниці вугілля, перші три одиниці коштували б по 1 кожній, а 4-й коштував 2, а загальна вартість 5. Це залишає 20 одиниць доступними. Якщо другий гравець також хотів би придбати 4 одиниці вугілля, вартість складе (2 * 2 + 2 * 3) = 10.

Змагання

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

У вашому дописі в будь-якому розумному форматі в будь-якому порядку слід приймати такі параметри:

  • Тип ресурсу - гарантовано один із [C, O, G, U].
  • Обсяг цього ресурсу, який присутній на ринку, гарантовано буде невід'ємним цілим числом. Якщо тип ресурсу не U, він не буде більшим за 24. Якщо тип ресурсу - U, він не буде більше 12.
  • Обсяг цього ресурсу, який хотів би придбати гравець - гарантовано буде невід'ємним цілим числом, яке менше або дорівнює сумі, яка вже присутня на ринку.

Вихід повинен бути вартістю запитуваних ресурсів.

Додаткові правила

  • Наведені формули мають лише ілюстративні цілі, сміливо використовуйте будь-який метод розрахунку витрат, які вам подобаються.
  • Буквені коди для різних типів ресурсів (C, O, G, U) можуть бути замінені їх малими еквівалентами. Ви також можете замінити літери для цифр у формі C=0, O=1, G=2, U=3або C=1, O=2, G=3, U=4.
  • Це , тому найменше подання в байтах буде переможцем.
  • Якщо ваше подання вимагає введення в іншому порядку або форматі, ніж зазначено в попередньому розділі, вам слід надати детальну інформацію.

Тестові справи

Формат тестового випадку:

resource type, amount in market, amount to buy
> result

Тестові приклади:

C, 24, 4
> 5

C, 20, 4
> 10

O, 3, 3
> 24

U, 1, 1
> 16

C, 1, 1
> 8

G, 0, 0
> 0

O, 10, 7
> 44

U, 12, 4
> 10

G, 11, 4
> 22

Чи вважаємо ми, що вкладення законні, чи ми повинні вирішувати такі речі f("O",1,5)?
Katenkyo

@Katenkyo Ні, як детально зазначено в специфікації, дані гарантовано є дійсними. Перевірка помилок IMO в коді гольфу - втомлива, тому я покінчив з нею: o)
Sok

Ідеально, можливо, пропустив це в специфікаціях.
Зробимо

Я думаю, що в тестових випадках є деякі помилки. Я двічі перевірив і отримав f(G, 11, 4) = 22і f(O, 10, 7) = 44.
PurkkaKoodari

@ Pietu1998 Ви абсолютно праві, не впевнені, як я помилився: \ редагування зараз
Sok

Відповіді:


3

Javascript (ES6), 71 59 байт

f=(t,m,b)=>b&&(t>2?m>4?13-m:18-m*2:9+~(~-m/3))+f(t,m-1,b-1)

Приймає type, market_amountі в buy_amountякості аргументів. typeє цілим числом між 0 і 3.

Демо


4

Пітон 3, 71 69 байт

Завдяки @xnor за -2 байти

f=lambda r,a,b:b and[8-int(~-a/3),max(18-2*a,13-a)][r>2]+f(r,a-1,b-1)

Функція, яка приймає введення через аргумент нульово-індексованого типу ресурсу r , наявної суми aта суми, яку потрібно придбати b, і повертає вартість.

Це використовує той факт, що Trueі Falseприрівнюється до1 і 0в Python, що дозволяє використовувати булеві вирази для індексації в списки.

Як це працює

f=lambda r,a,b           Function with input resource type r, amount available a and amount
                         to buy b
b and...                 Base case: return 0 if b=0
[8-int(~-a/3),...][r>2]  If not uranium, yield the unit cost 8-floor((a-1)/3)...
max(18-2*a,13-a)         ..else yield the current uranium unit cost
...f(r,a-1,b-1)          Decrement a and b, then pass to function
...+...                  Add the cost of each unit to give the total cost
:...                     Return the above

Спробуйте це на Ideone


1
Можна зробити max(18-2*a,13-a)замість [18-2*a,13-a][a>4].
xnor

3

Befunge, 142 байти

&2`#v_&&>:!#v_\:1-3/8\-v
v:&&<   ^-1\ -1p15+g15 <
v>#<v       <
! v5<
# 1:
>^g-
| 81
\ 4\
: *-
4 -1
` .p
# @^15+g15<
>:49+\-   ^
|
>:2*92*\- ^

Спробуйте тут!Вводиться як 3 цілих числа, де тип ресурсу 0,1,2,3. Вихід - ціле число.

Не маю уявлення, чи можна це краще пограти в гольф. Пробілів не так багато, але, напевно, новинки болять.


3

Python 2.7, 85 байт:

F,G,H=input();B=0;exec"B+=[[18-(2*G),13-G][G>5],8-((G-1)/3)][F!='U'];G-=1;"*H;print B

На основі відповіді Р. Капа, але ви можете поголити байт до 85, видаливши додатковий / для поділу підлоги. Оскільки це всі цілі числа, це автоматично зводиться до цілого числа.


1
Ласкаво просимо до PPCG!
FantaC

2

Python 2.7, 86 байт:

F,G,H=input();B=0;exec"B+=[[18-(2*G),13-G][G>5],8-((G-1)//3)][F!='U'];G-=1;"*H;print B

Вводить масив у форматі [resource type, units available, units to purchase] . Вихід - ціле число. Буде намагатися з часом більше займатися гольфом.

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


2

Луа, 107 101 байт

Рекурсивна функція, яку потрібно викликати f(resource,stock,buy). ресурс повинен бути числом від 0 до 3. Виведення здійснюється через повернене значення.

Дякую LeakyNun, що врятував мене на 6 байт: (25-y+(y-1)%3)/3коротший, ніж 8-math.floor((y-1)/3)на 5 байт, і дозволив мені отримати ще один байт завдяки його розміщенню.

function f(x,y,z)return z<1 and 0or(x<3 and(25-y+(y-1)%3)/3or(y<5 and 18-y*2or 13-y))+f(x,y-1,z-1)end

Безумовно

function f(x,y,z)                      -- define a function f with 3 parameters
  return z<1                           -- if we don't buy anything else
           and 0                       --   return 0
         or(                           -- else
           x<3                         --   if we're not buying Uranium
             and (25-y+(y-1)%3)/3      --     return 8-floor((stock-1)/3)                       
           or(y<5                      --   elseif there's less than 5 Uranium left
                and 18-y*2             --     return 18-stock*2
              or 13-y))                --   else return 13-stock
         +f(x,y-1,z-1)                 -- if we bought this iteration
                                       -- add f(resource,stock-1,toBuy-1) 
                                       -- to the returned value
end

Ви можете перевірити цей код в Інтернеті , скопіювавши наступний фрагмент.

function f(x,y,z)return z<1 and 0or(x<3 and(25-y+(y-1)%3)/3or(y<5 and 18-y*2or 13-y))+f(x,y-1,z-1)end
print(f(1,24,4))
print(f(2,20,4))
print(f(0,10,7))
print(f(3,1,1))
print(f(3,12,4))

@ Pietu1998 це Lua 5.3. Я не знаю про 5.2, але в 5.3 він не скаржиться на них, коли вони не формують шістнадцяткових значень. наприклад, 6andне працюватиме, оскільки 6aце шістнадцяткове значення, але 6anце не так.
Katenkyo

8-math.floor((y-1)/3)це справді(25-y+(y-1)%3)/3
Leaky Nun
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.