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\$
5
  • 1
    \$\begingroup\$ Related \$\endgroup\$
    – Leaky Nun
    Jun 7 '17 at 6:18
  • 35
    \$\begingroup\$ ok apparently this is a crime scene investigation \$\endgroup\$
    – Okx
    Jun 7 '17 at 6:30
  • 1
    \$\begingroup\$ Related. \$\endgroup\$ Jun 7 '17 at 6:39
  • \$\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
  • \$\begingroup\$ 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 :) \$\endgroup\$
    – BradC
    Jun 8 '17 at 21:06

21 Answers 21

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\$
4
  • \$\begingroup\$ Oh my is this really converting to unary then replacing? \$\endgroup\$ 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\$ 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\$

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\$
3
  • \$\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\$ 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
  • \$\begingroup\$ 1728 can be Ž6Ç now; and can be Ā. \$\endgroup\$ Feb 12 at 8:22
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\$
4
  • 1
    \$\begingroup\$ +1. And you can change _-=_/1728*1728 to _%=1728 to golf a few bytes. \$\endgroup\$ 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\$ 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\$ 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\$
1
  • \$\begingroup\$ In Python 2 this could be shortened to 82 bytes, using simple division (/ instead of //) and using backtick operator instead of str(...) \$\endgroup\$ Jun 7 '17 at 9:35
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\$
2
  • \$\begingroup\$ Functions are acceptable as standard on PPCG \$\endgroup\$
    – Beta Decay
    Jun 7 '17 at 11:27
  • \$\begingroup\$ 83 bytes \$\endgroup\$
    – ceilingcat
    Jul 10 '20 at 16:37
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\$
2
\$\begingroup\$

///, 179 bytes

/|/\/\///b/l0|d/11|x/dddd|sbxxxxxxxx/1sb|cbxxxd1/1cb|bxd/1b|d/2|2222/8|222/6|22/4|21/3|81/9|61/7|41/5|bc/gc|cb/c|bs/gs|sb/s|bi/gi|b|/g/0|mc/m|ms/m|mi/0i|m|/si/s|cs/c|ci/c/mcl0sl0i

Try it online!

Input is taken in unary 1s at the end of the program right before the i.
Ex:

.../si/s|cs/c|ci/c/mcl0sl0<--input here-->i

You can also use an x in place of 8 1s as a side affect of golfing the program. There is a wrapper for easier testing below.

Testing wrapper: Try it online!

Ungolfed: Try it online!

It does 2 divmods, one to separate into chests, stacks, and items, then again to convert to decimal. I could have it convert input from decimal as well, but I would also have to change all of the symbol names and add additional logic to keep it from breaking, so I'm not going to do that. Besides, I think unary is a recognized standard input for ///.

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

Jelly, 21 bytes

d64d1¦27FµTȯ3ịż“csi”$

Try it online!

Like Jonathan Allan's essentially-the-same answer before it, this does seem too long.

Even more essentially the same:

Jelly, 21 bytes

d64d1¦27Fż“csi”ẠƇȯ⁾0i

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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