Затраты ресурсов энергосистемы

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 каждая, а четвертая будет стоить 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
Sok
источник
Предполагаем ли мы, что входные данные являются законными, или мы должны иметь дело с такими вещами f("O",1,5)?
Катенкё
@ Katenkyo Нет, как указано в спецификации, входные данные гарантированно действительны. Проверка ошибок IMO в коде гольф утомительна, поэтому я покончил с этим: о)
Сок
Отлично, возможно, пропустил это в спецификациях. Собираюсь сделать пост для моего представления :)
Katenkyo
Я думаю, что есть некоторые ошибки в тестовых случаях. Я дважды проверил и получил f(G, 11, 4) = 22и f(O, 10, 7) = 44.
PurkkaKoodari
@ Pietu1998 Вы абсолютно правы, не знаете, как я ошибся: \ edit сейчас
Сок

Ответы:

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

демонстрация

PurkkaKoodari
источник
4

Python 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

TheBikingViking
источник
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, удалив лишнее / для разделения по полу. Поскольку это все целые числа, оно автоматически сводится к целому числу.

Strother
источник
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]. Выход является целым числом. Постараюсь в гольф больше со временем.

Попробуйте онлайн! (Ideone)

Р. Кап
источник
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

Ungolfed

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))
Katenkyo
источник
@ Pietu1998 это Lua 5.3. Я не знаю о 5.2, но в 5.3 он не будет жаловаться на них, когда они не формируют шестнадцатеричные значения. например, 6andне будет работать, потому что 6aэто шестнадцатеричное значение, но 6anэто не так.
Катенкё
8-math.floor((y-1)/3)действительно(25-y+(y-1)%3)/3
Leaky Nun