Прибуток в магазині іграшок


15

Історія

"2016 рік? Все добре", - бурчав продавець іграшок Гільберт. Він розплющив очі, витер соломку з вуха, витріщивши з вуха і з’їв ранковий ударний крем. Зразкові свята. Йому зараз потрібно ходити на роботу і закінчити бухгалтерію.

Різдво - це дуже урожайний період року, особливо для його продажу. Гільберт точно знає, як це працює: людина заходить у магазин і купує перший подарунок, який їм пропонують. Вони платять за це і біжать в інший магазин. На практиці те, що насправді подарунок, насправді не має значення. Ціна також не має значення, за умови, що вона не надто висока. Все залежить від часу, що залишився до Різдва - чим коротший час, тим більші розкаяння клієнтів, тим більша ціна, яку вони готові платити.

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

Тим не менше, Гільберт хотів би знати, наскільки б його бізнес процвітав, якби він насправді використовував свою грандіозну схему. Йому вдалося скласти список людей, які прийшли до його магазину, проте він не впевнений, скільки грошей він міг заробити на них.

Ваше завдання (TL; DR)

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

Для кожного замовника знайдіть найдорожчий подарунок, який вони готові заплатити, і виведіть його за ціною. Якщо подарунків у межах бюджету немає, виведіть a 0.

Ви отримуєте -40%бонус символів, якщо асимптотична складність вашого алгоритму є O(n+m)(а не тривіальною O(n*m)) Де n, mдовжини списків введення.

Це , виграє найкоротші байти. Стандартні лазівки заборонені.

Приклад

Вхід:

1 2 2 2 5 7 10 20
1 1 2 3 6 6 15 21 21 22

Вихід:

1 0 2 2 5 2 10 20 7 0

Це завдання було взято з місцевого конкурсу програмування, і я переклав англійською мовою. Ось оригінальне завдання: https://www.ksp.sk/ulohy/zadania/1131/


9
Бонуси - одне, чого слід уникати під час написання викликів . Однак я думаю, що це може бути добре. Якщо ви хочете зберегти його, рекомендую змінити його на бонус у відсотках. Бонус на 20 символів нічого не означає для подання Java, але в основному є обов'язковим для рішень на мові для гольфу.
Денкер

Чи можу я вручити винагороду за ОП за поодинці? Чесно кажучи, це змусило мене посміхнутися; кожен виклик потребує одного з таких.
кіт

@tac Спасибі, але, як зазначається в невеликому тексті внизу, я насправді не складав попередню історію - я лише переклав її.
саммко

@sammko так, я це бачив, але мій вище коментар все ще тримається :)
кіт

Відповіді:


5

Pyth, 17 16 байт

1 байт завдяки Pietu1998

VE=.-Q]
e|fgNTQ0

Демонстрація

Пояснення:

VE=.-Q]<\n>e|fgNTQ0
                        Implicit: Q is the list of prices.
VE                      For N in the list of budgets
             f   Q      Filter the list of prices
              gNT       On the current person's budget being >= that price
            |     0     If there aren't any, use 0 instead.
          e             Take the last (most expensive) value.
      <\n>              Print it out.
  =.-Q                  Remove it from the list of prices.

Я думаю, ви можете зберегти 1 байт за допомогою VE=.-Q]\ n e|fgNTQ0. В основному те саме, але з петлею.
PurkkaKoodari

4

Haskell, 67 байт

a#(b:c)|(h,t)<-span(<=b)a=last(0:h):(init(h++[0|h==[]])++t)#c
_#x=x

Приклад використання: [1,2,2,2,5,7,10,20] # [1,1,2,3,6,6,15,21,21,22]-> [1,0,2,2,5,2,10,20,7,0].

Розділіть ціни на дві частини: (h,t)де hвсі ціни <= бюджет наступного клієнта і tчи всі інші. Візьміть останню ціну hта продовжуйте рекурсивно з усіма, крім останнього hплюсу tта решти бюджетів. last(0:h)оцінює, 0чи hпорожній. Аналогічно: init (h++[0|h==[]]) ++ tдодає елемент манекена 0до параметра hif, якщо hвін порожній, так що initє що відпустити ( initне вдається в порожньому списку).


3

Java, 154 * 0,6 = 92,4 байт

-13 байт, тому що лямбда може реально використовувати int[], а не Integer[](спасибі BunjiquoBianco )

Це повинно зайняти час O (n + m) та додатковий простір O (n + m) (якщо я розумію великі позначення O) .

g->b->{int l=g.length,L=b.length,G=0,B=0,A=0;int[]a=new int[l],s=new int[L];for(;B<L;){while(G<l&&g[G]<=b[B])a[A++]=g[G++];s[B++]=A>0?a[--A]:0;}return s;}

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

static int[] toyStore(int[]g,int[]b) {
    int gl=g.length,bl=b.length,gp=0,bp=0,ap=0;
    int[] a=new int[gl],s=new int[bl];
    for (;bp<bl;) {
        while(gp<gl&&g[gp]<=b[bp])a[ap++]=g[gp++];
        s[bp++]=ap>0?a[--ap]:0;
    }
    return s;
}

public static void main(String[] args)
{
    System.out.println(Arrays.toString(
        toyStore(new int[] {1,2,2,2,5,7,10,20},
                 new int[] {1,1,2,3,6,6,15,21,21,22})
        ));
}

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

Пояснення:

Використовувані змінні:

  • gце перелік цін на подарунки, bце список бюджетів.
  • gl- це довжина gі blє довжина b.
  • aє стеком доступних подарунків, sце вихідний масив проданих подарунків.
  • gp, bpІ apє покажчиками для g, bі aвідповідно. bpтакож вказівник для s.

Алгоритм:

  • Для кожного бюджету за тривалістю бюджетів
    • Хоча цей бюджет можна придбати подарунок за адресою g[gp]
      • Висуньте бюджет на стек aта прирістgp
    • Поп верх aв , s[bp]якщо вона існує, то ще покласти 0.

Хіба ти не зможеш прирікати лямбда? (тобто (g,b)->до g->b->?
лише ASCII

@ хтось, мабуть, так. Чомусь це ніколи раніше не працювало для мене, але зараз воно буде. 0.o (Ви заощадили 0,6 байт після бонусу.)
CAD97

Ви можете зберегти кілька байтів, використовуючи longs, якщо вхід вважається довгим [] (відводить вас до 158 байт) - ideone.com/invHlc
BunjiquoBianco

1
@BunjiquoBianco насправді я можу просто використовувати int []. Чомусь у мене було враження, що оскільки аргументи типу приймають типи посилань (таким чином, не типові примітиви типу int), мені потрібно було використовувати масив посилальних типів. Але я можу добре використовувати масив int. Я оновлюсь, коли отримаю можливість.
CAD97

@ CAD97 Га! Не можу повірити, що я не зробив це посилання ...
BunjiquoBianco

2

Haskell, 87 * 0,6 = 52,2 байти

g s(p:q)d@(b:c)|p<=b=g(p:s)q d
g[]p(b:c)=0:g[]p c
g(s:t)p(b:c)=s:g t p c
g _ _ _=[]
g[]

Цілком відрізняється від моєї іншої відповіді , бо я йду на бонус.

Останній рядок (-> g[]) не є частиною визначення, а називає накладні. Приклад використання: g [] [1,2,2,2,5,7,10,20] [1,1,2,3,6,6,15,21,21,22]-> [1,0,2,2,5,2,10,20,7,0].

Працює в основному так само, як і відповідь @ CAD97 , тобто використовує (спочатку порожній) помічник стека для відстеження елементів, що купуються. Детально: перевірити по порядку:

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

Це працює в m+nчасі, оскільки а) для операцій над стеком помічників використовується постійний час і б) в кожному з рекурсивних викликів один із списків скорочується на один елемент.


2

Желе , 15 байт

ṀṄ;©®œ^
Rf@€ç/Ṁ

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

Як це працює

ṀṄ;©®œ^  Helper link. Arguments: G, H (lists of affordable gifts)

Ṁ        Compute the maximum of G (0 if the list is empty).
 Ṅ       Print it.
  ; ®    Concatenate it with the register (initially 0).
   ©     Save the result in the register.
     œ^  Compute the multiset symmetric difference of the updated register and H.

Rf@€ç/Ṁ  Main link. Arguments: B (budgets), P (prices)

R        Range; replace each t in B with [1, ..., t].
 f@€     Intersect the list of prices with each budget range, obtaining, for each
         customer, the list of all gifts he's willing to pay for.
    ç/   Reduce the array of lists by the helper link.
         In each iteration, this computes and prints the most expensive gift for
         a customer, than removes the selected gift (and all previously
         selected gifts) from the next list.
      Ṁ  Compute the maximum of the resulting list, which corresponds to the last
         customer.

1

JavaScript, 85 * 0,6 = 51 байт

f=(a,b,s=[],[t,...u]=a,[v,...w]=b)=>v?t<=v?f(u,b,[...s,t]):[s.pop()|0,...f(a),w,s)]:[]

Ще один клон відповіді @ CAD97.

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