7
\$\begingroup\$

Your task is given an input string of the full/short name of a CS:GO (Counter-Strike: Global Offensive, a computer game) rank return an integer from 1-18 representing the rank number. A higher number means you are a higher rank and so "better" at CS:GO.

Input

A string representing either the full name or short name of the CS:GO rank. Your code must be able to handle both cases.

Output

An integer representing the rank number of the given input. You can output in either 0-indexing or 1-indexing as 0-17 and 1-18 respectively.

Test cases:

The test cases use 1 - 18 as the output, just subtract one if you are using 0-indexing. Where SN means short name.

Full name                     SN   -> output

Silver I                      S1   -> 1
Silver II                     S2   -> 2
Silver III                    S3   -> 3
Silver IV                     S4   -> 4
Silver Elite                  SE   -> 5
Silver Elite Master           SEM  -> 6
Gold Nova I                   GN1  -> 7
Gold Nova II                  GN2  -> 8
Gold Nova III                 GN3  -> 9
Gold Nova Master              GNM  -> 10
Master Guardian I             MG1  -> 11
Master Guardian II            MG2  -> 12
Master Guardian Elite         MGE  -> 13
Distinguished Master Guardian DMG  -> 14
Legendary Eagle               LE   -> 15
Legendary Eagle Master        LEM  -> 16
Supreme Master First Class    SMFC -> 17
Global Elite                  GE   -> 18
\$\endgroup\$
  • 38
    \$\begingroup\$ English, 3 bytes Bad \$\endgroup\$ – Skidsdev Jun 5 '17 at 15:10
  • 5
    \$\begingroup\$ @Mayube that's gold! \$\endgroup\$ – Ivanka Todorova Jun 5 '17 at 15:18
  • 4
    \$\begingroup\$ @IvankaTodorova Actually it's silver :P \$\endgroup\$ – TheLethalCoder Jun 5 '17 at 15:22
  • 2
    \$\begingroup\$ @TheLethalCoder actually it's Global Elite \$\endgroup\$ – Christopher Jun 5 '17 at 16:48
  • 1
    \$\begingroup\$ Sure, but naming it hardly impedes (I went to search for what it was, it may save others a few seconds too). \$\endgroup\$ – Jonathan Allan Jun 6 '17 at 20:03
3
\$\begingroup\$

Jelly,  51 49 46  45 bytes

Oḅ4%⁽+Þ%63“¬>ṬṿḄḋḷ<¶Ġþṛṫ9ṡt[`3"G£ḳọċ’b59¤i‘:2

A monadic link accepting a list of characters and returning an integer.
Result is 0-indexed.

Try it online! or see all valid inputs at the test suite.

How?

Oḅ4%⁽+Þ%63“ ... ’b59¤i‘:2 - Main link: list of characters, s  e.g. "Global Elite"
O                         - cast to ordinals                       [71,108,111,98,97,108,32,69,108,105,116,101]
 ḅ4                       - convert from base 4                    448653509 (71 * 4 ^ 15 + 108 * 4 ^ 14 + ... + 116 * 4 + 101 = 448653509)
    ⁽+Þ                   - base 250 compressed number             11771
   %                      - modulo                                 1844 (448653509 = 11771 * 38115 + 1844)
       %63                - modulo 63                              17 (1844 = 63 * 29 + 17)
                     i    - first index (or 0 if not found) in:    33  -----------------------------------------------------------------------+
                    ¤     - nilad followed by link(s) as a nilad:                                                                             |
          “ ... ’         -   base 250 integer = 29327561081972369663135271131767983884313794468054748055733                                  v
                 b59      -   convert to base 59 = [1,4,5,44,6,14,7,23,43,45,16,48,21,49,50,51,13,55,2,53,28,54,10,37,18,36,8,58,31,57,24,47,17,37]
                          -   i.e. all valid results of the hashing except Silver I (40) and S1 (3) in ascending rank order.
                      ‘   - increment                              34
                       :2 - integer divide by 2                    17

(another 45 byter: Oḅ30%⁽EÐ%53“ḷṡ{Żiȧ)ßØẊ×HuÑç%Ɱȧḷ9)×ḍỊ’b53¤i‘:2)

\$\endgroup\$
6
\$\begingroup\$

Ruby, 120 111 100 99 bytes

->x{x.tr!'a-z ','';x.gsub!(/I.*/){$&.sum%18%11};'

   '[x.sum%36%20+x.ord%4].ord}

Hexdump, since the Stack Exchange software mangles lots of the unprintables in the source code:

00000000: 2d3e 787b 782e 7472 2127 612d 7a20 272c  ->x{x.tr!'a-z ',
00000010: 2727 3b78 2e67 7375 6221 282f 492e 2a2f  '';x.gsub!(/I.*/
00000020: 297b 2426 2e73 756d 2531 3825 3131 7d3b  ){$&.sum%18%11};
00000030: 270e 0f0d 0920 2010 0102 0304 0511 0a20  '....  ........ 
00000040: 1206 200b 0c20 0708 275b 782e 7375 6d25  .. .. ..'[x.sum%
00000050: 3336 2532 302b 782e 6f72 6425 345d 2e6f  36%20+x.ord%4].o
00000060: 7264 7d                                  rd}

Try it online!

(Note: I can't figure out how to get a carriage return into the "Code" box on TIO, so the TIO version has it replaced with an X and hence outputs 88 instead of 13 for MGE.)

Explanation:

x.tr!'a-z ',''

This deletes all lowercase letters and spaces from the input.

x.gsub!(/I.*/){$&.sum%18%11}

This searches for an I in the string and, if found, replaces it to the end of the string with the result of a black-magic algorithm (found by brute force search) that produces the numeric equivalent of the Roman numeral.

'junk'[more junk].ord

The first section of junk (and the ord) maps the values [7, 8, 9, 10, 11, 16, 21, 22, 3, 13, 18, 19, 2, 0, 1, 6, 12, 15] to the range 1..18 by indexing into the string, which contains the appropriate bytes at their corresponding indices.

The second section of junk maps the values ["S1", "S2", "S3", ...] to the values [7, 8, 9, ...]. The formula was produced by a simple brute force search minimizing the maximum value obtained while ensuring that 18 unique values still exist.

\$\endgroup\$
  • \$\begingroup\$ So... string.sum is equivalent to string.bytes.sum? Is there any other quirky sum behavior I should be aware of??? (Also, you need to specify Ruby 2.4) \$\endgroup\$ – Value Ink Jun 5 '17 at 18:46
6
\$\begingroup\$

JavaScript (ES6), 164 150 135 bytes

s=>'GE S1|S2|S3|S4|SE|SEMGN1GN2GN3GNMMG1MG2MGEDMGLE LEMSMFC'.search(s[r='replace'](/[a-z ]/g,'')[r]('IV',4)[r](/I+/,a=>a.length))/3||18

(Saved a bunch of bytes thanks to @Craig Ayre and @Steve Bennett.)

Explanation:

s[r='replace'](/[a-z ]/g,'')[r]('IV',4)[r](/I+/,a=>a.length) converts Full names to the SN equivalents. It doesn't change SNs.

We then simply index into the array of SNs created by split.

Snippet:

f=
s=>'GE S1|S2|S3|S4|SE|SEMGN1GN2GN3GNMMG1MG2MGEDMGLE LEMSMFC'.search(s[r='replace'](/[a-z ]/g,'')[r]('IV',4)[r](/I+/,a=>a.length))/3||18

console.log(f('Silver I'));                      // S1   -> 1
console.log(f('Silver II'));                     // S2   -> 2
console.log(f('Silver III'));                    // S3   -> 3
console.log(f('Silver IV'));                     // S4   -> 4
console.log(f('Silver Elite'));                  // SE   -> 5
console.log(f('Silver Elite Master'));           // SEM  -> 6
console.log(f('Gold Nova I'));                   // GN1  -> 7
console.log(f('Gold Nova II'));                  // GN2  -> 8
console.log(f('Gold Nova III'));                 // GN3  -> 9
console.log(f('Gold Nova Master'));              // GNM  -> 10
console.log(f('Master Guardian I'));             // MG1  -> 11
console.log(f('Master Guardian II'));            // MG2  -> 12
console.log(f('Master Guardian Elite'));         // MGE  -> 13
console.log(f('Distinguished Master Guardian')); // DMG  -> 14
console.log(f('Legendary Eagle'));               // LE   -> 15
console.log(f('Legendary Eagle Master'));        // LEM  -> 16
console.log(f('Supreme Master First Class'));    // SMFC -> 17
console.log(f('Global Elite'));                  // GE   -> 18

console.log(f('S1'));
console.log(f('S2'));
console.log(f('S3'));
console.log(f('S4'));
console.log(f('SE'));
console.log(f('SEM'));
console.log(f('GN1'));
console.log(f('GN2'));
console.log(f('GN3'));
console.log(f('GNM'));
console.log(f('MG1'));
console.log(f('MG2'));
console.log(f('MGE'));
console.log(f('DMG'));
console.log(f('LE'));
console.log(f('LEM'));
console.log(f('SMFC'));
console.log(f('GE'));

\$\endgroup\$
  • \$\begingroup\$ Could you remove the parens before indexOf? '...'.split`|`.indexOf \$\endgroup\$ – Craig Ayre Jun 5 '17 at 15:56
  • \$\begingroup\$ @CraigAyre, yes, thanks, thought I had already tried that! \$\endgroup\$ – Rick Hitchcock Jun 5 '17 at 15:59
  • 2
    \$\begingroup\$ No worries! I think you could shave some extra bytes from the numerals: [r]('III',3)[r]('II',2)[r]('I',1) -> [r](/I+/,a=>a.length) \$\endgroup\$ – Craig Ayre Jun 5 '17 at 16:17
  • 1
    \$\begingroup\$ Ah. Why didn't I think of this? I thought I'd change SNs to full name with words for each charactet or something. \$\endgroup\$ – lol Jun 6 '17 at 2:37
  • 1
    \$\begingroup\$ Ok, this is 135. Haven't thoroughly tested but handles most cases: s=>'GE S1|S2|S3|S4|SE|SEMGN1GN2GN3GNMMG1MG2MGEDMGLE LEMSMFC'.search(s[r='replace'](/[a-z ]/g,'')[r]('IV',4)[r](/I+/,a=>a.length))/3||18 \$\endgroup\$ – Steve Bennett Jun 7 '17 at 6:41
5
\$\begingroup\$

Retina, 70 bytes

V
3
G.*N.*M|L
55
G.*N
6
M.*G.*E
67
G.*E
99
D
4
E
5
F
88
G
9
\d
$*I
I|M

Try it online! Works by converting specific upper case letter combos into digits and totalling the digits.

\$\endgroup\$
5
\$\begingroup\$

PHP, 151 Bytes

0-Indexing

Remove all characters that not Uppercase or digit

After that replace the digits with their roman numbers

Search and Output the Key in the Array

<?=array_flip([SI,SII,SIII,SIV,SE,SEM,GNI,GNII,GNIII,GNM,MGI,MGII,MGE,DMG,LE,LEM,SMFC,GE])[strtr(preg_replace("#[^C-V\d]#","",$argn),[_,I,II,III,IV])];

Try it online!

PHP, 158 Bytes

0-Indexing

Remove all characters that not Uppercase

After that replace the roman numbers with their digit

Search and Output the Key in the Array

<?=array_flip([S1,S2,S3,S4,SE,SEM,GN1,GN2,GN3,GNM,MG1,MG2,MGE,DMG,LE,LEM,SMFC,GE])[preg_replace(["#[^C-V]#","#IV#","#III#","#II#","#I#"],["",4,3,2,1],$argn)];

Try it online!

PHP, 295 Bytes

0-Indexing Without Regex

Search and Output the Key of an Array

If more than 4 characters are set in the input take the array with the longer names else take the array with the short names

<?=array_flip(explode(_,$argn[4]?strtr("0I_0II_0III_0IV_03_03 4_1I_1II_1III_14_45I_45II_453_Distinguished 45DMG_2_2 4_Supreme 4 First Class_Global 3",["Silver ","Gold Nova ","Legendary Eagle",Elite,Master," Guardian "]):S1_S2_S3_S4_SE_SEM_GN1_GN2_GN3_GNM_MG1_MG2_MGE_DMG_LE_LEM_SMFC_GE))[$argn];

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 3 + Roman, 291 bytes

import roman as r,sys
a=sys.argv
x,y,o=a[1],a[-1],{r:i for i,r in enumerate(["S1","S2","S3","S4","SE","SEM","GN1","GN2","GN3","GNM","MG1","MG2","MGE","DMG","LE","LEM","SMFC","GE"])}
print(o[x if x in o else "".join([n[0] for n in a[1:-1]] + [str(r.fromRoman(y)) if y in "IIIV" else y[0]])])

Non-golfed version:

import roman
from sys import argv

if __name__ == "__main__":
    ranks = ["S1", "S2", "S3", "S4", "SE", "SEM", "GN1", "GN2", "GN3", "GNM",
             "MG1", "MG2", "MGE", "DMG", "LE", "LEM", "SMFC", "GE"]
    output = {rank : i for i, rank in enumerate(ranks)}

    if argv[1] in output:
        print(output[argv[1]])
    else:
        argv[-1] = str(roman.fromRoman(argv[-1])) if argv[-1] in "IIIV" else argv[-1][0]
        print(output["".join([x[0].upper() for x in argv[1:]])])
\$\endgroup\$
  • 1
    \$\begingroup\$ You can golf the last line to print(o[x if x in o else"".join([n[0] for n in a[1:-1]]+[str(r.fromRoman(y))if y in"IIIV"else y[0]])]). \$\endgroup\$ – Esolanging Fruit Jun 6 '17 at 0:25
  • \$\begingroup\$ Also, can't you do y=a.pop(), and then use a[1:] rather than a[1:-1] on the last line? \$\endgroup\$ – Esolanging Fruit Jun 6 '17 at 0:26
  • \$\begingroup\$ @Challenger5: First suggestion is great (will work in to my solution tomorrow morning). As for second one, does it actually save any characters? The last line drops 2, but the third line adds 2 I think (since len("a[1:-1]") == len("a.pop()"). \$\endgroup\$ – tonysdg Jun 6 '17 at 0:30
  • \$\begingroup\$ Also, you can replace the dictionary comprehension with a call to dict. \$\endgroup\$ – Esolanging Fruit Jun 6 '17 at 0:36
  • \$\begingroup\$ That's true, I don't know why I said that. \$\endgroup\$ – Esolanging Fruit Jun 6 '17 at 0:37
1
\$\begingroup\$

Python 2,  100  96 bytes

lambda s:"F]u^B_&`5qDy,MeN<O$iW'?(d;hHQ2Y:1o%a".find(chr((9*ord(s[0])+ord((s*18)[35]))%92+33))/2

An unnamed function accepting the string s and returning an integer.
Result is 0-indexed.

Try it online!

How?

Takes the 1st and 36th (modulo the length) characters of the input using s[0] and (s*18)[35] respectively, that produces the mapping:

{"Silver I":"Sv", "S1":"S1", "Silver II":"SI", "S2":"S2", "Silver III":"Sr", "S3":"S3", "Silver IV":"SV", "S4":"S4", "Silver Elite":"Se", "SE":"SE", "Silver Elite Master":"St", "SEM":"SM", "Gold Nova I":"Gl", "GN1":"G1", "Gold Nova II":"GI", "GN2":"G2", "Gold Nova III":"G ", "GN3":"G3", "Gold Nova Master":"Gd", "GNM":"GM", "Master Guardian I":"Ma", "MG1":"M1", "Master Guardian II":"MI", "MG2":"M2", "Master Guardian Elite":"Mn", "MGE":"ME", "Distinguished Master Guardian":"Dg", "DMG":"DG", "Legendary Eagle":"Ld", "LE":"LE", "Legendary Eagle Master":"Ll", "LEM":"LM", "Supreme Master First Class":"Sa", "SMFC":"SC", "Global Elite":"Ge", "GE":"GE"}

Converts them to ordinals and converts that from base 9 (ignoring the "base 9 only has 9-digits" restriction) by multiplying the first ordinal by nine and adding it to the second (9*ord(s[0])+ord((s*18)[35])).

Reduces the range of those numbers while maintaining uniqueness by taking the modulo 92 of the result. Adds 33 to make the range fit across printable characters (while avoiding the pesky \ which would require escaping).

Looks up the index of the resulting character in a string, using find and integer divides the result by two with /2 (since every two characters represent a "class" - one for the long name and one for the short name).

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