33
\$\begingroup\$

Given the name of an HTTP status code, such as OK or Continue, output or return the corresponding number. Your code is limited to 200 bytes, and the winner is the answer that correctly finds the number for the most status codes.

For this challenge, the status codes your program should handle are:

100 Continue
101 Switching Protocols
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported

Test cases:

Continue        -> 100
OK              -> 200
No Content      -> 204
Not Found       -> 404

For invalid status codes or ones not supported by your program, any behavior is fine. Input and output can be in any reasonable format. If there is a tie, the shortest program that can support that many status codes wins.

\$\endgroup\$
17
  • 3
    \$\begingroup\$ useful site: httpstat.us \$\endgroup\$
    – Razetime
    Mar 11 at 1:49
  • 3
    \$\begingroup\$ I think this challenge would be more interesting if you disallowed built-ins that do this. \$\endgroup\$
    – pxeger
    Mar 11 at 8:31
  • 3
    \$\begingroup\$ @pxeger If doing so, lot of solutions will be invalid, and they would require deletion \$\endgroup\$
    – wasif
    Mar 11 at 9:27
  • 3
    \$\begingroup\$ "Your code is limited to 200 bytes". That's cute. There probably will be a 7-byte answer written in 05AB1E or Jelly anyway. \$\endgroup\$ Mar 11 at 13:28
  • 20
    \$\begingroup\$ Any reason why 418: I'm a teapot isn't included in the status-code list? \$\endgroup\$
    – 0stone0
    Mar 11 at 17:18

18 Answers 18

32
\$\begingroup\$

Node.js,  135 126 125  123 bytes, score 40

Saved 2 bytes by using unprintable characters, as suggested by @dingledooper

s=>Buffer('~>/6%sH~~d4~\\~i~~,~~~~~.~~~~n)W*~~~~;~CR@M"~1E~$~ _Z9~')[parseInt(s[0]+s[4]+s[19],34)*57%65]*209%523

Try it online!

Decoding example

Let's consider the input string "Internal Server Error".

We extract the characters at indices \$0\$, \$4\$ and \$19\$ and concatenate them together:

Internal Server Error
^   ^              ^

This gives "Iro".

We parse this string as a base-34 value, leading to \$\color{blue}{21750}\$.

Note: For many shorter entries, some characters are undefined. This leads to strings such as "Piundefined" and much higher integers.

We apply the hash formula:

$$(\color{blue}{21750}\times57)\bmod65=5$$

We extract the corresponding character from the lookup string (which is a "s") and take its ASCII code, leading to \$\color{blue}{115}\$.

We apply another black magic formula to turn this into the final HTTP status code:

$$(\color{blue}{115}\times209)\bmod 523=500$$

Given an HTTP status code \$c\$, the ASCII code \$k\$ of the encoding character is given by the following reverse formula:

$$k = \lfloor c / 100\rfloor \times 23 - (c \bmod 100) \times 5$$

Try it online!


Node.js, 84 bytes, score 40

With a built-in.

s=>Object.keys(c=require('http').STATUS_CODES).find(k=>c[k]==s)||413+(~s.length/6&3)

Try it online!

How?

There are 3 strings that do not match the values stored in STATUS_CODES for codes 413, 414 and 416. For these ones, we use the length of the input to figure out the correct answer.

 string                            | len | ~len/6  | &3 | +413
-----------------------------------+-----+---------+----+------
 "Request Entity Too Large"        |  24 | -4.1667 |  0 |  413
 "Request-URI Too Long"            |  20 | -3.5000 |  1 |  414
 "Requested Range Not Satisfiable" |  31 | -5.3333 |  3 |  416
\$\endgroup\$
7
  • 18
    \$\begingroup\$ How do you find formulas like this so consistently on so many different challenges!? Color me impressed yet again. \$\endgroup\$
    – sporeball
    Mar 11 at 7:44
  • 7
    \$\begingroup\$ @sporeball Finding a hash function is not very hard. We can either use a specialized tool such as gperf, or just inject random values into some simple formula templates (which is what I do most of the time). However, there's no hash built-in in JS, so we also have to find a way to turn the input string into something that can be parsed by parseInt(). For this challenge, I first looked for all triplets (i,j,k) such that s[i]+s[j]+s[k] are unique for all possible input strings. The triplet is also randomly chosen by the script I used here. \$\endgroup\$
    – Arnauld
    Mar 11 at 8:02
  • \$\begingroup\$ Maybe this can save 1 byte by changing 100 to 99 and modify many many values. (But maybe too complex so just ignore it...) \$\endgroup\$
    – tsh
    Mar 11 at 9:59
  • \$\begingroup\$ @tsh I've found a way to turn the ASCII code into the HTTP code without having to use a variable. \$\endgroup\$
    – Arnauld
    Mar 11 at 10:59
  • 3
    \$\begingroup\$ WT....I was trying to compress it to minimal unique codes but this is some black magic stuff! I kind of understand your explanation but I have NO idea how you get to that place. \$\endgroup\$ Mar 11 at 15:01
17
\$\begingroup\$

Python 3, 68 bytes, score: 40

A cheap builtin answer.

lambda s:+http.HTTPStatus[re.sub('\W','_',s.upper())]
import http,re

Try it online!

Python 2, 131 119 115 104 bytes, score: 40

A nicer method with the same score, using a magic formula. @Arnuald's answer had a really nice way of calculating the status code, which saves me a ton of bytes.

lambda s:ord('?".\, ;?Zd?s>M?C6/W4?)??*??H1@R???i_??n$?9E?%'[hash(s)%762%517%233%56])*209%523

Try it online!

\$\endgroup\$
6
  • 1
    \$\begingroup\$ I like the second more. \$\endgroup\$
    – rues
    Mar 11 at 2:07
  • 5
    \$\begingroup\$ @user Yep me too. Naturally a builtin will be less exciting than a genuine one :P. \$\endgroup\$ Mar 11 at 2:20
  • 1
    \$\begingroup\$ I get fascinated each time when I see use of insane math formulas \$\endgroup\$
    – wasif
    Mar 11 at 8:14
  • 2
    \$\begingroup\$ My new ASCII to HTTP conversion formula may also save some bytes in your answer. \$\endgroup\$
    – Arnauld
    Mar 11 at 11:12
  • \$\begingroup\$ @Arnauld What a nice formula! After brute-forcing some values I reached a shorter formula. Perhaps yours could be shortened as well. \$\endgroup\$ Mar 11 at 20:02
9
\$\begingroup\$

Jelly, score 40, tiebreak score 61 bytes

ȷ;€ȷḥ€ɠḋ“^,fḷɱ⁹⁴ƒẈ®ẒỤĖṅ}PG¬Ƭṙ⁴&©ẉ}Ḳḍƙḋ¥ȤẊḌÐẈ’b123¤%127b28ḅ³+³

Try it online!

Jelly, score 40, tiebreak score 58 bytes, in collaboration with @Arnauld and @ChartZ Belatedly

ȷ;€ȷḥ€ɠḋ“Rḳk_ṇṙƤĊ⁻ƒƓḍ¹⁹¡Ɱṫ°ė÷Ḣ4[⁶æȥ.’b41¤ị“£¬®Ø©‘Ḷ+"J׳ƊF¤

Try it online!

Discussion

I found an almost asymptotically optimal algorithm for solving this sort of problem (mapping a set of given inputs into specific numbers, not caring about other inputs) a while ago. The algorithm takes a few bytes to express in Jelly, but the savings in not having any wasted bytes actually describe the outputs are worthwhile, making this the currently shortest non-builtin-based solution. (As a side note, it may well be worth adding the algorithm in question as a Jelly builtin, which would save 11-13 bytes from this program depending on how it was implemented; it seems likely to come up in the future.)

The algorithm basically generates programs that work by running a large number of hash functions on the input to produce a vector of hashes, then taking the dot product of that vector with a hardcoded vector over a finite field. (When implementing this in Jelly, we use a finite field of prime order, because it doesn't have builtins for dealing with other sorts of finite field.) It turns out that the minimum length of a hardcoded vector that solves this problem is almost always equal to the number of input/output pairs, and the maximum size of the vector elements is the order of the finite field, so the amount of storage used by this is equal to the amount of storage needed to store the possible outputs (thus asymptotically optimal). Adding a new HTTP status code to this program would typically cost less than a byte on average per code, unless it was outside the range of the existing codes (e.g. here's how to add "I'm a teapot" to the original program at the cost of only one more byte).

I've since automated a program generator that generates Jelly programs to solve these programs. So this codegolf submission was pretty much entirely automatically generated. This is the generation program I used (configured to generate a solution to this problem). The Sage program it generates, when run, generates this Jelly program which generates the program written above.

The reason I've described the algorithm as "almost asymptotically optimal" is that it has two failure modes. One is mathematical; the algorithm involves solving a set of simultaneous equations, which can almost always be solved using a vector whose length is equal to the number of input/output pairs, but rarely and randomly have no solution (the odds of this become smaller as the size of the codomain becomes larger, and when it happens you can "reroll" by adding an arbitrary extra input/output pair, leading to a slightly larger program). The other is a deficiency of Jelly; the shortest way in Jelly to describe a list of integers drawn from a uniform random distribution is to use a large constant integer and base-convert it, but this mechanism is incapable of expressing lists with a leading 0 (the program generator I've written above doesn't attempt to fix this problem itself, but the odds of it happening are again just 1 in the size of the output domain).

Explanation (original version)

Here's how this program is implemented in Jelly:

ȷ;€ȷḥ€ɠḋ“…’b123¤%127b28ḅ³+³
    ḥ                        Hash
      ɠ                        a line taken from standard input
                             using
     €                         each of the following hash configurations:
ȷ €                              each number from 1 to 1000 (the salt)
 ;                               concatenated with
   ȷ                             1000 (the codomain of the hash function);
       ḋ                     take the dot product of the resulting hashes and
               ¤               a constant calculated by
        “…’                      converting a large constant integer
           b123                  to a list of base 123 digits;
                %127         take the resulting dot product modulo 127,
                    b28      convert to a list of base 28 digits,
                       ḅ³    interpret as base 100 digits,
                         +³  and add 100

Everything up to the %127 is just the implementation of our general-purpose input→output mapper. The b28ḅ³+³ after that implements the inverse of a function that maps HTTP status codes from 100…505 onto integers in the range 0…117; producing a smaller codomain allows for a smaller hardcoded vector. (The basic idea is to note that the last two digits of the status code are never greater than 27, so the double base conversion "closes some of the gaps" in the range of possible outputs.)

As it happens, our hardcoded vector didn't contain any of the values 123, 124, 125, or 126, so it was possible to use 123 as the base for that base conversion. (The gain from this is minimal; if Jelly had a builtin for this algorithm, you'd hardcode that the "123" and "127" were the same number.)

There's no particular algorithmic reason for the codomain of the hash function to be 1…1000 (any sufficiently large codomain would do), and calculating 1000 hashes is likewise not algorithmically useful because we only use the first 40 of them. This is just a tiny byte saving: 1000 has a 1-byte representation, whereas most other numbers can't be written in a single byte.

Incidentally, the reason we take input from standard input is that 100 (the lowest HTTP status code) can be represented in 1 byte in Jelly if the program has no command-line arguments, but takes 3 bytes if there are any command-line arguments. There wasn't a byte cost to doing anything because I needed to take explicit input anyway (attempting to take implicit input would run into a parse ambiguity that would need a byte to fix, so the extra byte for explicit input doesn't cost).

Explanation (improved version)

@Arnauld suggested, instead of the base-28 calculation used in the previous version, to generate a list of the 41 possible (return values + 306) (trying to omit 306 from the list would cost more bytes than simply just adding it; and including it also gives us a prime number of possible outputs, which we need to be able to do finite field operations over the range of outputs in Jelly).

We can generate a list of the values like this:

“£¬®Ø©‘Ḷ+"J׳ƊF
“£¬®Ø©‘          [2,7,8,18,6]
       Ḷ         range from 0 to n-1, i.e. [[0,1],[0,1,…,6],…]
             Ɗ   group the three preceding bultins together
        +        add
           ׳      100 times
          J        the index of
         "         each sublist to every element of the sublist
              F  flatten

In other words, we're adding 1 to each element of the first list, 2 to each element of the second list, etc., 100 times, thus effectively adding [100,200,300,400,500] to each element of the corresponding sublist of [[0,1],[0,1,…,6],…] to produce [[100,101],[200,201,…,206],…], which can be flattened to produce the list of status codes we want.

I originally generated the list using slightly different code (doing the addition 100 times rather than adding 100 times the index), and connected the list to the original program using a newline and ị¢; is wrapping indexing into a list (thus contains an implicit "modulo 41"; 41 is the size of the finite field we're using in this version and also the number of status codes in the list), and ¢ tells Jelly to look at the previous line to find the list to index into. However, @ChartZ Belatedly realised that rearranging the list generation like this, although it still takes the number of bytes, makes the list generation into a nilad followed by a sequence of monads. This makes it possible to treat the entire list generation like a literal constant by using a single ¤ byte, which is a less general method of specifying the grouping than the a newline and ¢ were, but worth it as it's a byte shorter overall.

This approach, where almost all the outputs are used, costs several bytes for the more complex post-processing, but makes the hardcoded vector require substantially less storage because the numbers in it now only go up to 40 rather than 122, so it saves more bytes than it costs.

\$\endgroup\$
4
  • \$\begingroup\$ Would it be any shorter to generate the list of HTTP codes (e.g. turning [1,6,7,17,5] into [[100,101],[200,...,206],...] and flatten it) and storing the indices as the relevant permutation of 0..39? \$\endgroup\$
    – Arnauld
    Mar 12 at 18:00
  • \$\begingroup\$ It took me a while to golf the list generation down far enough, but it turns out that it is in fact shorter. Thanks for the improvement! \$\endgroup\$
    – ais523
    Mar 12 at 20:36
  • \$\begingroup\$ 58 bytes for the second one \$\endgroup\$ Mar 12 at 21:24
  • \$\begingroup\$ @ChartZ Belatedly: I was trying to do something like that but couldn't make it work. Thanks for the improvement! \$\endgroup\$
    – ais523
    Mar 12 at 21:40
6
\$\begingroup\$

Ruby -n -l -rnet/http/status, 31 bytes, score: 37

p Net::HTTP::STATUS_CODES.key$_

Try it online!

Another cheap builtin answer. Not a perfect score because the reason phrases in the library are taken from RFC 7231 instead of the older RFC 2616 (as used in the question).


Ruby -n -l -rnet/http/status, 47 bytes, score: 40

p Net::HTTP::STATUS_CODES.key($_)||416-~/$//7%4

Try it online!

Uses the length of the input to return the correct code for the three reason phrases not stored in the builtin hash. Credit to @Arnauld for the idea.

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

Python 3, 200 190 188 bytes Score:40

Thanks to pxeger for -8 bytes, ChartZ Belatedly for -4 bytes!

At least I didn't use a builtin :P this was an editor nightmare, couldn't copy and paste my encoded data correctly. I stopped working on this when it came out to exactly 200 bytes. I don't know what kind of black magic created dingledooper's solution and I'm afraid to ask.

lambda i:sum(e[1:(e.index(sum(i)&4095)+2):2])
e=[*map(ord,"ͅdޕšcʸ̙୧θӾ׈ت^ڪǼ̿ѲͯܕА]Ԃؿ΍͍ښԵୣװ̲Ɖ׃ݓࣣ܈࡫஗۩߾SׅϹݕיॽ")]

Try it online!

The encoded data goes like this:

[Sum of description bytes & 0xfff,Numeric change in HTTP Code,Sum of ...

e.g.

[837, 100, 1941, 1, 154, 99, 696, 1, 793, 1, 2919, 1, 952, 1, 1278, 1, 1480, 1, 1578, 94, 1706, 1, 508, 1, 831, 1, 1138, 1, 879, 1, 1813, 2, 1040, 93, 1282, 1, 1599, 1, 909, 1, 845, 1, 1690, 1, 1333, 1, 2915, 1, 1520, 1, 818, 1, 393, 1, 1475, 1, 1875, 1, 2275, 1, 1800, 1, 2155, 1, 2967, 1, 1769, 1, 2046, 83, 1477, 1, 1017, 1, 1877, 1, 1497, 1, 2429, 1]

Here's the code I used to generate it (plus some useless vestigial code...):

dat = b"""100 Continue
101 Switching Protocols
200 OK
201 Created
202 Accepted
203 Non-Authoritative Information
204 No Content
205 Reset Content
206 Partial Content
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
305 Use Proxy
307 Temporary Redirect
400 Bad Request
401 Unauthorized
402 Payment Required
403 Forbidden
404 Not Found
405 Method Not Allowed
406 Not Acceptable
407 Proxy Authentication Required
408 Request Timeout
409 Conflict
410 Gone
411 Length Required
412 Precondition Failed
413 Request Entity Too Large
414 Request-URI Too Long
415 Unsupported Media Type
416 Requested Range Not Satisfiable
417 Expectation Failed
500 Internal Server Error
501 Not Implemented
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
505 HTTP Version Not Supported"""
data = ([(x[4:],x[:3]) for x in dat.split(b"\n")])
def e(d) : return sum(d)&0xfff
d2 = ([(x[1],e(x[0])) for x in data])
print(d2)
ol=[]
px = 0
for x in d2:
	ol.append(x[1])
	ol.append(int(x[0])-px)
	px = int(x[0])
de="".join([chr(x) for x in ol])
with open("de","w") as fh:
	fh.write(de)

ind=b"Non-Authoritative Information" 
print(len(bytes(de,'utf-8')))
ct=f"""\
d="{de}"
e=list(map(ord,d))
c=lambda i:(sum(e[1:(e.index(sum(i)&0xfff)+2):2]))\
"""

with open("decoder.py","w") as fh:
	fh.write(ct)

from decoder import *
res = [(c(bytes(i[0])),i[1]) for i in data]
re = [x[0]==int(x[1]) for x in res]
print(sum(re))
print(len(data))
for i,v in enumerate(re):
	if not v:
		print(res[i])

print(ct)

	

Try it online!

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Replace 0xfff with 4095 for -1 byte? And list(...) -> [*...] for -3. And you don't need to include the c= in the lambda definition nor the extra parentheses around (sum(...)) \$\endgroup\$
    – pxeger
    Mar 11 at 11:11
  • 1
    \$\begingroup\$ You don't need to assign the string to d as you only use it once, just replace e=list(map(ord,d)) with e=list(map(ord,'...')) where ... is the string in d \$\endgroup\$ Mar 11 at 13:21
  • \$\begingroup\$ Thanks! Can you see a way for me to remove the c= and still validate in TIO? I suppose I could redefine the lambda in the footer? \$\endgroup\$
    – M Virts
    Mar 11 at 13:23
  • 1
    \$\begingroup\$ Move the lambda to the first line, above e, and add c = \ to the header \$\endgroup\$ Mar 11 at 13:25
  • \$\begingroup\$ If you delete the sections that are struck out, I think your answer will look a lot cleaner. Deleted sections can still be viewed in the edit history, if people are curious about the higher byte-count previous answers \$\endgroup\$ Mar 11 at 17:05
4
\$\begingroup\$

APL (Dyalog Unicode),

186 bytes, Score : 40 41

S←18 22 53 56 38 91 76 83 98 11 31 86 90 62 40 47 25 80 72 5 10 99 85 24 2 68 52 96 77 19 9 65 4 87 33 36 57 16 49 28 41
C←{(∊⍳¨⍵)+⍵\100×1+⍳5}2 7 8 18 6
f←{C[⍸S=∊⍎2↑⌽⍕8-⍨|-/∊⎕UCS¨33⍴⍵]}

I made a very sketchy "hash function", that is so hobbled together it will only work for these messages.

{⍎2↑⌽⍕8-⍨|-/∊⎕UCS¨33⍴⍵} 'Foo Bar'

33⍴⍵   ⍝ 'Foo BarFoo BarFoo BarFoo BarFoo B'
∊⎕UCS¨ ⍝ convert to UTF8 numerical array 70 111 111 32...
|-/    ⍝ |70-111+111-32...|=104
8-⍨    ⍝ 96
⍎2↑⌽⍕  ⍝ 69

Rehydrating the Status Codes

{(∊⍳¨⍵)+⍵\100×1+⍳5}2 7 8 18 6

100×1+⍳5 ⍝ 100 200 300 400 500
⍵\       ⍝ 100 100 200 200 200 200 200 200 200 300...
∊⍳¨⍵     ⍝ 0 1 0 1 2 3 4 5 6 0 1 2 3...
+        ⍝ 100 101 200 201 202 203 204...

Lookup Status Code

C[⍸S=∊Calculated_Hash]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Wow, really cool answer \$\endgroup\$
    – rak1507
    Mar 21 at 11:54
  • \$\begingroup\$ @rak1507 Thanks :) \$\endgroup\$ Mar 21 at 14:05
3
\$\begingroup\$

APL (Dyalog Extended), 123 bytes

⎕FIX'file:///opt/mdyalog/17.1/64/unicode/Library/Conga/HttpUtils.dyalog'
f←{⊃s⌿⍨(⊂⍵)≡⍥(⌈~∘'-')¨⊣/⌽s←HttpUtils.HttpStatuses}

No builtins that do this exactly (as far as I can tell) but luckily the statuses are stored in Dyalog's HTTP utilities.

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ HttpUtils.dyalog is not guaranteed to exist in that exact path (or at all), so I'm not sure if this is valid. Also, you should include this answer's score in the header. \$\endgroup\$
    – Makonede
    Mar 11 at 20:51
  • 1
    \$\begingroup\$ @Makonede if dyalog is installed, that file exists, and on a normal system (not TIO) you can do ⎕SE.SALT.Load'HttpUtils' anyway. \$\endgroup\$
    – rak1507
    Mar 12 at 9:11
  • \$\begingroup\$ @Makonede I gave it a try without any system calls codegolf.stackexchange.com/a/220985/92642 \$\endgroup\$ Mar 21 at 5:44
3
\$\begingroup\$

c# 9, 101 bytes.

System.Console.WriteLine(args.Length>0?(int)System.Enum.Parse<System.Net.HttpStatusCode>(args[0]):0);
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to Code Golf! This is a nice answer, but it's recommended to also link to an online interpreter like TIO. TIO can also automatically count your bytes and generate Markdown. Also, this question uses the number of http status codes supported as a scoring criterion, so you should also add that to your header. \$\endgroup\$
    – rues
    Mar 13 at 2:14
  • \$\begingroup\$ This is a snippet, please change it to a function or full program for it to be valid. \$\endgroup\$ Mar 14 at 0:39
  • \$\begingroup\$ For c# 9 it's a full program. docs.microsoft.com/en-us/dotnet/csharp/whats-new/… \$\endgroup\$ Nov 18 at 20:27
3
\$\begingroup\$

YaBASIC, 195 bytes, score:40

h=0
for i=1 to len(c$)
h=h+asc(mid$(c$,i,1))
next
x=instr(")64rRz!\"VEjX(#3I	2nBAsfm=tC_TuUhid",chr$(mod(xor(h,1329),127)))
b=99
if x>2 b=197
if x>9 b=290
if x>17 b=382
if x>35 b=464
?b+x;

Try it online!

Well this bit of voodoo was probably the hardest challenge I've completed on Code-Golf! But here it is - a complete, self contained routine that recognizes all 40 codes, in 195 bytes, in good old-fashioned BASIC.

As genius as @Arnauld's answer was, I really wanted to come up with my own solution, not blindly copy his formula, nor just pull codes off the net.

An early attempt with 2 bytes per status code, based on a Pearson hash, bottom out at 238 bytes, and it became obvious I needed a hash table with a single byte per code. Worse, due to the vagaries of UTF-8 coding, attempting to use all 256 ASCII codes gave garbage out, so I was stuck with the basic 127...

I based my answer on the fact that the sum of the ASCII values for each code was unique, and I just needed to find a way to get a unique byte from each one. I ended up writing a seperate utility to generate hash tables, XOR them, test for collisions, and increment the XOR until each hash was unique. 1329 was the "magic number" I got. Of course, the result had to include a " so I lost a byte with the \ needed to add it to a string, plus an extra X to deal with that sneaky jump from 305 to 307.

I really feel I levelled up as a programmer on this one, and I hope you like it!

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

Java EE, 111 bytes, score: 40

s->javax.servlet.http.HttpServletResponse.class.getField("SC_"+s.toUpperCase().replaceAll(" |-","_")).get(null)

HttpServletResponse has public fields for all the statuses prefixed with "SC_". The names, however, are all uppercase and spaces or dashes are replaced with underscores. The values of these fields can be obtained dynamically using reflection.

Demo

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

Zsh, 197 187 bytes, score 40

>`sum`
F()for a {let n++;ls|grep -q $[32#$a]$&&<<<$n&&bye}
for b (5SOO E3HOIOTU3P5PJL 1K82FFFCPFC5JIQF 3AIQ9M13UPUUQ0PR9RBUIAHSNOF8M32QLT2H C2Q1BISP3DKE)n=$[m++]99 F `fold -2<<<$b`
<<<201

Try it online!

Can probably be a fair bit shorter, but I'm not really with it right now.

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

PowerShell, 41 bytes

+[net.httpstatuscode]($args-replace" |-")

Try it online!

Cheap builitins, again

-7 bytes for @ZaelinGoodman

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Dang, you beat me to it! I missed yours on the first pass and ended up writing almost the same thing lol :( Great golf! Here's a few bytes for beating me to it! 43 bytes, Try it online! \$\endgroup\$ Mar 11 at 12:25
  • 1
    \$\begingroup\$ And 41 bytes if you take input as a string instead Try it online! \$\endgroup\$ Mar 11 at 12:26
  • \$\begingroup\$ @ZaelinGoodman thank you for golfing the solution! \$\endgroup\$
    – wasif
    Mar 11 at 15:57
1
\$\begingroup\$

JavaScript (Node.js), 133 bytes, score 40

f=(t,i,c,s=require('http').STATUS_CODES[i])=>s==t?i:i>999?0:(g=_=>s&&s.slice(--j)==t.slice(j)?g():j)(j=0)>=c?f(t,-~i,c):f(t,-~i,j)||i

Try it online!

I have no idea why it is so complex. But it at least works within 200 bytes.


JavaScript (Node.js), 54 bytes, score 37

f=(t,i)=>require('http').STATUS_CODES[i]==t?i:f(t,-~i)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ You can use i>>9 instead of i>999. \$\endgroup\$
    – Arnauld
    Mar 11 at 8:13
  • \$\begingroup\$ Out of interest, you can score 39 in only 79 bytes: f=(t,i)=>`${require('http').STATUS_CODES[i]}`.endsWith(t.slice(-10))?i:f(t,-~i). \$\endgroup\$
    – Neil
    Mar 11 at 10:50
1
\$\begingroup\$

JavaScript, 63 bytes (Node.js), score 36 for some reason

n=>Object.keys(a=require('http').STATUS_CODES).find(e=>a[e]==n)

Works with ES6 and above.

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

Julia 1.0, 143 135 bytes, score 40

x->Int["Ƙ...Ĭ..ƙ.ƞıƕƐƛ.ǵƚ.ÎĮįƜijǷʃdĭƠÌƖǶơÍƔǸÈƑǴƗƓǹƟËÉe....Ɲ.İ"...][sum(Int[x...])%217%159%117%54]

Try it online!

it could probably be more golfed but good enough for now

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

05AB1E, 30 bytes, score 40

l„ -'_º‡…ƒË :’§¬.¡¤n.‡‚.’™rJ.E

Beats all other answers. No TIO link because the module (Plug.Conn.Status) used here is blocked by TIO.

l„ -'_º‡…...’...’™rJ.E  # trimmed program
l                       # push...
                        # implicit input...
l                       # in lowercase...
       ‡                # with each character in...
 „ -                    # literal...
       ‡                # replaced with corresponding character in...
    '_                  # literal...
      º                 # concatenated with...
    '_                  # literal...
      º                 # reversed
        …...            # push "code :"
            ’...’       # push "plug.conn.status."...
                 ™      # in title case
                  r     # reverse stack
                    .E  # evaluate...
                   J    # joined stack...
                    .E  # as Elixir code

====================

Plug.Conn.Status.code  # full program
Plug.Conn.Status.code  # return HTTP status code with given name
\$\endgroup\$
0
\$\begingroup\$

Java, 32 bytes

n -> HttpStatus.valueOf(n).value()

Using Spring. Plus a couple of megs of libs!

\$\endgroup\$
6
  • 4
    \$\begingroup\$ Welcome to Code Golf! You'll need to make a lambda, a method, or a full program. Also, I'd suggest linking to an online interpreter like TIO. \$\endgroup\$
    – rues
    Mar 11 at 16:16
  • \$\begingroup\$ Welcome to Code Golf! As mentioned by @user, this is a snippet, which we do not allow. However, I believe this can be fixed by adding n-> to the front and changing name to n. \$\endgroup\$ Mar 11 at 16:29
  • 3
    \$\begingroup\$ Also, this challenge has a special scoring which should be included in the header. \$\endgroup\$
    – Arnauld
    Mar 11 at 16:50
  • \$\begingroup\$ Yeah, I wasn't sure I was doing it right. Thanks for going easy on me! \$\endgroup\$
    – jeremyt
    Mar 12 at 19:19
  • 2
    \$\begingroup\$ You don't need the 2 spaces around the -> \$\endgroup\$ Mar 14 at 0:42
0
\$\begingroup\$

R, 131 128 bytes, score 40

`-`=utf8ToInt
c(408:417,0:7+100*1:5%x%!!1:8)[-"+41i@N!>Q      -bTE6 ;?J85 M0IP)F/^]3G*  "==sum(-readLines())%%217%%124]

Try it online!

Unlike many other answers, this one isn't really based on some "magic formula". Here we use modulo hashing simply to convert the byte sum of the input to a unique checksum and then to make it fit within ASCII in order to avoid multi-byte characters (albeit with some unprintables). The lookup string is then just a catalog of these checksums.

Finally, we return a value from the vector of status codes at the position where the checksum matches. The status codes themselves are completely unencoded: Initially, I just used a literal concatenation of relevant ranges c(100:101,200:206,...), but then managed to squeeze off a few extra bytes by declaring a "structured" range encompassing the values x00:x07 for each hundred. However, the savings are rather modest, as we now also have to fill the lookup string with dummy values (whitespace) for missing codes.

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