22
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ Related \$\endgroup\$ – Leaky Nun Jun 7 '17 at 6:18
  • 33
    \$\begingroup\$ ok apparently this is a crime scene investigation \$\endgroup\$ – Okx Jun 7 '17 at 6:30
  • 1
    \$\begingroup\$ Related. \$\endgroup\$ – Martin Ender Jun 7 '17 at 6:39
  • \$\begingroup\$ @Okx I read the title and thought it was going to be some form of Clue/Cluedo but for minecraft. \$\endgroup\$ – caird coinheringaahing Jun 7 '17 at 15:13
  • \$\begingroup\$ @Okx with all the spinoffs that wouldn't be surprising. Now we need a challenge with drawing a chalk outline -- of a creeper perhaps \$\endgroup\$ – Chris H Jun 8 '17 at 9:01

19 Answers 19

11
\$\begingroup\$

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)
\$\endgroup\$
7
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Oh my is this really converting to unary then replacing? \$\endgroup\$ – Jonathan Allan Jun 7 '17 at 8:03
  • \$\begingroup\$ @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!) \$\endgroup\$ – Neil Jun 7 '17 at 8:43
  • 2
    \$\begingroup\$ You can avoid some of that $.& duplication like this: tio.run/##FYs9DsIwDIX3d46ASpGq2Ens5ARcAiEQYsjCQNmqnj21Lb9veD@/… \$\endgroup\$ – Martin Ender Jun 7 '17 at 9:43
  • \$\begingroup\$ @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! \$\endgroup\$ – Neil Jun 7 '17 at 11:52
4
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ +1. And you can change _-=_/1728*1728 to _%=1728 to golf a few bytes. \$\endgroup\$ – Kevin Cruijssen Jun 7 '17 at 10:48
  • \$\begingroup\$ 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. \$\endgroup\$ – Kevin Cruijssen Jun 7 '17 at 10:55
  • \$\begingroup\$ @KevinCruijssen Ahh, thank you. \$\endgroup\$ – LiefdeWen Jun 7 '17 at 10:56
  • 3
    \$\begingroup\$ +1 for >_> in the edited one \$\endgroup\$ – caird coinheringaahing Jun 7 '17 at 15:16
3
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ In Python 2 this could be shortened to 82 bytes, using simple division (/ instead of //) and using backtick operator instead of str(...) \$\endgroup\$ – Gábor Fekete Jun 7 '17 at 9:35
3
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ How does it work in the 0 input case, and why does that also print a trailing newline while other inputs don't? \$\endgroup\$ – Jonathan Allan Jun 7 '17 at 8:32
  • \$\begingroup\$ @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. \$\endgroup\$ – Emigna Jun 7 '17 at 8:36
3
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ Functions are acceptable as standard on PPCG \$\endgroup\$ – Beta Decay Jun 7 '17 at 11:27
3
\$\begingroup\$

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

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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%
\$\endgroup\$
  • \$\begingroup\$ You do know you can use division and modulus in a set/a expression, don't you? \$\endgroup\$ – Neil Jun 7 '17 at 12:21
  • \$\begingroup\$ @Neil I know, I'm working as the same way right now \$\endgroup\$ – stevefestl Jun 7 '17 at 12:22
  • \$\begingroup\$ @Neil I'm just encountering an issue: if %c%==0 (set c=)else rem this codes gives me "(set is not expected" \$\endgroup\$ – stevefestl Jun 7 '17 at 12:23
  • \$\begingroup\$ Huh, that should only happen if c is empty... \$\endgroup\$ – Neil Jun 7 '17 at 12:28
  • 1
    \$\begingroup\$ JFTR my solution (two slightly different variations with the same length) is down to 122 bytes. \$\endgroup\$ – Neil Jun 7 '17 at 12:33
0
\$\begingroup\$

Braingolf, 71 bytes

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

Try it online!

Not at all golfy, but it works

\$\endgroup\$
0
\$\begingroup\$

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)&
\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

dc, 76 bytes

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

Try it online!

\$\endgroup\$

protected by Steadybox Jun 8 '17 at 13:23

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.