Управління запасами Minecraft


11

Управління запасами Minecraft важко. У вас 17 алмазів, але вам потрібно 7, щоб скласти чарівний стіл, кирку і меч. Ви піднімаєте їх і клацніть правою кнопкою миші 7 разів? Або клацніть правою кнопкою миші один раз і правою кнопкою миші двічі та візьміть 7 ліворуч? Це так заплутано!

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

Виклик

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

Визначення

Опис являє собою набір слотів , де ви можете зберігати предмети.

Слот є місце для зберігання в вашому інвентарі , де можна розмістити до одного типу елемента.

Стека є кількість елементів , розміщених в одній і тій же групі. Для цілей цього виклику стек - це просто купа елементів у тому самому місці (тому ігноруйте розмір стека)

Курсор Ваша загострена штуковина. Цей курсор. У ньому можуть бути предмети "на ньому"; інакше кажучи, якщо ви натиснули на слот і забрали предмети, підняті вами предмети знаходяться "на курсорі", поки ви не відкладете їх.

Технічні умови

Можливі чотири ситуації. Або у вас є елемент на курсорі, або немає, або ви клацнули лівою кнопкою миші або клацніть правою кнопкою миші.

Якщо у вас немає елемента на курсорі, і ви клацаєте лівою кнопкою миші на слоті, ви збираєте весь стек.

Якщо у вас немає елемента на курсорі і клацніть правою кнопкою миші на слоті, ви збираєте половину стека, округлюючи вгору.

Якщо у вас є елемент на курсорі і клацніть лівою кнопкою миші на слоті, ви розміщуєте всі елементи у цьому слоті. (Для всіх ваших гравців Minecraft у вас не буде> 64 предметів для цього виклику, і всі вони можуть бути складені 64 рази, і у вас є лише один тип, так що заміна предмета тут не застосовується)

Якщо у вас є елемент на курсорі і клацніть правою кнопкою миші на слоті, ви помістите один елемент у цей слот.

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

Проведемо приклад. Скажімо, ви починаєте з 17 предметів і хочете 7. По-перше, ви клацніть правою кнопкою миші на стеку, це означає, що ви зібрали 9 і в цьому слоті є 8. Потім, якщо ви знову клацніть правою кнопкою миші на стеку, ви кладете один елемент назад у слот, залишаючи вам 8, а слот - 9. Нарешті, ви знову клацніть правою кнопкою миші, і у вас є 7, а в слоті - 10. Отже, ви б повернули 3(кількість кліків).

Якщо вам вдасться перехитрити гольф на мене, скажіть, будь ласка, і я відредагую приклад: P

Випробування

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

Given, Desired -> Output
17, 7 -> 3
64, 8 -> 5
63, 8 -> 5
10, 10 -> 1
10, 0 -> 0 # note this case
25, 17 -> 7

Пояснення

Цей виклик може бути складним для гравців, які не входять у Minecraft, я не маю уявлення. Ось кілька пояснень.

64, 8 -> 5 тому що ви підбираєте 32 за допомогою клацання правою кнопкою миші, кладіть його вниз, піднімайте 16, кладіть його вниз, а потім піднімайте 8.

63, 8 -> 5 з тієї ж причини.

25, 17 -> 7 тому що ви набираєте 13, поміщаєте його вниз, вибираєте 6 із залишку 12, 2 повертаєте назад у стек, що залишився, а потім кладіть 4 у курсорі на 13, а потім вибирайте їх.

Правила

  • Застосовуються стандартні лазівки
  • Ви можете припустити, що 0 <= desired <= given <= 64
  • Ви можете приймати дані в будь-якому порядку та робити введення-виведення в будь-якому розумному форматі



2
Так що це як-державної машини , яка починається з стану 0,[n], може перейти: (1) від 0,[a,b,...]до a,[b,...], b,[a,...], ceil(a/2),[floor(a/2),b,...], або ceil(b/2),[a,floor(b/2),...]; або (2) з x,[a,b,...]( x>0) до x-1,[a+1,b,...], x-1,[a,b+1,...], x-1,[a,b,...,1], 0,[a+x,b,...], 0,[a,b+x,...], 0,[a,b,...,x]. Завдання полягає в тому, щоб знайти мінімально можливі переходи, 0,[g]звідки g задано, t,Lде tє бажана мета і чи Lє список?
Джонатан Аллан

Відповіді:


2

C ++ , 498 482 457 байт

Якщо цю функцію буде викликано один раз, вона може становити 455 байт.

Я виявив, що майже кожен онлайн-компілятор GCC (включаючи TIO) забороняє мені опускати тип функції f. Однак GCC на моєму комп’ютері дозволяє це, і я не знаю чому.

Цей може обробляти великі входи, якщо слот може містити таку кількість елементів (хоча потрібен більший масив і, ймовірно, не вистачить часу).

#import<bits/stdc++.h>
#define t N.first
#define X n.erase(n.find
#define p(c){if(c==r)return l;if(L.emplace(w={n,c},l).second)Q[U++]=w;}
#define T(S,C)n.insert(S);p(C)X(S));
using m=std::multiset<int>;using s=std::pair<m,int>;s Q[99999];int x,l,B,U;int f(int a,int r){if(!r)return 0;std::map<s,int>L;s f({a},B=0),w,N;L[Q[U=1]=f];for(;;){l=L[N=Q[B++]]+1;x=N.second;t.insert(0);for(int i:t){m n=t;X(i));if(x){T(i+x,0)T(i+1,x-1)}if(!x&&i){p(i)T(i/2,i-i/2)}}}}

Безголівки:

#include <map>
#include <set>
#include <queue>
#include <iostream>

using namespace std;

struct state {
    multiset<int> t; int q;
    bool operator<(const state& i) const { return make_pair(t, q) < make_pair(i.t, i.q); }
};

int f(int a, int target) {
    if (target == 0) return 0;

    map<state, int> len;
    queue<state> qu;
    state first = {{a}, 0};
    qu.push(first);
    len[first] = 0;

    #define push(c) { state a = {n, c}; auto t = len.insert({a, l + 1}); if (t.second) { \
        if (a.q == target) return l + 1; qu.push(a); \
    } } // push new state into queue and check for termination
    #define next(stk, cur) { n.insert(stk); push(cur); n.erase(n.find(stk)); }
    // insert new stack, push new state, erase the stack (for another use)

    while (qu.size()) { // BFS cycle
        state now = qu.front();
        qu.pop();

        int q = now.q;
        int l = len[now];

        multiset<int> n(now.t);
        for (int i : now.t) { // click on non-empty stack
            n.erase(n.find(i));
            if (!q) { // nothing on cursor
                push(i); // click left
                next(i / 2, (i + 1) / 2); // click right
            }
            else { // item on cursor
                next(i + q, 0); // click left
                next(i + 1, q - 1); // click right
            }
            n.insert(i);
        }
        if (q) { // click on empty stack
            next(q, 0); // click left
            next(1, q - 1); // click right
        }
    }
}

1

Желе , 74 байти

Ẏċ⁴¬
HĊ,$Ḟµ€1¦€F€;⁸Ḣ,$€
‘1¦€ṭ€⁹’¤
+1¦€⁹ṭ€0;ç
⁹Ȧ‘Ḥ¤ŀ
Ṫ;0ṙJ$çḢ
Wṭ0WÇ€Ẏ$ÑпL’

Повна програма з першим входом (3-й аргумент) поточного стеку та другим входом (4-й аргумент) шуканим курсором.

Спробуйте в Інтернеті! Завдяки впровадженню цей показник досягає 60 секунд часу TIO для25, 17тестового випадку. Це можна усунути, видаливши надлишки, залишені для гольфізму, використовуючи цей 84 байт (який фільтрує стеки нульового розміру і сортує ті, що залишилисяḟ€Ṣ¥0¦€0в кінці посилання 6, і зберігає лише унікальні стани на кожному кроці з використаннямQ$головного посилання).

Як?

Програма реалізує визначений стан-машина.
Він створює початковий стан, [0, [argument 1]]
потім переходить до всіх наступних можливих станів повторно,
поки не буде знайдено відповідність [argument 2, [...]].

Примітка: запис програми знаходиться на "Основному посиланні", яке є найнижчим ( Wṭ0WÇ€Ẏ$ÑпL’)

Ẏċ⁴¬ - Link 1, test a list of states for not having the desired cursor
Ẏ    - tighten by one
  ⁴  - program's fourth argument (second input) - desired cursor
 ċ   - count occurrences (the stack list will never match, so just inspecting the cursors)
   ¬ - logical negation

HĊ,$Ḟµ€1¦€F€;⁸Ḣ,$€ - Link 2, next states given a 0 cursor: list, rotatedStacks; number currentCursor (unused)
     µ€1¦€         - for each rotation of rotatedStacks apply to the first element:
H                  -   halve
   $               -   last two links as a monad
 Ċ                 -     ceiling
  ,                -     pair
    Ḟ              -   floor (vectorises) -- i.e. n -> [floor(ceil(n/2)),floor(n/2)]
                                                     = [ceil(n/2),floor(n/2)]
          F€       - flatten each -- i.e. each [[c1,f1],s2, s3,...] -> [c1,f1,s2,s3,...]
             ⁸     - chain's left argument, rotatedStacks
            ;      - concatenate -- i.e. [[c1,f1,s2,s3,...],[c2,f2,s3,...,s1],...,[s1,s2,s3,...],[s2,s3,...,s1],...]
                $€ - last two links as a monad for each:
              Ḣ    -   head
               ,   -   pair -- i.e. [c1,f1,s2,s3,...] -> [c1,[f1,s2,s3,...]]

‘1¦€ṭ€⁹’¤ - Link 3, next states given a non-0 cursor and a right-click: list, rotatedStacks; number currentCursor
 1¦€      - for each rotation of rotatedStacks apply to the first element:
‘         -   increment -- i.e. place an item into the first stack of each rotation
        ¤ - nilad followed by link(s) as a nilad:
      ⁹   -   chain's right argument -- currentCursor
       ’  -   decrement
    ṭ€    - tack each -- i.e. [s1-1,s2,s2,...] -> [currentCursor-1,[s1-1,s2,s2,...]]

+1¦€⁹ṭ€0;ç - Link 4, next states given a non-0 cursor: list, rotatedStacks; number currentCursor
 1¦€       - for each rotation of rotatedStacks apply to the first element:
    ⁹      -   chain's right argument -- currentCursor
+          -   add
     ṭ€0   - tack each to zero -- i.e. [s1+currentCursor,s2,s3,...] -> [0,[s1+currentCursor,s2,s3,...]]
         ç - call the last link (3) as a dyad -- get the right-click states
        ;  - concatenate

⁹Ȧ‘Ḥ¤ŀ - Link 5, next states: list, rotatedStacks; number currentCursor
     ŀ - call link at the given index as a dyad...
    ¤  -   nilad followed by link(s) as a nilad:
⁹      -     chain's right argument -- currentCursor
 Ȧ     -     any & all -- for our purposes zero if zero, one if not
  ‘    -     increment
   Ḥ   -     double
       - -- i.e. call link 2 if currentCursor is zero else call link 4

Ṫ;0ṙJ$çḢ - Link 6, next states: currentState  e.g. [cc, [s1, s2, s3, ...]]
Ṫ        - tail -- get the stacks, [s1, s2, s3, ...]
 ;0      - concatenate a zero - add an empty stack to the options for use
     $   - last two links as a monad for each:
    J    -   range(length)
   ṙ     -   rotate left by -- i.e. [[s2,s3,0,...,s1],[s3,0,...,s1,s2],[0,...,s1,s2,s3],[...,s1,s2,s3,0],...[s1,s2,s3,0,...]]
       Ḣ - head -- get the currentCursor, cc
      ç  - call the last link (5) as a dyad

Wṭ0WÇ€Ẏ$ÑпL’ - Main link: initialStack, requiredCursor
W             - wrap -- [initialStack]
 ṭ0           - tack to zero -- [0, [initialStack]]
   W          - wrap -- [[0, [initialStack]]]
         п   - loop while, collecting the results:
        Ñ     - ...condition: call next link (1) as a monad -- cursor not found
       $      - ...do: last two links as a monad:
    ǀ        -   call the last link (6) as a monad for each
      Ẏ       -   flatten the resulting list by one level
           L  - length
            ’ - decremented (the collect while loop keeps the input too)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.