The Sorting Hat

51

5

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!

RGS

Posted 2020-02-18T07:17:20.720

Reputation: 5 047

@ovs I will allow it and edit the challenge accordingly. – RGS – 2020-02-18T13:52:22.693

17Crab should really be Crabbe, although potentially a bit late for the answers already written – Nick – 2020-02-18T16:21:20.227

2What's beyond 127 in the ASCII table? – S.S. Anne – 2020-02-18T16:23:41.490

@NickA geez, you are absolutely right! ahaha sorry for that one! And I call myself a Harry Potter fan :/ Well, I don't want to edit the question now because it might ruin some of the answers... – RGS – 2020-02-18T17:44:56.603

6if this is purely deterministic should it have the random tag? – 640KB – 2020-02-18T17:53:14.937

The idea was that you could pick a random function from strings to the set {0,1,2,3}. Do you think it is not appropriate? What would you suggest? – RGS – 2020-02-18T17:55:04.450

6@NickA Technically it should be vincent. Also goyle should be gregory. – Magma – 2020-02-18T19:18:49.330

@Magma I think calling him "crab" is worse than calling him "crabbe" :) – RGS – 2020-02-18T19:19:40.167

@Noodle9 nice catch! Fixed it – RGS – 2020-02-19T07:29:53.140

"as long as the indexing is done with 0, 1, 2, 3" - can we please use 1-indexing? Also how about allowing any four consistent, distinct values? Lastly if all the listed names provide satisfactory outputs and we show four names from the linked name list map to the houses, can other names be assigned produce different output (not one of the four houses)? – Jonathan Allan – 2020-02-19T14:57:20.457

1@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 – 2020-02-19T17:23:58.673

Thanks, could you clarify indexing and "You should also prove that there are other English names" bits in the question (the latter implies we may have other strings which map elsewhere IMO) – Jonathan Allan – 2020-02-19T17:27:15.063

1@JonathanAllan My interpretation of that rule is that there needs to be some (not necessarily uniform) distribution across the houses and not just return Gryffindor for everything that isn't a special input. The statement is just to prove that your program actually does that – Cruncher – 2020-02-19T17:47:05.377

@JonathanAllan thanks for your feedback! I tried making the challenge more clear, but my intention was exactly as Cruncher said :) – RGS – 2020-02-19T19:36:46.583

@S.S.Anne - 128 :-) – Bob Jarvis - Reinstate Monica – 2020-02-20T22:03:44.647

@Bob ASCII is a 7-bit character set. There is no 128. – S.S. Anne – 2020-02-20T22:08:17.583

Answers

15

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.

ovs

Posted 2020-02-18T07:17:20.720

Reputation: 21 408

Really nice job and you got the imaginary points! Also, I replied to your comment about the house indices. – RGS – 2020-02-18T13:56:25.810

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 – 2020-02-18T22:07:49.940

1@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 – 2020-02-18T22:19:07.573

@ovs Knew I had to have been missing something! Guess I didn't read the whole spec lol – Cruncher – 2020-02-19T14:35:53.250

@ovs So how did you find those mods? Somewhat experimentally? – Cruncher – 2020-02-19T14:36:17.337

@Cruncher I have written a program that, given disjoint sets of integers, find s modulo operation, such that the resulting sets are still disjoint and the resulting numbers are in a small range. I still have to try out different number of modulo operation and different ranges for these numbers. And there are different ways of generating the initial integers from the name, e.g. hash(n), int(n,36), ~hash(n) ..., all will lead to different results. – ovs – 2020-02-19T18:05:01.717

12

JavaScript (Node.js), 35 bytes

Expects the names in title case. Returns \$0\$ 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.

Arnauld

Posted 2020-02-18T07:17:20.720

Reputation: 111 334

34 bytes Including bonus. – G B – 2020-02-18T10:47:49.953

@GB You may want to post it as a separate answer. But I think this requires 3 extra bytes to support all inputs.

– Arnauld – 2020-02-18T10:56:32.983

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 – 2020-02-18T11:37:25.993

1

@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 – 2020-02-18T16:37:31.827

1@Arnauld Thanks for making your answer even more complete with the explanation. – RGS – 2020-02-18T21:03:38.910

12

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

Jonathan Allan

Posted 2020-02-18T07:17:20.720

Reputation: 67 804

Good job! +1 And thanks for sharing your Python script! – RGS – 2020-02-18T17:40:13.900

@RGS found one satisfying the bonus for both variants of your moniker given :) – Jonathan Allan – 2020-02-18T20:08:10.190

Great job! And you taught me a new word! Had no idea what moniker was :) – RGS – 2020-02-18T21:01:59.517

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 – 2020-02-19T14:42:56.477

@Cruncher 1-indexing is allowed by default, although that text does appear to override that so I've asked OP (I actually would think it best to allow any 4 consistent, distinct values). – Jonathan Allan – 2020-02-19T14:59:54.067

1@Cruncher - 1-indexing has been allowed. – Jonathan Allan – 2020-02-19T17:30:22.323

8

Ruby, 30 31 bytes

->x{"HSSRGRHHGRR"[x.sum%91%11]}

Try it online!

Returns initial of house. RGS is on Ravenclaw

G B

Posted 2020-02-18T07:17:20.720

Reputation: 11 099

Great work! +1 for this nice ruby submission. – RGS – 2020-02-18T13:55:27.797

6

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].

Kevin Cruijssen

Posted 2020-02-18T07:17:20.720

Reputation: 67 575

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 – 2020-02-18T09:05:03.003

Great port! +1 Now I want it in Java :D – RGS – 2020-02-18T09:07:13.963

112 bytes (no bonus, unfortunately) – Grimmy – 2020-02-18T09:29:06.357

@Grimmy Thanks! I know 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 – 2020-02-18T10:11:09.763

6

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!

Jonathan Allan

Posted 2020-02-18T07:17:20.720

Reputation: 67 804

Good job working on this one! +1 and congratulations for the bonus imaginary internet points! – RGS – 2020-02-19T00:18:51.870

1@Belly Buster I'm glad the authors of both Python answers got assigned to Slytherin :-D – qdread – 2020-02-19T19:11:31.567

5

x86-16 machine code, IBM PC DOS, 37 32 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:

enter image description here

enter image description here

640KB

Posted 2020-02-18T07:17:20.720

Reputation: 7 149

1Even though it is a port, really nice job! +1 – RGS – 2020-02-18T19:20:20.593

1@RGS, well Noodle9 says you can be in Ravenclaw, so it's okay by me too. – 640KB – 2020-02-18T20:01:22.247

Really good job! Hehe :D – RGS – 2020-02-18T20:03:29.947

5

PHP, 36 33 31 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!

Guillermo Phillips

Posted 2020-02-18T07:17:20.720

Reputation: 561

Cool submission! +1 If I understand correctly, I am in Ravenclaw? – RGS – 2020-02-18T22:33:27.513

You are indeed. Output formatting's not obvious, but needs must, sorry about that. – Guillermo Phillips – 2020-02-18T22:36:45.520

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 – 2020-02-18T22:39:00.333

Gryffindor..... – S.S. Anne – 2020-02-20T22:26:39.650

4

W d, 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

a'_'

Posted 2020-02-18T07:17:20.720

Reputation: 1 099

I'm assuming there is no TIO link? Also, GBs answer has a problem, so yours might have it as well – RGS – 2020-02-18T08:58:41.920

My answer is fixed (I can't count to 11, it seems) – G B – 2020-02-18T09:03:07.173

4

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!!!

Noodle9

Posted 2020-02-18T07:17:20.720

Reputation: 2 776

Thanks for your submission +1 :) it is just a pity that I can't be in Ravenclaw, but that is ok :) – RGS – 2020-02-18T19:03:05.073

1@RGS The Hat hears your preference for Ravenclaw and puts you in Ravenclaw! :D – Noodle9 – 2020-02-18T19:49:12.307

Why'd you have to post an answer before I could? – S.S. Anne – 2020-02-18T20:32:44.493

@S.S.Anne Because it's the Sorting Hat!!! :))) – Noodle9 – 2020-02-18T20:38:09.533

47 bytes abuses bitwise ops and wide strings. – S.S. Anne – 2020-02-18T20:45:06.713

4

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!

Belly Buster

Posted 2020-02-18T07:17:20.720

Reputation: 141

Good job on your "golf putt"! +1 for the nice solution – RGS – 2020-02-18T23:34:52.287

+1, nicely done; sorry to have pipped your score – Jonathan Allan – 2020-02-18T23:41:57.153

3

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

Kevin Cruijssen

Posted 2020-02-18T07:17:20.720

Reputation: 67 575

+1 for this really interesting submission! and you get bonus imaginary internet points! – RGS – 2020-02-18T13:58:06.563

3

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

GammaFunction

Posted 2020-02-18T07:17:20.720

Reputation: 2 838

Cool submission! +1 for your work :D – RGS – 2020-02-18T14:02:37.163

3

Retina 0.8.2, 36 bytes

\B(u|h|p|ra|oy|nn|edr|rni)
$.&$*
3`1

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.

3`1

Count the number of scoring letters, up to 3.

Neil

Posted 2020-02-18T07:17:20.720

Reputation: 95 035

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 – 2020-02-18T14:24:00.993

2

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.

Kaddath

Posted 2020-02-18T07:17:20.720

Reputation: 449

Cool submission! It's just too bad you can't get the bonus imaginary internet points... +1 – RGS – 2020-02-18T14:24:55.390

@RGS much better version, and you got your house with both names, capital or not ;) – Kaddath – 2020-02-18T14:47:32.937

Indeed! Good job on this one! :D – RGS – 2020-02-18T17:43:23.737

1

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.

Bubbler

Posted 2020-02-18T07:17:20.720

Reputation: 16 616

2Thanks 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 – 2020-02-18T14:00:52.277

@RGS Sorry, I missed the input range. Luckily it is fixable at the cost of 1 byte. – Bubbler – 2020-02-18T23:16:28.317

Thanks for taking the time to fix it! +1 for your submission! – RGS – 2020-02-18T23:33:15.760

If this is mod 9 then you can remove the trailing H. – S.S. Anne – 2020-02-20T22:24:01.137

@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 – 2020-02-20T23:04:14.740

1

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.

Nick Kennedy

Posted 2020-02-18T07:17:20.720

Reputation: 11 829

Good job! ANd you got some bonus imaginary internet points as well! +1 – RGS – 2020-02-18T14:03:07.997

1

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.

Level River St

Posted 2020-02-18T07:17:20.720

Reputation: 22 049

Thanks for your submission. I'm upvoting it even though I am not on Ravenclaw :) – RGS – 2020-02-18T23:34:02.020

1

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)

Bob Jarvis - Reinstate Monica

Posted 2020-02-18T07:17:20.720

Reputation: 544

Cool answer +1! But maybe going where no one went means you end up spending some more bytes, no? – RGS – 2020-02-22T11:26:26.360

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 – 2020-02-22T16:38:12.070

1

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.)

Mitchell Spector

Posted 2020-02-18T07:17:20.720

Reputation: 3 392

Really nice job on this one! +1 And congratz for the bonus imaginary internet points :D – RGS – 2020-02-23T00:55:34.237

0

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")))
    )   
  )

Attilio

Posted 2020-02-18T07:17:20.720

Reputation: 131