Manajemen Inventaris Minecraft

11

Manajemen persediaan Minecraft sulit. Anda memiliki 17 berlian, tetapi Anda perlu 7 untuk membuat meja pesona, beliung, dan pedang. Apakah Anda mengambilnya dan mengklik kanan 7 kali? Atau apakah Anda mengklik kanan sekali dan klik kanan dua kali dan mengambil 7 kiri? Sangat membingungkan!

Bagi Anda yang sekarang bingung, jangan khawatir, saya akan menjelaskan semuanya dalam sekejap

Tantangan

Mengingat ukuran tumpukan item dan jumlah yang diinginkan, tentukan jumlah klik paling sedikit untuk mendapatkan jumlah itu. Anda hanya perlu menangani hingga 64 untuk kedua input dan Anda mungkin menganggap Anda memiliki slot inventaris tak terbatas. Anda tidak dapat menggunakan trik seret untuk mendistribusikan.

Definisi

The persediaan adalah kumpulan slot di mana Anda dapat menyimpan barang-barang.

Sebuah Slot adalah ruang penyimpanan di inventaris Anda di mana Anda dapat menempatkan hingga satu jenis barang.

Sebuah tumpukan adalah jumlah item ditempatkan dalam kelompok yang sama. Untuk keperluan tantangan ini, tumpukan hanyalah sekelompok item di tempat yang sama (jadi abaikan ukuran tumpukan)

The kursor adalah thingy runcing Anda. Kursor itu. Itu dapat memiliki item "di atasnya"; dalam istilah lain, jika Anda mengklik slot dan mengambil item, item yang Anda ambil adalah "pada kursor" sampai Anda meletakkannya.

Spesifikasi

Ada empat kemungkinan situasi. Entah Anda memiliki item pada kursor atau tidak, dan Anda mengklik kiri atau mengklik kanan.

Jika Anda tidak memiliki item pada kursor Anda dan Anda mengklik kiri pada slot, Anda mengambil seluruh tumpukan.

Jika Anda tidak memiliki item pada kursor Anda dan Anda mengklik kanan slot, Anda mengambil setengah tumpukan, dibulatkan.

Jika Anda memiliki item pada kursor dan klik kiri pada slot, Anda menempatkan semua item ke dalam slot itu. (Untuk Anda semua pemain Minecraft, Anda tidak akan memiliki> 64 item untuk tantangan ini dan semuanya 64-stackable, dan Anda hanya memiliki satu jenis sehingga pertukaran item tidak berlaku di sini)

Jika Anda memiliki item pada kursor Anda dan Anda mengklik kanan slot, Anda menempatkan satu item ke slot itu.

Jadi, Anda mulai dengan semua item yang diberikan (input pertama, atau kedua; Anda dapat memilih urutan) dalam slot, dan Anda ingin menyelesaikan dengan memiliki jumlah yang diinginkan (input lain) di kursor Anda.

Mari kita jalankan melalui sebuah contoh. Katakanlah Anda mulai dengan 17 item dan Anda ingin 7. Pertama, Anda klik kanan pada tumpukan, yang berarti Anda telah mengambil 9 dan ada 8 di slot itu. Kemudian, jika Anda mengklik kanan tumpukan lagi, Anda menempatkan satu item kembali ke dalam slot, meninggalkan Anda dengan 8 dan slot dengan 9. Akhirnya, Anda klik kanan lagi dan Anda memiliki 7 dan slot memiliki 10. Jadi, Anda akan kembali 3(jumlah klik).

Jika Anda berhasil meng-klik-golf saya, tolong beri tahu saya dan saya akan mengedit contoh: P

Uji Kasus

Ini dibuat secara manual, jadi tolong beri tahu saya jika ada kesalahan. Saya melakukan manajemen inventaris melalui klik kanan jitter sehingga saya tidak memiliki pengalaman dengan manajemen inventaris yang optimal: 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

Penjelasan

Tantangan ini mungkin rumit untuk pemain non-Minecraft, saya tidak tahu. Berikut ini beberapa penjelasannya.

64, 8 -> 5 karena Anda mengambil 32 menggunakan klik kanan, letakkan, ambil 16, letakkan, lalu ambil 8.

63, 8 -> 5 untuk alasan yang sama.

25, 17 -> 7 karena Anda mengambil 13, meletakkannya, mengambil 6 dari sisa 12, menempatkan 2 kembali ke tumpukan sisa, dan kemudian menempatkan 4 di kursor ke dalam 13, dan kemudian mengambilnya.

Aturan

  • Celah standar berlaku
  • Anda mungkin menganggap itu 0 <= desired <= given <= 64
  • Anda dapat mengambil input dalam urutan apa pun dan melakukan I / O dalam format apa pun yang wajar
HyperNeutrino
sumber
1
ae-mod.info
Stephen
Terkait
AdmBorkBork
2
Jadi seperti negara-mesin yang dimulai dengan keadaan 0,[n], mungkin transisi: (1) dari 0,[a,b,...]ke a,[b,...], b,[a,...], ceil(a/2),[floor(a/2),b,...], atau ceil(b/2),[a,floor(b/2),...]; atau (2) dari x,[a,b,...]( x>0) ke 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]. Tantangannya adalah untuk menemukan transisi seminimal mungkin dari 0,[g]mana g diberikan ke t,Lmana ttarget yang diinginkan dan Lapakah ada daftar?
Jonathan Allan

Jawaban:

2

C ++ , 498 482 457 byte

Jika fungsi ini hanya dipanggil sekali, bisa 455 byte.

Saya menemukan bahwa hampir setiap kompiler GCC online (termasuk TIO) melarang saya untuk menghilangkan jenis fungsi f. Namun, GCC di komputer saya memungkinkan, dan saya tidak tahu mengapa.

Yang ini dapat menangani input besar jika slot dapat berisi jumlah item (meskipun membutuhkan array yang lebih besar dan mungkin akan kehabisan waktu).

#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)}}}}

Tidak Disatukan:

#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
        }
    }
}
Colera Su
sumber
1

Jelly , 74 byte

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

Program lengkap dengan input pertama (argumen ke-3) tumpukan saat ini dan input kedua (argumen ke-4) kursor yang diinginkan.

Cobalah online! Karena implementasinya, waktu TIO 60 detik habis untuk25, 17kasus uji. Ini dapat diatasi dengan menghapus redundansi yang tersisa untuk golf menggunakan byter 84 ini (yang menyaring tumpukan berukuran nol dan memilah yang tersisa denganḟ€Ṣ¥0¦€0di akhir tautan 6 dan hanya menyimpan status unik pada setiap langkah dengan menggunakanQ$di Main tautan).

Bagaimana?

Program mengimplementasikan mesin negara yang ditentukan.
Itu menciptakan keadaan asli [0, [argument 1]]
kemudian melangkah ke semua keadaan berikutnya yang mungkin berulang kali
sampai ditemukan yang cocok [argument 2, [...]].

Catatan: entri program ada di "Tautan utama" yang merupakan yang paling bawah ( 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)
Jonathan Allan
sumber