# Convert version string to pack_format

When making a Minecraft data/resource pack, you need to include a pack.mcmeta file, which specifies information about it. pack.mcmeta contains a description, but it also contains a pack_format number, which tells Minecraft which versions this pack is for.

Your task is to take a version string, and output what pack_format number matches the string.

Your input must be a string, and you can assume it's either 1.x or 1.x.y.

As of when this challenge was posted, the conversion goes like so:

1.6.1 - 1.8.9 -> 1
1.9 - 1.10.2 -> 2
1.11 - 1.12.2 -> 3
1.13 - 1.14.4 -> 4
1.15 - 1.16.1 -> 5
1.16.2 - 1.16.5 -> 6
1.17 -> 7


These are all the possible inputs, and what they need to be mapped to:

1.6.1 -> 1
1.6.2 -> 1
1.6.4 -> 1
1.7.2 -> 1
1.7.4 -> 1
1.7.5 -> 1
1.7.6 -> 1
1.7.7 -> 1
1.7.8 -> 1
1.7.9 -> 1
1.7.10 -> 1
1.8 -> 1
1.8.1 -> 1
1.8.2 -> 1
1.8.3 -> 1
1.8.4 -> 1
1.8.5 -> 1
1.8.6 -> 1
1.8.7 -> 1
1.8.8 -> 1
1.8.9 -> 1
1.9 -> 2
1.9.1 -> 2
1.9.2 -> 2
1.9.3 -> 2
1.9.4 -> 2
1.10 -> 2
1.10.1 -> 2
1.10.2 -> 2
1.11 -> 3
1.11.1 -> 3
1.11.2 -> 3
1.12 -> 3
1.12.1 -> 3
1.12.2 -> 3
1.13.1 -> 4
1.13.2 -> 4
1.14 -> 4
1.14.1 -> 4
1.14.2 -> 4
1.14.3 -> 4
1.14.4 -> 4
1.15 -> 5
1.15.1 -> 5
1.15.2 -> 5
1.16 -> 5
1.16.1 -> 5
1.16.2 -> 6
1.16.3 -> 6
1.16.4 -> 6
1.16.5 -> 6
1.17 -> 7


This is code golf, so the shortest answer wins. Good luck!

• Sandbox May 18 '21 at 18:00
• Are we allowed to assume a trailing zero at the end of major versions (e.g. 1.16.0 instead of 1.16)? May 18 '21 at 19:35

# JavaScript (ES6),  43  42 bytes

s=>([,x,y]=s.split.,x*x+x*3+~~y)/51^x>16


Try it online!

### How?

Given an input string 1.x.y, we compute:

$$\left\lfloor\frac{x^2+3x+y}{51}\right\rfloor$$

Because we're using ~~y, we implicitly assume $$\y=0\$$ if the input string is just 1.x.

This gives the correct result for all versions except the last one, which gives $$\6\$$ instead of $$\7\$$. This is fixed by XOR'ing with $$\1\$$ if $$\x>16\$$.

• I'm curious, how do you get these insanely precise formulae?
– user100690
May 18 '21 at 18:30
• @ophact Trying $x^2+y$ was a total guess. I noticed that $\lfloor (x^2+y)/40\rfloor$ was already surprisingly good. I then wrote a small script to fine-tune the formula. May 18 '21 at 19:06
• Wow. I guess I'll try some of that.
– user100690
May 18 '21 at 19:19

# JavaScript (ES7), 31 bytes

s=>s.slice(2)**2/45+.2|s[3]%1.2


Try it online!

TIO setup is based on Arnauld's answer.

Ignore the 1. part and treat the input as a floating point number. For example, 1.16.1 becomes 16.1. This formula (find out by some brute force search) works quite good (48/52 correctness).

$$\left\lfloor\frac{s^2}{45}+0.2\right\rfloor$$

And with some manually fix... It finally works.

So if you are interesting in how it works: I don't know why it work either.

# Excel, 46 44 bytes

-2 bytes change first item from 6.1 to 0

=MATCH(MID(A1,3,9)*1,{0,9,11,13,15,16.2,17})


Since they are all 1.x or 1.x.y, this basically matches everything from the 3rd character on.

• Do you need the trailing })? May 20 '21 at 5:01
• I need the } for sure. If I leave the ) off, Excel will add it. I went ahead and counted it. May 20 '21 at 11:36

# Jelly, 16 bytes

ṫ3V×⁵>“Ym²Ɱƙʋ‘S‘


Try it online!

ṫ3V×⁵>“Zn³Ɲɱȥ‘S‘   Main Link; take the string as required
ṫ3                 Remove the first two characters
V                Eval it
×⁵              Multiply it by 10
>“Zn³Ɲɱȥ‘     Compare (>) to each of [89, 109, 130, 149, 161, 169]
S    Sum
‘   Increment


# Japt, 18 bytes

Port of hyper-neutrino's solution so be sure to upvote them too.

Ò"Ym¡©"¬mc x<¢*A


Try it (Includes all test cases)

Ò"..."¬mc x<¢*A     :Implicit input of string U
Ò                   :Negate the bitwise NOT of
"..."              :String containing the characters at codepoints 89, 109, 130, 149, 161 & 169
¬             :Split
m            :Map
c           :  Codepoint
<        :After checking each is less than
¢       :  Slice the first 2 characters off U
*A     :  Multiply by 10


[+] Version.new($v) <<>=<<(v1.6,v1.9,v1.11,v1.13,v1.15,v1.16.2,v1.17)  Like Perl, Raku has native support for version string comparison. See Version for more info. Explanation • Version.new($v) converts from Str to Version type (it's a shame v$v doesn't work) • <<>=<< hyper-operator converts major versions to Bools • [+] counts True values # Python 3, 9460 57 bytes lambda s:sum(x<=float(s[2:])for x in(0,9,11,13,15,16.2,17))  Try it online! This function takes the string s and returns the corresponding pack_format. -34 bytes thanks to Command Master (using lambda and sum instead of a basic loop + a stopping condition) -3 bytes thanks to tsh (flipping the conditional, changing the list structure, replacing float with eval) • 60 bytes with a lambda function and using sum instead of a loop May 18 '21 at 18:50 • float(s[2:])>=x  -> x<=float(s[2:]) save a space. – tsh May 19 '21 at 9:48 • lambda s:7-sum(x>eval(s[2:])for x in(9,11,13,15,16.2,17)) – tsh May 20 '21 at 3:39 # C (gcc), 67 $$\\cdots\$$ 60 58 bytes Saved a byte thanks to ceilingcat!!! Saved 4 6 bytes thanks to tsh!!! Saved 2 bytes thanks to rtpax!!! y;f(p){p=(~-sscanf(p,"1.%d.%d",&p,&y)*y+p*p+3*p)/51+p/17;}  Try it online! Uses a variation of Arnauld's formula from his JavaScript answer. • It's allowed to read from stdin in the default I/O methods, so I think you can just use normal scanf. May 19 '21 at 3:25 • @ceilingcat Nice one - thanks! :D May 19 '21 at 10:16 • @ceilingcat completely remove the type (use default int) still (at least) works on TIO – tsh May 19 '21 at 10:20 • @tsh Well spotted - thanks! :D May 19 '21 at 10:29 • @CommandMaster When I have some time, I'll check that out - thanks! :D May 19 '21 at 12:13 # 05AB1E, 18 bytes ¦¦T*•BÎΣÚÁÿ•Ƶζв›O>  Try it online! ¦¦T*•...•Ƶζв›O> # trimmed program O # sum of all elements of... › # is... # implicit input... ¦ # excluding the first character... ¦ # excluding the first character... * # times... T # 10... › # greater than... # (implicit) each element of... в # list of base-10 values of base... Ƶζ # 170... в # digits of... •...• # 12728408213639... > # plus 1 # implicit output  • •BÎΣÚÁÿ•Ƶζв -> "Ym¡©"Ç for -2 (stack exchange removes some characters so I added a link to TIO) May 19 '21 at 4:12 • @CommandMaster Those unprintables aren't in 05AB1E's codepage, so while that lowers the character count by 2, it adds 7 bytes because UTF-8 or similar is necessary to encode those. May 19 '21 at 16:20 • TIO says it's 9 bytes in SBCS 🤔 May 20 '21 at 6:06 • @CommandMaster TIO is wrong. It's just too lazy to count characters outside 05AB1E's codepage so it just shows the character count May 20 '21 at 16:33 # Java, 93 bytes s->{var i=Float.valueOf(s.substring(2));return i<9?1:i<11?2:i<13?3:i<15?4:i<16.2?5:i<17?6:7;}  Try it online! # Vyxal, 23 bytes L2$"iE₀*-AViu}C44+>∑›


Try it Online!

# Python 3, 72 bytes

f=lambda p,n=0:float(p[2:])<[9,11,13,15,16.2,17,18][n]and n+1or f(p,n+1)


Try it online!

# Charcoal, 32 29 bytes

ＩＬΦＩ⪪”#｜⊞u⦄,<q'Ｚχ=” ¬›ιＩ✂θ²χ¹


Try it online! Link is to verbose version of code. Explanation:

     ”...”              Compressed string 0 9 11 13 15 16.2 17
⪪                   Split on spaces
Ｉ                    Cast to float
Φ                     Filtered where
ι          Current value
¬›           Is not greater than
✂θ²χ¹    Slice of input string
Ｉ         Cast to float
Ｌ                      Take the length
Ｉ                       Cast to string
Implicitly print


Prefixing 0  to the compressed string or post-incrementing both cost 1 byte. I've stuck with prefixing 0  as it used to be shorter with the previous method. Edit: Switched to a less-than-or-equals comparison which costs a byte but saves 4 bytes from the compressed string.

# BRASCA 0.5.2, 30 bytes

The G operator was added on the same day as the challenge was posted, but not specifically for this challenge.

The program assumes input as 1.x.y at all times. Ex. 1.16 must be input as 1.16.0.

The math is from Arnauld's JS answer, go upvote it!

C'.iGX$:16S>[7n@]x::*$3*++51S/


Try it online!

## Explanation

The second number will be called X, the third number will be called Y.

C                               - Set implicit output to number mode
i                            - Turn "0-9" from char into the numbers 0-9
'. G                           - Split stack by "."
X                          - Remove the first number, it's not needed.
$- Put X on top of the stack :16S>[7n@]x - If it's more than 16, the version is 1.17.0, so print 7 and terminate. - Calculate the final number: ::* - (X**2$3*+       -        + X*3
+      -              + Y)
51S/  -                  /51
<implicit>                      - Output the number


# Python 3, 66 bytes

lambda i:sum([float(i[2:])>x+8.2 for x in [.7,2,4,6.2,7.9,8.3]])+1


Try it online!

Explanation:

• Our input is i. Remove the 1. at the start with i[2:].
• Convert the rest to a number with float.
• For each x in the list, check if this is greater than x+8.2.
• Why 8.2? Well, all of the finishing versions (1.8.9, 1.10.2, etc.) are greater than 8, thus saving some bytes.
• In addition, since two of them end with .2, I can subtract that as well, saving 2 more bytes.
• Since True and False are treated as 1 and 0 by the arithmetic operators, we can use sum to count the number of Trues in the list.
• This is now off by one, so we add 1.