我的世界库存管理


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

说明

对于非《我的世界》玩家来说,这一挑战可能很棘手,我不知道。这里有一些解释。

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>0x-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列表中的最小可能过渡。
乔纳森·艾伦

Answers:


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’

一个完整的程序,其中第一个输入(第三个参数)是当前堆栈,第二个输入(第四个参数)是所需的游标。

在线尝试!由于实施,这导致25, 17测试用例的TIO超时达到60秒。这可以通过以下方法来解决:使用此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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.