# Context

At Hogwarts School of Witchcraft and Wizardry, students are sorted into 4 houses, Gryffindor, Ravenclaw, Slytherin and Hufflepuff. This sorting is done by a magical hat, called the Sorting Hat.

# Task

Your task is to code a sorting hat. In other words, you should create some deterministic rule that, given the name of a person, outputs one of the four available houses. (See the output section for a restriction on the rule)

# Input

Input will be a string (representing the student name) in the ascii range [32, 126], the printable characters.

This is not necessarily an English name. The input may be "@_??" and your code should still assign a house.

# Output

For a fixed string (any string of printable ASCII characters), your code should always output the same house, thus your code should be deterministic. The output has to uniquely identify the houses, in any of the following ways:

• returning the full house name, e.g. "Gryffindor" (capitalization doesn't matter)
• returning the house initial, e.g. "G" (capitalization doesn't matter)
• returning the house index, e.g. 0 (you may use any house ordering as long as the indexing is done with 0, 1, 2, 3 or 1, 2, 3, 4 and as long as you specify it in your answer.)

What is more, there are 12 cases that should be as follows:

• the inputs harry, hermione and ron should return gryffindor;
• the inputs luna, cho and penelope should return ravenclaw;
• the inputs draco, crab and goyle should return slytherin;
• the inputs cedric, ernie and hannah should return hufflepuff;

You can either get these 12 inputs as stated, or the 12 inputs where the first letter is upper case (e.g. Harry).

You should also prove that there are other English names in this list that get mapped into each house.

Be sure to include the house that your code assigns to your own codegolf.SE nickname, plus the house rgs or RGS gets assigned to. Bonus imaginary internet points if I get assigned to Ravenclaw!!!

As of now, these answers qualify for the bonus imaginary internet points: G B Ruby answer, ovs Python answer, Kevin Cruijssen Whitespace answer, Jonathan Allan Jelly answer, Nick Kennedy Jelly answer, Kaddath PHP answer, Noodle9 C answer, 640KB x86-16 answer, Guillermo Phillips PHP answer, Jonathan Alan Python 2 answer, Bob Jarvis - Reinstate Monica Clojure answer, Mitchell Spector Bash answer.

# Test cases

"Harry" -> "Gryffindor"
"Hermione" -> "Gryffindor"
"Ron" -> "Gryffindor"
"Luna" -> "Ravenclaw"
"Cho" -> "Ravenclaw"
"Penelope" -> "Ravenclaw"
"Draco" -> "Slytherin"
"Crab" -> "Slytherin"
"Goyle" -> "Slytherin"
"Cedric" -> "Hufflepuff"
"Hannah" -> "Hufflepuff"
"Ernie" -> "Hufflepuff"


This is so shortest submission in bytes, wins! If you liked this challenge, consider upvoting it... And happy golfing!

• Can we use different indices for the houses? (would this be allowed: tio.run/…) – ovs Feb 18 at 9:34
• Crab should really be Crabbe, although potentially a bit late for the answers already written – Nick Feb 18 at 16:21
• if this is purely deterministic should it have the random tag? – 640KB Feb 18 at 17:53
• @NickA Technically it should be vincent. Also goyle should be gregory. – Magma Feb 18 at 19:18
• @JonathanAllan 1 indexing is fine but it might be a bit late for me to allow any four distinct values. Also, it is not admissible that the sorting hat doesn't work for some strings in the ascii range of printable characters, even if it works for many strings. – RGS Feb 19 at 17:23

# Python 2, 30 bytes

Input is lower case name, output is 1 for Gryffindor, 0 for Ravenclaw, 2 for Slytherin and 3 for Hufflepuff.

lambda n:hash(n)%94%69%45%17%4


Try it online!

RGS is in Ravenclaw.

# Python 2, 34 bytes

Takes names in lower case and outputs upper case house initials.

lambda n:'HSHHSRRG'[hash(n)%189%8]


Try it online!

# Python 2, 34 bytes

Input with first letter in upper case, output is the house indices.

lambda n:~hash(n)%74%64%27%16%11%4


Try it online!

Rgs gets assigned to Ravenclaw, Ovs to Gryffindor.

• Really nice job and you got the imaginary points! Also, I replied to your comment about the house indices. – RGS Feb 18 at 13:56
• What am I missing? Why doesn't lambda n:hash(n)%4 work? It's deterministic and always returns a number between 0 and 3 – Cruncher Feb 18 at 22:07
• @Cruncher this wouldn't put the right people together in the same house (e.g. Harry, Hermione and Ron should all be assigned to the same house) – ovs Feb 18 at 22:19
• @ovs Knew I had to have been missing something! Guess I didn't read the whole spec lol – Cruncher Feb 19 at 14:35
• @ovs So how did you find those mods? Somewhat experimentally? – Cruncher Feb 19 at 14:36

# JavaScript (Node.js), 35 bytes

Expects the names in title case. Returns $$\0$/extract_tex] for Gryffindor, $$\1\$$ for Hufflepuff, $$\2\$$ for Slytherin or $$\3\$$ for Ravenclaw. s=>(([a]=Buffer(s))[3]*9|a*553)%9&3  Try it online! # JavaScript (ES6), 40 bytes Returns the house initial in upper case. s=>"SSHGRHGR"[parseInt(s,28)*51%78%10&7]  Try it online! ### How? The base formula that maps our 12 wizard students to the relevant houses is: "SSHGRHGRS?"[parseInt(s, 28) * 51 % 78 % 10]  We first parse the input as Base-28. Valid input strings in this base must consist of an optional leading unary operator (+ or -), followed by a sequence of characters matching [0-9A-Ra-r]+. If the whole string is invalid, it is parsed as $$\NaN\$$. Otherwise, the parsing stops just before the first invalid character. Example: parseInt("harry", 28) == parseInt("harr", 28) // -> 381807  There are, obviously, countless ways of building the hash formula and the corresponding lookup table $$\t\$$. Among all brute-forced formulas, this one was chosen because: • $$\t[8]=t[0]\$$ and we don't care about the value of $$\t[9]\$$, which means that we can apply a final modulo $$\8\$$ to get 8 entries. • This modulo $$\8\$$ can be turned into a bitwise AND with $$\7\$$, which also guarantees that the index will be forced into $$\[0..7]\$$ even if the input string is parsed as $$\NaN\$$ or a negative value. • 34 bytes Including bonus. – G B Feb 18 at 10:47 • @GB You may want to post it as a separate answer. But I think this requires 3 extra bytes to support all inputs. – Arnauld Feb 18 at 10:56 • This is interesting, I know some of the Javascript quirks, but I didn't expect the modulo operation to return a negative int. – G B Feb 18 at 11:37 • @GB Taking the sign of the divisor is needed more common. But quite a few languages use the sign of the dividend. There's a table on Wikipedia summarizing that. – Arnauld Feb 18 at 16:37 • @Arnauld Thanks for making your answer even more complete with the explanation. – RGS Feb 18 at 21:03 # Jelly, 11 8 bytes Updated 8-byter so that the bonus is fulfilled for both 'rgs' and 'RGS' :) “EwS’,4ḥ  A monadic Link accepting a list of characters which yields: 4: Gryffindor 2: Ravenclaw 1: Slytherin 3: Hufflepuff  Try it online! Or see a test-suite showing the 3 given names belonging to each house, that an extra name exists in the linked name-list for each house and that both 'rgs' and 'RGS' are in 2, Ravenclaw. Places 'Jonathan Allan' in Ravenclaw. ### How? “¢Ʋ⁹’,4ḥ - Link: list of characters “EwS’ - base 250 number = 4405084 4 - 4 , - pair ḥ - hash using: 4405084 as a salt, and implicit range(4) = [1,2,3,4] as the domain  # 11-byter: OP%⁽MJ%23%4  A monadic Link accepting a list of characters which yields: 3: Gryffindor 2: Ravenclaw 1: Slytherin 0: Hufflepuff  (Bonus fulfilled for 'rgs') Try it online! Or see a test-suite showing the 3 given names belonging to each house, that an extra name exists in the linked name-list for each house and that 'rgs' is in 2, Ravenclaw. Places 'Jonathan Allan' in Slytherin. ### How? OP%⁽MJ%23%4 - Link: list of characters e.g. 'rgs' O - ordinals [114,103,115] P - product 114 * 103 * 115 = 1350330 ⁽MJ - 20325 20325 % - modulo 1350330 % 20325 = 8880 23 - 23 23 % - modulo 8880 % 23 = 2 4 - 4 4 % - modulo 2 % 4 = 2  Here is a Python script which will print viable i j {G} {R} {S} {H} results for code like OP%i%j%4 for which each of i and j are small enough to write within three bytes. The first result happens to place 'rgs' in Ravenclaw. from functools import reduce a,b,c,d = (['harry', 'hermione', 'ron'], ['luna', 'cho', 'penelope'], ['draco', 'crab', 'goyle'], ['cedric', 'ernie', 'hannah']) pa,pb,pc,pd = ([reduce(lambda x,y:x*y, map(ord,n)) for n in v] for v in (a,b,c,d)) for j in range(5, 32251): for i in range(j, 32251): i+=1 A=set(v%i%j%4 for v in pa) B=set(v%i%j%4 for v in pb) if A&B: continue C=set(v%i%j%4 for v in pc) if A&C or B&C: continue D=set(v%i%j%4 for v in pd) if A&D or B&D or C&D: continue print(i, j, A, B, C, D) break  • Good job! +1 And thanks for sharing your Python script! – RGS Feb 18 at 17:40 • @RGS found one satisfying the bonus for both variants of your moniker given :) – Jonathan Allan Feb 18 at 20:08 • Great job! And you taught me a new word! Had no idea what moniker was :) – RGS Feb 18 at 21:01 • While this is an amazing answer, doesn't the output domain of 1-4 break the explicit rule about indexing? you may use any house ordering as long as the indexing is done with 0, 1, 2, 3 and as long as you specify it in your answer. – Cruncher Feb 19 at 14:42 • @Cruncher - 1-indexing has been allowed. – Jonathan Allan Feb 19 at 17:30 # Ruby, 30 31 bytes ->x{"HSSRGRHHGRR"[x.sum%91%11]}  Try it online! Returns initial of house. RGS is on Ravenclaw • Great work! +1 for this nice ruby submission. – RGS Feb 18 at 13:55 # 05AB1E, 14 12 bytes •Sâ;»•4вs1öè  Outputs 0123 instead of GRSH. -2 bytes thanks to @Grimmy (unfortunately it no longer got the internet bonus for outputting Ravenclaw for RGS). Try it online. Explanation: •Sâ;»• # Push compressed integer 478937616 4в # Convert it to base-4 as list: [1,3,0,2,0,3,0,0,0,0,2,0,1,0,0] s1ö # Take the input, and convert it from base-1 to a base-10 integer # which will essentially sum the indices of the characters in the string "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzǝʒαβγδεζηθвимнт\nΓΔΘιΣΩ≠∊∍∞₁₂₃₄₅₆ !"#%&'()*+,-./:;<=>?@[$^_{|}~Ƶ€Λ‚ƒ„…†‡ˆ‰Š‹ŒĆŽƶĀ‘’“”–—˜™š›œćžŸā¡¢£¤¥¦§¨©ª«¬λ®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
è  # And use that to (modular) index into the earlier created list
# (after which the result is output implicitly)


See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand why •Sâ;»• is 478937616 and •Sâ;»•4в is [1,3,0,2,0,3,0,0,0,0,2,0,1,0,0].

• My name is RGS, which is close to RGB... But I'm being assigned to Gryffindor. GB edited his answer, so maybe check it again! He now gets the bonus imaginary points – RGS Feb 18 at 9:05
• Great port! +1 Now I want it in Java :D – RGS Feb 18 at 9:07
• 12 bytes (no bonus, unfortunately) – Grimmy Feb 18 at 9:29
• @Grimmy Thanks! I know 1ö could be used as an alternative for SO (digit sum), but didn't really knew how it works. Now I do by looking at the Python code of the legacy version. :) – Kevin Cruijssen Feb 18 at 10:11

# Python 2, 24 bytes

lambda n:hash(n)/64779%4


3: Gryffindor
0: Ravenclaw
2: Slytherin
1: Hufflepuff


Bonus fulfilled for 'rgs' while 'Jonathan Allan' is placed in Slytherin.

Try it online!

• Good job working on this one! +1 and congratulations for the bonus imaginary internet points! – RGS Feb 19 at 0:18
• @Belly Buster I'm glad the authors of both Python answers got assigned to Slytherin :-D – qdread Feb 19 at 19:11

# x86-16 machine code, IBM PC DOS, 3732 30 bytes

Binary:

00000000: 92be 8200 ad8a e0ac b3be f7f3 92d4 08bb  ................
00000010: 1601 d7cd 29c3 4853 5252 4753 5252       ....).HSRRGSRR


Build HAT.COM from above using xxd -r.

Unassembled listing:

92          XCHG AX, DX             ; DX = 0
BE 0082     MOV  SI, 82H            ; SI to input string (char*s)
AD          LODSW                   ; AL = s[0], SI = SI + 2
8A E0       MOV  AH, AL             ; AH = s[0]
AC          LODSB                   ; AL = s[2]
B3 BE       MOV  BL, 190            ; divisor = 190
F7 F3       DIV  BX                 ; DX = AX % 190
92          XCHG AX, DX             ; AX = DX
D4 08       AAM  8                  ; AL = AL % 8
BB 011D     MOV  BX, OFFSET S       ; BX = output string table
D7          XLAT                    ; AL = [BX][AL]
CD 29       INT  29H                ; DOS fast console output
C3          RET                     ; return to DOS
S           DB "HSRRGSRR"           ; house char table


A standalone PC DOS executable. Input via command line, output to console is the house initial {"G","R","S","H"}.

All credit goes to @Noodle9, as this is really just a port of that answer. I promise to try harder next time.

I/O:

• Even though it is a port, really nice job! +1 – RGS Feb 18 at 19:20
• @RGS, well Noodle9 says you can be in Ravenclaw, so it's okay by me too. – 640KB Feb 18 at 20:01
• Really good job! Hehe :D – RGS Feb 18 at 20:03

# PHP, 363331 29 bytes

<?=467921>>crc32($argn)%20&3;  Try it online! I'm in danger of turning into a one trick pony. 2=Gryffindor, 1=Ravenclaw, 0=Slytherin, 3=Hufflepuff I'm in Ravenclaw along with @RGS! • Cool submission! +1 If I understand correctly, I am in Ravenclaw? – RGS Feb 18 at 22:33 • You are indeed. Output formatting's not obvious, but needs must, sorry about that. – Guillermo Phillips Feb 18 at 22:36 • don't worry! I just wanted to confirm it before linking to your answer in my challenge :) good job on getting the bonus imaginary internet points! – RGS Feb 18 at 22:39 • Gryffindor..... – S.S. Anne Feb 20 at 22:26 # Python 3.8, 18 bytes Sharing because it's an amusing solution! If invoked with the following environment variable PYTHONHASHSEED=895984 (apparently this does not have to be counted towards byte length), lambda s:hash(s)%4  Try it online! given lowercase input, • 0 => Gryffindor • 1 => Hufflepuff • 2 => Ravenclaw • 3 => Slytherin RGS (and rgs) goes to Ravenclaw, chinatsu goes to Gryffindor. In the range [0, 895984] there are 3 good seeds, 139840, 330811, and 895984. Only the latter places RGS in Ravenclaw. • I like this solution :D thanks for this – RGS Mar 19 at 16:18 ## Wd, 19 18 bytes Port of G B's answer. (RGS is also on Ravenclaw.) BTW, my name can't be entered in the W interpreter, so I do not belong in any house. • I forgot that the operator overloading exists, so -1 byte due to the order-free indexing. r#↔X┌3ÇMQyΘf○ºÞΘ☺¬  Uncompressed: CJ91m11m"HSSRGR HGRR"[  ## Explanation C % Convert the input to a list of characters J % Reduce the list by addition 91m % Modulus by 91 11m"HSSRGR HGRR"[ % Cyclic indexing into the string  • I'm assuming there is no TIO link? Also, GBs answer has a problem, so yours might have it as well – RGS Feb 18 at 8:58 • My answer is fixed (I can't count to 11, it seems) – G B Feb 18 at 9:03 # Python 2, 25 bytes lambda n:hash(n)%814329%4  Try it online! Firstly, forgive me for mostly ripping off ovs's answer but this is my first ever golf "putt", so I'm taking it for posting practice! 2: Gryffindor 3: Ravenclaw 1: Slytherin 0: Hufflepuff RGS -> Slytherin and Belly Buster -> Slytherin! • Good job on your "golf putt"! +1 for the nice solution – RGS Feb 18 at 23:34 • +1, nicely done; sorry to have pipped your score – Jonathan Allan Feb 18 at 23:41 # C (clang), 50 $$\\cdots\$$ 47 42 bytes Added a byte to fix a bug kindly pointed out by RGS. Saved 2 bytes thanks to S.S. Anne!!! Saved 5 bytes thanks to ceilingcat!!! #define f(s)"HSRRGSRR"[(*s<<8|s[2])%190%8]  Try it online! Inputs a capitalised name string and returns G, H, S, or R. RGS is in Ravenclaw!!! • Thanks for your submission +1 :) it is just a pity that I can't be in Ravenclaw, but that is ok :) – RGS Feb 18 at 19:03 • @RGS The Hat hears your preference for Ravenclaw and puts you in Ravenclaw! :D – Noodle9 Feb 18 at 19:49 • Why'd you have to post an answer before I could? – S.S. Anne Feb 18 at 20:32 • @S.S.Anne Because it's the Sorting Hat!!! :))) – Noodle9 Feb 18 at 20:38 • 47 bytes abuses bitwise ops and wide strings. – S.S. Anne Feb 18 at 20:45 # Whitespace, 295 bytes [S S S N _Push_0][N S S T T N _Create_Label_LOOP][S N S _Dupe][S N S _Dupe][T N T S _Read_STDIN_as_character][T T T _Retrieve_input][S N S _Dupe_input][S S S T S T S N _Push_10][T S S T _Subtract][N T S T S N _If_0_Jump_to_Label_DONE][T S S S _Add][N S N T T N _Jump_to_Label_LOOP][N S S T S N _Create_Label_DONE][S N N _Discard][S S S T S T T S T T N _Push_91][T S T T _Modulo][S S S T S T T N _Push_11][T S T T _Modulo][S N S _Dupe][N T S S S N _If_0_Jump_to_Label_HUFFELPUFF][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S T N _If_0_Jump_to_Label_SLYTHERIN][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S T N _If_0_Jump_to_Label_SLYTHERIN][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S N _If_0_Jump_to_Label_RAVENCLAW][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S S N _If_0_Jump_to_Label_GRYFFINDOR][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S N _If_0_Jump_to_Label_RAVENCLAW][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S N _If_0_Jump_to_Label_RAVENCLAW][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S S S N _If_0_Jump_to_Label_HUFFELPUFF][S S S T N _Push_1][T S S T _Subtract][S N S _Dupe][N T S S N _If_0_Jump_to_Label_GRYFFINDOR][N S S N _Create_Label_RAVENCLAW][S S S T N _Push_1][T N S T _Print_as_integer][N N N _Exit_Program][N S S S N _Create_Label_GRYFFINDOR][T N S T _Print_as_integer][N N N _Exit_Program][N S S T N _Create_Label_SLYTHERIN][S S S T S N _Push_2][T N S T _Print_as_integer][N N N _Exit_Program][N S S S S N _Create_Label_HUFFELPUFF][S S S T T N _Push_3][T N S T _Print_as_integer]  Letters S (space), T (tab), and N (new-line) added as highlighting only. [..._some_action] added as explanation only. Port of @GB's Ruby answer. Since Whitespace inputs one character at a time, the input should contain a trailing newline (\n) so it knows when to stop reading characters and the input is done. Try it online (with raw spaces, tabs and new-lines only). Explanation in pseudo-code: Integer sum = 0 Start LOOP: Integer c = STDIN as character If(c == '\n'): Jump to Label DONE sum = sum + c Go to next iteration of LOOP Label DONE: sum = sum modulo-91 sum = sum modulo-11 If(sum == 0): Jump to Label HUFFELPUFF If(sum-1 == 0): Jump to Label SLYTHERIN If(sum-2 == 0): Jump to Label SLYTHERIN If(sum-3 == 0): Jump to Label RAVENCLAW If(sum-4 == 0): Jump to Label GRYFFINDOR If(sum-5 == 0): Jump to Label RAVENCLAW If(sum-6 == 0): Jump to Label RAVENCLAW If(sum-7 == 0): Jump to Label HUFFELPUFF If(sum-8 == 0): Jump to Label GRYFFINDOR Label RAVENCLAW: Integer n = 1 Print n as integer to STDOUT Exit program Label GRYFFINDOR: Print top (sum-4 or sum-8) as integer to STDOUT Exit program Label SLYTHERIN: Integer n = 2 Print n as integer to STDOUT Exit program Label HUFFELPUFF: Integer n = 3 Print n as integer to STDOUT  • +1 for this really interesting submission! and you get bonus imaginary internet points! – RGS Feb 18 at 13:58 # Zsh, 66 bytes case$1 in ?ra*|g*)<<<S;;[lp]*|cho)<<<R;;h?r*|r*)<<<G;;*)<<<H;esac


Try it online!

No hash functions available, so we make do with pattern matching in a single case statement:

case $1 in ?ra*|g*) <<< S ;; [lp]*|cho) <<< R ;; h?r*|r*) <<< G ;; *) <<< H # last branch doesn't need ;; esac  • Cool submission! +1 for your work :D – RGS Feb 18 at 14:02 # Retina 0.8.2, 36 bytes \B(u|h|p|ra|oy|nn|edr|rni)$.&$* 31  Try it online! Link includes test suite. Outputs the house index. Neil and rgs both map to index 0. Explanation: \B(u|h|p|ra|oy|nn|edr|rni)$.&$*  Replace each of the scoring letters with 1s. The \B means that the first letter never counts as a scoring letter, allowing it to be upper or lower case. 31  Count the number of scoring letters, up to 3. • Thanks for your submission! Regex for the win, isn't it? Too bad I don't get bonus imaginary internet points... But I can't imagine how you could get them without spending bytes. +1 – RGS Feb 18 at 14:24 # PHP, 43 bytes <?='RSHGGGHSHRSGRRSGHHRS'[crc32($argn)%20];


Try it online!

I wanted to do something else than a port.. better but maybe I can do better, when I have time. And this time with bonus points! I'm Griffindor without my capital ;) (Hacks not to be Hufflepuff)

Takes input with Capital letter and returns house initial letter (works with any string input actually, but the result will change)

EDIT: changed a not meaningful G to a S for equal representation between G and S

EDIT 2: saved 10 bytes with a longer string, and ran for the double extra points!! Houses are equally reprensented for meaningless values.

• Cool submission! It's just too bad you can't get the bonus imaginary internet points... +1 – RGS Feb 18 at 14:24
• @RGS much better version, and you got your house with both names, capital or not ;) – Kaddath Feb 18 at 14:47
• Indeed! Good job on this one! :D – RGS Feb 18 at 17:43

# Jelly, 16 bytes

OḄ%19ị“®5ƭ{~’ḃ4¤


Try it online!

A monadic link taking a string or list of strings and returning a 1-indexed number corresponding to Gryffindor, Ravenclaw, Slytherin, Hufflepuff.

"rgs" gets sorted into Ravenclaw.

• Good job! ANd you got some bonus imaginary internet points as well! +1 – RGS Feb 18 at 14:03

# Ruby, 28 bytes

->n{296887>>n.sum%20%11*2&3}


Try it online!

Returns 2310 instead of GRSH. RGS is on 1=S, I am on 2=G.

• Thanks for your submission. I'm upvoting it even though I am not on Ravenclaw :) – RGS Feb 18 at 23:34

# APL (Dyalog Unicode), 23 24 bytesSBCS

'GSGHSSRRH'⊃⍨9|15|19|⍋⊥⍒


Try it online!

Some number digging magic using three functions unique to APL:

• Grade up ⍋X: Indices to reorder the array X into ascending order
• Mixed base X⊥Y: Convert array Y from base X to integer
• Grade down ⍒X: Indices to reorder the array X into descending order

Interestingly, modulo 15 doesn't guarantee successful indexing into a length-10 list, yet both rgs and bubbler fit into the list nicely. I missed the input range, so I added 9| in the modulo chain to fix it at the cost of 1 byte. rgs goes to Slytherin; I go to Hufflepuff.

• Thanks for your submission! Unfortunately your code doesn't work for the input string john, so it doesn't meet the requirements! The sorting hat should assign a house to any string in the ascii range specified :/ – RGS Feb 18 at 14:00
• @RGS Sorry, I missed the input range. Luckily it is fixable at the cost of 1 byte. – Bubbler Feb 18 at 23:16
• Thanks for taking the time to fix it! +1 for your submission! – RGS Feb 18 at 23:33
• If this is mod 9 then you can remove the trailing H. – S.S. Anne Feb 20 at 22:24
• @S.S.Anne No, the code assumes ⎕IO←0 (I should have mentioned that), and all characters from indexes 0 to 8 (inclusive) are used. – Bubbler Feb 20 at 23:04

# Clojure - 186 bytes

Since everyone else seems to have settled on somewhat similar algorithms I boldly went where no one wanted to go before (that I noticed)!

Takes the string, converts it to individual characters, sums up the character values. Has precomputed special cases for the desired assignments. For all other names takes the character sum, mod 4, to get a number in [0..3]. 0 = Gryffindor, 1 = Ravenclaw, 2 = Slytherin, 3 = Hufflepuff.

Golfed version

(defn s[m](let[n(apply + (map int (into [] (clojure.string/upper-case m))))p {390 0,599 0,239 0,1973 0,304 1,218 1,600 1,361 2,280 2,384 2,426 3,430 3,371 3,236 1}](or (p n) (mod n 4))))

Ungolfed version

Adds precomputed values for other versions of the character's names (e.g. accepts "Harry", "Harry Potter", and "Potter" for The Boy Who Lived, and so on), and also returns the full house name instead of a number:

(defn sorting-hat [name]
(let [ n          (apply + (map int (into [] (clojure.string/upper-case name))))
houses     [ "Gryffindor" "Ravenclaw" "Slytherin" "Hufflepuff" ]
name-map   { 390 0, 900 0, 478 0, 599 0, 1149 0,  518 0, 239 0, 809 0, 1018 0, 538 0, 1973 0,
304 1, 943 1, 218 1, 603 1,  600 1, 1378 1,
361 2, 849 2, 456 2, 280 2,  415 2,  982 2, 384 2, 959 2,
426 3, 991 3, 430 3, 906 3,  371 3, 1057 3, 236 1 }
house      (name-map n)                                                              ; house derived from special cases
house2     (mod n 4)]
(houses (or house house2))))


Test harness:

(doseq [ person  ["Harry"  "Hermione" "Ron"
"Luna"   "Cho"      "Penelope"
"Draco"  "Crab"     "Goyle"
"Cedric" "Hannah"   "Ernie"
"RGS"                            ; poster's codegolf nickname
"Bob Jarvis - Reinstate Monica"  ; my codegolf nickname
"Ackerley" "Ealasaid" "Icarus" "Mabel" "Qing" "Ulbrecht" "Yardley"] ]  ; other names
(println person " -> "(s person)))


Test results (using golfed version):

Harry  ->  0
Hermione  ->  0
Ron  ->  0
Luna  ->  1
Cho  ->  1
Penelope  ->  1
Draco  ->  2
Crab  ->  2
Goyle  ->  2
Cedric  ->  3
Hannah  ->  3
Ernie  ->  3
RGS  ->  1
Bob Jarvis - Reinstate Monica  ->  0
Ackerley  ->  0
Ealasaid  ->  0
Icarus  ->  3
Mabel  ->  1
Qing  ->  3
Ulbrecht  ->  1
Yardley  ->  2


Note that OP is assigned to Ravenclaw. I'm in Gryffindor.

Try It Online! (golfed version)

• Cool answer +1! But maybe going where no one went means you end up spending some more bytes, no? – RGS Feb 22 at 11:26
• I (nearly) always use Clojure for puzzles/golfing. I know that with Clojure I won't win any prizes for brevity, so my goal is to go for beauty, grace, and style. And learning things - such as finding out as part of this solution that the or macro in Clojure functions more-or-less the same as COALESCE in SQL - is just an added bonus :-) – Bob Jarvis - Reinstate Monica Feb 22 at 16:38

# Bash, 78 bytes (& bonus imaginary Internet points!)

sortinghat:

o()(printf %d "'${s:$1}")
s=$1 h=HSSGGRSHRHSRGGHHR echo${h:(o-o -1)%13:1}


Try it online!

Input is passed as an argument in all lower-case, and output (G, R, S, or H) is on stdout.

Test program:

for x in %GRYFFINDOR-TEST harry hermione ron %RAVENCLAW-TEST luna cho penelope rgs %SLYTHERIN-TEST draco crab goyle %HUFFLEPUFF-TEST cedric ernie hannah %OTHER-SAMPLE-NAMES minerva newton myrtle salazar
do
if test "${x:0:1}" = '%' then echo "${x:1}"
else
printf "%12s " "$x" ./sortinghat "$x"
fi
done


Output of test program:

GRYFFINDOR-TEST
harry  G
hermione  G
ron  G
RAVENCLAW-TEST
luna  R
cho  R
penelope  R
rgs  R
SLYTHERIN-TEST
draco  S
crab  S
goyle  S
HUFFLEPUFF-TEST
cedric  H
ernie  H
hannah  H
OTHER-SAMPLE-NAMES
minerva  G
newton  H
myrtle  R
salazar  S


The extra sample names are all in OP's list of names, and I think they're even sorted into the right houses (according to the HP books)! (I get sorted into Gryffindor if you put my name in all lower-case like the others.)

• Really nice job on this one! +1 And congratz for the bonus imaginary internet points :D – RGS Feb 23 at 0:55

# Clojure - 124 bytes

## Solution

(defn f[n](if-let[k({:harry 3 :hermione 3 :cho 0 :crab 1 :ernie 2}(keyword(clojure.string/lower-case n)))]k(mod(count n)4)))

Gryffindor 3 Rawenclaw 0 Slytherin 1 Hufflepuff 2

## Explanation

The algorithm takes the modulo 4 length of the name and assigns a house based on that. Exceptions are made for the special cases for the few names that would not get to the predetermined house in this way (Harry, Hermione, Cho, Crab, Ernie).

## Test

(deftest a-test
(testing "known-cases"
(is (= 3 (f "Harry")))
(is (= 3 (f "Hermione")))
(is (= 3 (f "Ron")))

(is (= 0 (f "Luna")))
(is (= 0 (f "Cho")))
(is (= 0 (f "Penelope")))

(is (= 1 (f "Draco")))
(is (= 1 (f "Crab")))
(is (= 1 (f "Goyle")))

(is (= 2 (f "Cedric")))
(is (= 2 (f "Hannah")))
(is (= 2 (f "Ernie")))

)
(testing "other-names"
(is (= 0 (f "Ackerley")))
(is (= 1 (f "Acton")))
(is (= 2 (f "Africa")))
(is (= 3 (f "Addison")))

(is (= 3 (f "Attilio")))
(is (= 3 (f "RGS")))
)
)
`