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\$

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