CSI: Minecraft Items

22

3

Minecraft 1.12 will be released tomorrow, so let's celebrate!

Write code that takes in a non-negative integer N which represents the number of items of something in Minecraft. Output it in a way more helpful to players, giving the number of chests, stacks, and items N is equivalent to. Use the format

XcYsZi

where

  • X is the number of chests you can completely fill with N items,
  • Y is the number of stacks you can fill with the items remaining after filling chests,
  • Z if the number of items remaining after filling chests and stacks.

Note that:

  • 64 items fit in a stack. (We'll ignore items that stack to 16 or don't stack.)
  • 27 stacks fit in a chest. (These are single chests, not double chests.)

So it would never make sense if Y is more than 26 or if Z is more than 63.

A caveat with the format is that if there is zero of something, that term is not printed.

  • So, for example, if Y were zero and X and Z nonzero, the format would look like XcZi.

  • Likewise if Y and Z were zero and X nonzero, the format would be Xc.

  • The exception here is when N is zero. Then 0i is the output rather than an empty string.

You can assume all N items are of the same type, hence all stackable.

You may not output a list or tuple of three numbers. You must give a string with the exact "csi" notation, in that order, with no spaces or commas.

For reference, here's a chest completely filled with stacks of items:

Minecraft single chest filled with 27 stacks of diamonds

Testcases

in -> out
0 -> 0i
1 -> 1i
2 -> 2i
62 -> 62i
63 -> 63i
64 -> 1s
65 -> 1s1i
66 -> 1s2i
127 -> 1s63i
128 -> 2s
129 -> 2s1i
200 -> 3s8i
512 -> 8s
1337 -> 20s57i
1664 -> 26s
1727 -> 26s63i
1728 -> 1c
1729 -> 1c1i
1791 -> 1c63i
1792 -> 1c1s
1793 -> 1c1s1i
4096 -> 2c10s
5183 -> 2c26s63i
5184 -> 3c
5200 -> 3c16i
9999 -> 5c21s15i
385026 -> 222c22s2i
1000000000 -> 578703c19s

The shortest code in bytes wins.

Calvin's Hobbies

Posted 2017-06-07T06:17:57.047

Reputation: 84 000

1Related – Leaky Nun – 2017-06-07T06:18:41.560

33ok apparently this is a crime scene investigation – Okx – 2017-06-07T06:30:16.910

1Related. – Martin Ender – 2017-06-07T06:39:52.570

@Okx I read the title and thought it was going to be some form of Clue/Cluedo but for minecraft. – caird coinheringaahing – 2017-06-07T15:13:00.427

@Okx with all the spinoffs that wouldn't be surprising. Now we need a challenge with drawing a chalk outline -- of a creeper perhaps – Chris H – 2017-06-08T09:01:09.903

Mulling it over now, but I don't think this challenge can be done in Minecraft. No way to concatenate the output string. Maybe I could display the result as an actual pile of chests, blocks, and items :) – BradC – 2017-06-08T21:06:15.997

Answers

11

Jelly,  26  24 bytes

d64d1¦27Fża¥“csi”Fḟ0ȯ⁾0i

A full program taking the number and printing the result.
It does seem too long to me...

Try it online! or see the test suite.

How?

updating...

d64d1¦27Fża¥“csi”Fḟ0ȯ⁾0i - Main link: number n
 64                      - literal 64
d                        - divmod (whole divisions and remainder)
      27                 - literal 27
    1¦                   - apply to index 1 (the whole division from above)
   d                     - divmod
        F                - flatten into a single list (of three items i.e. [(n/64)/27, (n/64)%27, n%64]
            “csi”        - literal ['c','s','i']
           ¥             - last two links as a dyad:
         ż               -   zip
          a              -   logical and (any 0s in the divmod result become [0,0], others become [integer, character]
                 F       - flatten (from list of three lists to one list)
                  ḟ0     - filter discard zeros
                     ⁾0i - literal ['0','i']
                    ȯ    - logical or (non-vectorising)
                         - implicit print (smashed together representation, so [578703,'c',19,'i'] prints as 578703c19i)

Jonathan Allan

Posted 2017-06-07T06:17:57.047

Reputation: 67 804

7

Retina, 49 48 41 bytes

.+
$*i
i{64}
s
s{27}
c
(.)\1*
$.&$1
^$
0i

Try it online! Includes all test cases except the last, in case it overloaded TIO. Edit: Saved 7 bytes thanks to @MartinEnder. Explanation:

.+
$*i

Convert the input number to unary using is.

i{64}
s

64 items fill one stack.

s{27}
c

27 stacks fill one chest.

(.)\1*
$.&$1

Convert any chests, stacks or remaining items to decimal, but leaving the type as a suffix.

^$
0i

If the input was zero, make the result 0i.

Neil

Posted 2017-06-07T06:17:57.047

Reputation: 95 035

Oh my is this really converting to unary then replacing? – Jonathan Allan – 2017-06-07T08:03:44.757

@JonathanAllan I've added an explanation (I didn't have time earlier sorry). (Writing the explanation gave me an opportunity to save a byte too!) – Neil – 2017-06-07T08:43:12.200

@MartinEnder Ah, I was wondering whether it would be worthwhile converting directly to i instead of 1, but I just couldn't see that simplification, thanks! – Neil – 2017-06-07T11:52:54.357

4

C#, 84 86 bytes

_=>(_/1728>0?_/1728+"c":"")+((_-=_/1728*1728)/64>0?_/64+"s":"")+(_%64>0?_%64+"i":"")

Notice the inline subtraction, didn't realize it was possible but i-- made sense so why not i-=10

Edit:

_=>_>0?(_/1728>0?_/1728+"c":"")+((_%=1728)/64>0?_/64+"s":"")+(_%64>0?_%64+"i":""):"0i"

for 0 edge case and suggestion.

LiefdeWen

Posted 2017-06-07T06:17:57.047

Reputation: 3 381

1+1. And you can change _-=_/1728*1728 to _%=1728 to golf a few bytes. – Kevin Cruijssen – 2017-06-07T10:48:14.623

Also, you forgot about the edge case 0, which should result in 0i and is currently outputting nothing. Adding a simply _>0?...:"0i" would fix this. – Kevin Cruijssen – 2017-06-07T10:55:42.270

@KevinCruijssen Ahh, thank you. – LiefdeWen – 2017-06-07T10:56:04.917

3+1 for >_> in the edited one – caird coinheringaahing – 2017-06-07T15:16:08.687

3

Python 3, 87 bytes

lambda n:g(n//1728,"c")+g(n//64%27,"s")+g(n%64,"i")or"0i"
g=lambda n,s:(str(n)+s)*(n>0)

Try it online!

Leaky Nun

Posted 2017-06-07T06:17:57.047

Reputation: 45 011

In Python 2 this could be shortened to 82 bytes, using simple division (/ instead of //) and using backtick operator instead of str(...) – Gábor Fekete – 2017-06-07T09:35:56.780

3

05AB1E, 24 bytes

1728‰`64‰)˜…csiøvyJ¬0Êi?

Try it online!

Explanation

1728‰                      # input divmod 1728 (64*27)
     `                     # split as separate with mod result on top of stack
      64‰                  # divmod 64
         )˜                # wrap stack in flattened list
           …csiø           # zip with the string "csi"
                vy         # for each
                  J        # join amount with storage-type
                   ¬0Êi    # if head != 0
                       ?   # print

Emigna

Posted 2017-06-07T06:17:57.047

Reputation: 50 798

How does it work in the 0 input case, and why does that also print a trailing newline while other inputs don't? – Jonathan Allan – 2017-06-07T08:32:12.267

@JonathanAllan: If nothing has been printed, 05AB1E implicitly prints the top of the stack at the end of execution (with newline). For-loops breaks lists apart and pushes the elements to the stack, so any item not printed will be added to the stack. At the end of the loop in the 0 case 0i will be on the top of the stack (0s and 0c will be under it) and will be printed. – Emigna – 2017-06-07T08:36:23.460

3

C, 85 87 105 110 111 112 bytes

#define a(x,y)x?printf("%d%c",x,y+99):0;
f(z){a(z/1728,0)a(z%1728/64,16)!z+a(z%64,6)}

Try it here.

The code even works properly on negative numbers. You may now owe server OP blocks!

Keyu Gan

Posted 2017-06-07T06:17:57.047

Reputation: 2 028

Functions are acceptable as standard on PPCG – Beta Decay – 2017-06-07T11:27:19.570

3

JavaScript (ES6), 77 76 bytes

n=>[n+1,1728,64,1].map((v,i,a)=>(v=n%a[--i]/v|0)?v+'csi'[i]:'').join``||'0i'

Test cases

let f =

n=>[n+1,1728,64,1].map((v,i,a)=>(v=n%a[--i]/v|0)?v+'csi'[i]:'').join``||'0i'

console.log(f(0)) // -> 0i
console.log(f(1)) // -> 1i
console.log(f(2)) // -> 2i
console.log(f(62)) // -> 62i
console.log(f(63)) // -> 63i
console.log(f(64)) // -> 1s
console.log(f(65)) // -> 1s1i
console.log(f(66)) // -> 1s2i
console.log(f(127)) // -> 1s63i
console.log(f(128)) // -> 2s
console.log(f(129)) // -> 2s1i
console.log(f(200)) // -> 3s8i
console.log(f(512)) // -> 8s
console.log(f(1337)) // -> 20s57i
console.log(f(1664)) // -> 26s
console.log(f(1727)) // -> 26s63i
console.log(f(1728)) // -> 1c
console.log(f(1729)) // -> 1c1i
console.log(f(1791)) // -> 1c63i
console.log(f(1792)) // -> 1c1s
console.log(f(1793)) // -> 1c1s1i
console.log(f(4096)) // -> 2c10s
console.log(f(5183)) // -> 2c26s63i
console.log(f(5184)) // -> 3c
console.log(f(5200)) // -> 3c16i
console.log(f(9999)) // -> 5c21s15i
console.log(f(385026)) // -> 222c22s2i
console.log(f(1000000000)) // -> 578703c19s

Arnauld

Posted 2017-06-07T06:17:57.047

Reputation: 111 334

2

Java 8, 86 bytes

i->i>0?(i/1728>0?i/1728+"c":"")+((i%=1728)/64>0?i/64+"s":"")+((i%=64)>0?i+"i":""):"0i"

Try it here.

Kevin Cruijssen

Posted 2017-06-07T06:17:57.047

Reputation: 67 575

2

CJam, 31 bytes

ri64md\27md@]"csi"]z{0=},"0i"e|

Try it online!

Explanation

ri                               e# Read an int from input.
  64md                           e# Divmod by 64, gives total #stacks, #items.
      \27md                      e# Divmod total #stacks by 27, gives #chests, #stacks.
           @                     e# Bring #items back to top.
            ]                    e# Wrap in an array: [#chests, #stacks, #items]
             "csi"               e# Push "csi".
                  ]z             e# Zip with the other array.
                    {0=},        e# Filter out subarrays where the first element is 0.
                         "0i"e|  e# Logical or with "0i". An input of 0 gives an empty array
                                 e# from the rest of the program, in that case yield "0i"
                                 e# instead.

Business Cat

Posted 2017-06-07T06:17:57.047

Reputation: 8 927

1

Batch, 347 335 283 246 234 202 199 191 189 bytes

@set/al=%1,c=%1/1728,l-=c*1728,s=l/64,l-=s*64
@set c=%c%c
@set s=%s%s
@set i=%l%i
@if %c%==0c set c=
@if %s%==0s set s=
@if %i%==0i set i=
@if %c%%s%%i%.==. set i=0i
@echo(%c%%s%%i%

stevefestl

Posted 2017-06-07T06:17:57.047

Reputation: 539

You do know you can use division and modulus in a set/a expression, don't you? – Neil – 2017-06-07T12:21:11.293

@Neil I know, I'm working as the same way right now – stevefestl – 2017-06-07T12:22:10.047

@Neil I'm just encountering an issue: if %c%==0 (set c=)else rem this codes gives me "(set is not expected" – stevefestl – 2017-06-07T12:23:47.090

Huh, that should only happen if c is empty... – Neil – 2017-06-07T12:28:06.143

@Neil turns out it was an program error. %c% was undefined xD – stevefestl – 2017-06-07T12:28:48.630

1JFTR my solution (two slightly different variations with the same length) is down to 122 bytes. – Neil – 2017-06-07T12:33:58.897

Let us continue this discussion in chat.

– stevefestl – 2017-06-07T12:35:30.343

1

JavaScript (ES6) 71 bytes

n=>[n/1728|0,(n/64|0)%27,n%64].map((a,i)=>a?a+'csi'[i]:'').join``||'0i'

Snippet:

f=
n=>[n/1728|0,(n/64|0)%27,n%64].map((a,i)=>a?a+'csi'[i]:'').join``||'0i'

console.log(f(0)) // 0i
console.log(f(1)) // 1i
console.log(f(2)) // 2i
console.log(f(62)) // 62i
console.log(f(63)) // 63i
console.log(f(64)) // 1s
console.log(f(65)) // 1s1i
console.log(f(66)) // 1s2i
console.log(f(127)) // 1s63i
console.log(f(128)) // 2s
console.log(f(129)) // 2s1i
console.log(f(200)) // 3s8i
console.log(f(512)) // 8s
console.log(f(1337)) // 20s57i
console.log(f(1664)) // 26s
console.log(f(1727)) // 26s63i
console.log(f(1728)) // 1c
console.log(f(1729)) // 1c1i
console.log(f(1791)) // 1c63i
console.log(f(1792)) // 1c1s
console.log(f(1793)) // 1c1s1i
console.log(f(4096)) // 2c10s
console.log(f(5183)) // 2c26s63i
console.log(f(5184)) // 3c
console.log(f(5200)) // 3c16i
console.log(f(9999)) // 5c21s15i
console.log(f(385026)) // 222c22s2i
console.log(f(1000000000)) // 578703c19s

Rick Hitchcock

Posted 2017-06-07T06:17:57.047

Reputation: 2 461

1

Python 2, 82 bytes

I converted Gabor Fekete's comment from above into a working example:

lambda n:g(n/1728,"c")+g(n/64%27,"s")+g(n%64,"i")or"0i"
g=lambda n,s:(`n`+s)*(n>0)

Try it online!

Andrew U Baker

Posted 2017-06-07T06:17:57.047

Reputation: 41

0

Braingolf, 71 bytes

V"isc"R#@!%>93*!*,>,>!/!*,>,$_-,>,>,/<$_<&,!?_v@R:>|!?_v@R:>|!?_v@R:>|;

Try it online!

Not at all golfy, but it works

Skidsdev

Posted 2017-06-07T06:17:57.047

Reputation: 9 656

0

PHP, 84 bytes

<?=($c=($a=$argn)/1728^0)?$c.c:"",($s=$a/64%27)?$s.s:"",($i=$a%64)||$c+$s<1?$m.i:"";

Try it online!

PHP, 93 bytes

$i-=64*$s=($i-=1728*$c=($i=$argn)/1728^0)/64^0;echo$c?$c.c:"",$s?$s.s:"",$i||$c+$s<1?$i.i:"";

Try it online!

Jörg Hülsermann

Posted 2017-06-07T06:17:57.047

Reputation: 13 026

0

Mathematica, 155 bytes

A=AppendTo;G={};P=Print;(z=Mod[t=Mod[#,1728],64];If[(x=⌊#/1728⌋)>0,A[G,{x,c}]];If[(y=⌊t/64⌋)>0,A[G,{y,s}]];If[z>0||#==0,A[G,{z,i}]];Row@Flatten@G)&

J42161217

Posted 2017-06-07T06:17:57.047

Reputation: 15 931

0

T-SQL, 139 134 139 bytes

Input is stored in column a of pre-existing table t.

SELECT IIF(a=0,'0i',REPLACE(IIF(a<1728,'',STR(a/1728)+'c')
                           +IIF(a%1728<64,'',STR(a%1728/64)+'s')
                           +IIF(a%64=0,'',STR(a%64)+'i'),' ',''))FROM t

Line breaks for readability, not counted in byte total. Tested on MS SQL Server 2012.

EDIT 1: Changed multiple REPLACE to IIF to save 5 bytes. Final REPLACE still necessary because STR annoyingly pads with spaces to 10 chars.

EDIT 2: Fixed to follow the rules by using the approved input type for SQL, values stored in a named table. This cost bytes for the FROM, also requires SELECT instead of PRINT. Recovered 2 bytes by dropping an unnecessary parens.

BradC

Posted 2017-06-07T06:17:57.047

Reputation: 6 099

0

PowerShell, 113 Bytes

param($i)("$(($c=[math]::floor($i/1728)))c","")[!$c]+("$(($s=[math]::floor(($i%1728)/64)))s","")[!$s]+"$($i%64)i"

This hits a bunch of powershell's pain points very precisely.

[math]::Floor is required for this as PS does Bankers Rounding by default.

the PS Ternary also takes up a load of bytes compared to other languages, to do a simple null coallescence ($a="This";$a?$a:"That" or "This"?:"That") we need to do (($a="This"),"That")[$a-ne$null]

then we need to use all of these twice, and also add in another set of brackets in some places due to powershell's default operation order.

colsw

Posted 2017-06-07T06:17:57.047

Reputation: 3 195

0

Python 2, 77 bytes

lambda n:''.join(`k`+c for k,c in zip([n/1728,n/64%27,n%64],'csi')if k)or'0i'

Try it online!

xnor

Posted 2017-06-07T06:17:57.047

Reputation: 115 687

0

dc, 76 bytes

?dddsf[1728/n99P]sc1728/0<c1728%ddd[64/n115P]si64/0<i[64%n105P]sy64%0<ylf0=y

Try it online!

R. Kap

Posted 2017-06-07T06:17:57.047

Reputation: 4 730