Minecraft Inventory Management


11

Minecraftの在庫管理は困難です。17個のダイヤモンドがありますが、エンチャントテーブル、つるはし、剣を作るには7個必要です。それらを拾って右クリックを7回しますか?または、右クリックして2回、右クリックして7を左に移動しますか?とても混乱しています!

今混乱しているあなたのために、心配しないで、私はそれをすべてすぐに説明します

チャレンジ

アイテムのスタックのサイズと必要な量を考慮して、その量を得るための最小クリック数を決定します。両方の入力に対して最大64を処理するだけでよく、無限のインベントリスロットがあると仮定できます。ドラッグして配布するトリックは使用できません。

定義

在庫はあなたがアイテムを格納することができ、スロットのコレクションです。

スロットは、あなたがアイテムの1種類にまで置くことができ、あなたのインベントリ内の記憶領域です。

スタックは、同じグループ内に配置された項目の数です。この課題の目的のために、スタックは単に同じ場所にあるアイテムの集まりです(したがって、stack-sizeは無視してください)

カーソルがあなたの先のとがったブツです。そのカーソル。「その上に」アイテムを持つことができます。言い換えれば、スロットをクリックしてアイテムをピックアップした場合、ピックアップしたアイテムは、置くまで「カーソル上」にあります。

仕様書

4つの状況が考えられます。カーソルにアイテムがあるか、カーソルがないか、左クリックまたは右クリックのいずれかです。

カーソル上にアイテムがなく、スロットを左クリックすると、スタック全体が取得されます。

カーソルにアイテムがなく、スロットを右クリックすると、スタックの半分が切り上げられます。

カーソルの上にアイテムがあり、スロットを左クリックすると、すべてのアイテムがそのスロットに配置されます。(すべてのMinecraftプレイヤーは、このチャレンジで64を超えるアイテムを持たず、すべて64スタック可能です。1つのタイプしかないため、アイテムスワップはここでは適用されません)

カーソルの上にアイテムがあり、スロットを右クリックすると、そのスロットに1つのアイテムが配置されます。

そのため、スロットで指定されたすべてのアイテム(最初の入力、または2番目。順序を選択できます)で開始し、目的の量(他の入力)をカーソルに入れて終了します。

例を見てみましょう。17個のアイテムから始めて、7個のアイテムが必要だとします。最初に、スタックを右クリックします。つまり、9個をピックアップし、そのスロットに8個あります。次に、もう一度スタックを右クリックすると、1つのアイテムがスロットに戻され、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を拾い、下に置き、残りの12から6を拾い、残りのスタックに2を戻し、カーソルの4を13に置いてから拾います。

ルール

  • 標準的な抜け穴が適用されます
  • あなたはそれを仮定するかもしれません 0 <= desired <= given <= 64
  • どちらの順序で入力しても、妥当な形式でI / Oを実行できます。



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番目の引数)が現在のスタックで、2番目の入力(4番目の引数)が目的のカーソルである完全なプログラム。

オンラインでお試しください!実装のため、25, 17テストケースの60秒のTIOタイムアウトになります。これは、この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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.