title: The Sorting Hat

text:
# Question
Title: The Sorting Hat
# 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!

# Answer
> 16 votes
# 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.

# Answer
> 12 votes
# 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.

# Answer
> 12 votes
# 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

```

# Answer
> 8 votes
# Ruby, ~~30~~ 31 bytes

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

```

Try it online!

Returns initial of house. RGS is on Ravenclaw

# Answer
> 6 votes
# 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]`.

# Answer
> 6 votes
# 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:**

# Answer
> 6 votes
# 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!**

# Answer
> 5 votes
# 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!

# Answer
> 5 votes
# 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!

# Answer
> 5 votes
# 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.

# Answer
> 4 votes
## `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

```

# Answer
> 4 votes
# 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!!!

# Answer
> 3 votes
# 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

```

# Answer
> 3 votes
# 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

```

# Answer
> 3 votes
# 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 `1`s. 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.

# Answer
> 2 votes
# 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.

# Answer
> 1 votes
# 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.

# Answer
> 1 votes
# 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.

# Answer
> 1 votes
# 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`.

# Answer
> 1 votes
# 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)

# Answer
> 1 votes
# 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.)

# Answer
> 0 votes
# 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")))
    )
  )

```

---
Tags: code-golf
---


title: Walk home one step at a time

text:
# Question
Title: Walk home one step at a time
You're at integer coordinates \\$(x,y)\\$ facing one of North, South, East, or West. Your goal is to walk home to \\$(0,0)\\$. At each step, you may do one of:

* Walk one step in the current facing direction, that is to whichever of \\$(x+1,y)\\$, \\$(x-1,y)\\$, \\$(x,y-1)\\$, or \\$(x,y+1)\\$ you're facing.
* Rotate 90 degrees left, staying in place.
* Rotate 90 degrees right, staying in place.

Your goal is to write code that will eventually get you home to \\$(0,0)\\$ if called repeatedly, each time with your current position and facing. Your code must always give the same output for a given input, which precludes using randomness or past state.

**Input:**

Two integers \\$(x,y)\\$ and a facing direction. The 4 possible facing directions are given as numbers 0 through 3, or alternatively 1 through 4, matched as you choose. The position can also be taken as a vector or point or complex number.

You won't be given \\$(0,0)\\$ where you're already home. Don't worry about overflows caused by huge inputs.

**Output:**

One of three distinct consistent outputs corresponding to the possible actions of walking straight, turning left, and turning right.

# Answer
> 15 votes
# Haskell, 21 bytes

```
(!!).([(<0),(>0)]<*>)

```

Try it online!

Outputs a boolean with `True` being move forward and `False` being turn right.

# Haskell, 28 bytes

Here's a version that is easy to understand / translate into any language.

```
f(x,y)d=[x<0,y<0,x>0,y>0]!!d

```

Try it online!

## Explanation

The idea here is two-fold

* We notice that we only ever need to turn in one direction. A turn left is just 3 turns right. So we will limit ourselves to only right turns.
* Now we notice that given a direction there is a simple condition that can check if we ought to move forward. Namely the sign of one of the two variables.

With this information we construct out solution, by making a list of the conditions and indexing the list with the direction. `True` means the condition was passed and we can move forward (so we do), `False` means the condition was failed and we should not move forward, so we rotate.

Now the specification allows us to just output these values as is, since they are distinct and we have no intention of turning left.

# Answer
> 7 votes
# Pyth, 7 bytes

```
qi<L0E2

```

Try it online!

Input is in the form:

```
3
[3, 4]

```

The solution is simple:

* `<L0E` maps each coordinate to `0` if the coordinate is positive, and `1` if the coordinate is nonpositive.
* `i ... 2` converts the list to a number by interpreting it as binary.
* `q` checks whether the resulting number is equal to the other input.
* `True` means forward, `False` means turn, the direction is irrelevant, the third output is irrelevant.

We use the following mapping:

* `0`: up - the positive y direction.
* `1`: right - the positive x direction.
* `2`: left - the negative x direction.
* `3`: down - the negative y direction.

The path the walk takes is a sort of a staircase - from the `(-, -)` quadrant to `(-, 1)` to `(1, 1)` to `(0, 1)` to `(0, 0)` for instance.

# Answer
> 4 votes
# Python 2, 30 bytes

```
lambda i,d:abs(i+1j**d)<abs(i)

```

Try it online!

Takes as input a Gaussian integer for position, and an integer in `{0,1,2,3}` for the direction; outputs `True` for forward, `False` for rotate counter-clockwise, and whatever you like for rotate clockwise, because that never happens :).

# Answer
> 4 votes
# Jelly, 4 bytes

```
>-Ḅ⁼

```

Try it online!

A dyadic link taking the co-ordinates as the left argument and the direction faced as the right. Returns `0` for turn and `1` for move forwards.

The TIO footer picks a random starting point and demonstrates that the link will ultimately reach `[0,0]`

Based on @isaacg’s Pyth answer so be sure to upvote that one too!

## Explanation

```
>-   | Greater than -1
  Ḅ  | Convert from binary time decimal integer
   ⁼ | Equal to right argument

```

# Answer
> 3 votes
# , <sup>~~12~~</sup> 11 bytes

```
[>&|[+0j1^]

```

Try it online!

## idea

Our idea is simple: Walk straight, and see if that gets us closer in Euclidean distance. If yes, return "walk straight". If not, return "turn left".

## input / output

Take position as a complex number (left arg) and direction as a 0-indexed int (right arg). Similar to @PostRockGarfHunter's answer, we constrain our output to two values:

1. `1` \- Walk straight
2. `0` \- Turn left

## how

1. `[+0j1^]` First we convert our right arg integer to a complex number by raising *i* `0j1` to the right arg `0j1^]`. Then we add that `+` to the left arg `[`. This represents our "next position", if we were to walk straight.
2. `[>&|` Is the left arg `[` (current position) greater than `>` the next position after converting both to Euclidean distance from origin `&|`?

# Answer
> 3 votes
# APL (Dyalog Classic), ~~10~~ 9 bytes

```
⊣⊃0(>,<)⊢

```

Try it online!

all credit to Post Rock Garf Hunter's answer

the tio link shows numbers of steps for the square area around (0,0) for the 4 initial directions

left arg: direction

right arg: coord pair

`,` concatenation

`0(>,<)⊢` is equivalent to `(0>⊢),(0<⊢)`, i.e. the 4-vector `(0>x),(0>y),(0<x),(0<y)`

`⊣⊃`.. indexing with the left arg

# Answer
> 3 votes
# JavaScript (Node.js), 26 25 24 bytes

```
(x,y,d)=>--d%2*x<--d%2*y

```

Try it online!

`d` is direction one of `[0, 1, 2, 3]` for \[west, north, east, south\]

The expression
`(d - 1) % 2` gives `deltaX` one of `[-1, 0, 1, 0]`and
`(d - 2) % 2` gives `deltaY` one of `[0, -1, 0, 1]`

Either `x * deltaX` or `y * deltaY` will be non zero and will be negative if we are heading towards home. So if
`(deltaX * x + deltaY * y < 0)` also expressed as
`(deltaX * x < deltaY * -y)` we go forward = `true`, else we turn left = `false`.

To get to 24 I swapped north and south to change '-y' to 'y'

# Answer
> 2 votes
# JavaScript (ES6),  ~~28~~  27 bytes

Takes input as `(x,y,d)` with \\$d=0\\$ for *North*, \\$1\\$ for *South*, \\$2\\$ for *West*, \\$3\\$ for *East*.

Output:

* *true* : turn right
* *false* : walk straight

```
(x,y,d)=>(x&&2|x<0||y<0)!=d

```

Try it online!

### How?

This is parsed as:

```
           +--------------------> 0 if x = 0, 3 if x < 0, 2 if x > 0
           |                +---> 1 if the first expression is 0 and y < 0, 0 otherwise
   ________|_______        _|_
  /                \      /   \
((x && (2 | (x < 0))) || (y < 0)) != d

```

# Answer
> 1 votes
# Retina 0.8.2, ~~38~~ 35 bytes

```
. (-?).*( -?).*
$*-$2$1$1
^(-*) \1$

```

Try it online! Link includes demonstration of path taken from `5 3` to the origin. Takes input as direction first, then coordinates. Edit: Saved 3 bytes by porting @isaacg’s Pyth answer. Direction encodes as `y--`, `x--`, `x++`, `y++`. Outputs `1` to move, `0` to turn. Explanation:

```
. (-?).*( -?).*

```

Capture the signs of the coordinates.

```
$*-$2$1$1

```

Convert the direction to unary, and convert the coordinate signs from base 2, discarding everything else.

```
^(-*) \1$

```

Compare the direction to the base 2 decoded signs.

# Answer
> 1 votes
# C (gcc), 47 bytes

```
z;m(x,d)int*x;{x=abs(z=x[d/2])>abs(z+d%2*2-1);}

```

Returns `0` to move forward and `1` to turn clockwise. It never moves counterclockwise but let's just call that `2`.

North is `3`, south is `2`, east is `1`, and west is `0`.

*-2 bytes thanks to ceilingcat!*

Try it online!

# Answer
> 1 votes
# 05AB1E, 4 bytes

```
d2βQ

```

Port of *@NickKennedy*'s Jelly answer, so make sure to upvote him as well!

First input is the coordinate, second input is the current direction digit (in the range `[0,3]`).
Outputs `0` to turn, and `1` to move forward.

Try it online or verify a random coordinate will eventually result in `[0,0]` or verify all coordinates in the range `[[-1,1],[1,1]]` with all possible directions `[0,3]`.

**Explanation:**

```
d     # Check for both values in the (implicit) input-coordinate whether it's non-negative (>=0)
 2β   # Convert this from a binary-list to an integer
   Q  # And check whether it's equal to the (implicit) direction input-integer
      # (after which this is output implicitly)

```

# Answer
> 1 votes
# Pure Data, 65 bytes

```
#X obj 0 0 expr (8*($i1<0)+4*($i2<0)+2*($i1>0)+($i2>0)&1<<$i3)<1;

```

This line can be added to a pure data patch to make an object positioned at `0 0` which takes 3 inputs and produces one output. The first two are the x and y and the last is the direction (range 0 to 3).

Here is an example of how it can be called:

This ports my haskell answer in logic, however since arrays are a nightmare in pure-data we use arithmetic and bitwise operations instead. We pack the 4 booleans (ints in pd) into a four bit integer and use `&` to index them.

# Answer
> 0 votes
# Charcoal, ~~13~~ 9 bytes

```
⁼↨Ｅ²›⁰Ｎ²Ｎ

```

Try it online! Link is to verbose version of code. Edit: Saved 4 bytes by porting @isaacg’s Pyth answer. Uses the same "move or turn" approach; `-` means move, no output means turn. The directions encode as `y--`, `x--`, `x++`, `y++`. Explanation:

```
   ²        Literal 2
  Ｅ         Map over implicit range
     ⁰      Literal 0
    ›       Is greater than
      Ｎ     Input coordinate
 ↨     ²    Convert from base 2
⁼           Equals
        Ｎ   Input direction

```

---
Tags: code-golf, grid
---


# Question
Title: An Old Irish Blessing, reasked (without using encodings)
How much can you golf a program to print "An Old Irish Blessing" **without using unprintable ASCII characters**?

That restricts us to ASCII characters 32-126 (better still, 32,65-90,97-122 and 13(CR))

For reference that version of the proverb is 205 characters long (excl. newlines). I'm curious if anything beats Huffman-encoding incl. spaces.

# Answer
> 4 votes
### Golfscript, 198 characters

```
[]"-!9 4(% 2/!$<)3A50H/ -%%4 9/5
XXXN7).X\"?!,7I3>4UU2I!#+
[[[S35.;(`A[2- 50/.]]]&]%
YO2!U3F|,`/&4ZZZZZK)%,$3
!.$ }4),ze-%%Z!'!k\n-!9 '/S(/]hh )o4(%GG,/7 /&A)3;!v"{.32>{.58<{32+}{56-~1$>2<}if}*+}/+

```

**Output:**

```
$ ruby golfscript.rb blessing.gs
MAY THE ROAD RISE UP TO MEET YOU
MAY THE WIND BE ALWAYS AT YOUR BACK
MAY THE SUN SHINE WARM UPON YOUR FACE
THE RAINS FALL SOFT UPON YOUR FIELDS
AND UNTIL WE MEET AGAIN
MAY GOD HOLD YOU IN THE HOLLOW OF HIS HAND

```

The poem is compressed to 158 characters by using part of the ASCII range for back-references (of fixed length 2). The coding scheme is as follows:

```
[10]      : newline (unencoded)
[32]      : space (unencoded)
[33..57]  : literal (33=A, 34=B, ... 57=Y, Z not needed)
[58..126] : back-reference relative to the end of the decompressed string so far.

```

The remaining 40 characters make up the decompression code which can probably be golfed a little further, since this is my first attempt at Golfscript.

---

**Case-sensitive version, 207 characters**

Same concept, but trading some of the back-reference range for lower case letters at the cost of some compression.

```
[]"-AY THE ROAD RISaUPhO MEET YOU
xxxnWINxB_ALWiS^TuuRiACK
{{{sSUN[HINa{RM UPON}}}F}E
4HoRAuS fLL SOFTzzzzzkIELDS
!NDlNTIwWE MEEzAGAIN
-AY 'OsHOLxYOU k THEggLOW OF (ISeAND"{.32>{.90<{32+}{88-~1$>2<}if}*+}/+

```

**Output:**

```
$ ruby golfscript.rb blessing-casesensitive.gs
May the road rise up to meet you
May the wind be always at your back
May the sun shine warm upon your face
The rains fall soft upon your fields
And until we meet again
May God hold you in the hollow of His hand

```

# Answer
> 2 votes
**Perl, 214 characters**

```
s//01road rise2 to 34
01w5d be always at4r back
01s7 sh5e warm284r face
The ra5s fall soft284r fields
And 7til we 3 aga5
0God 6d4 5 1 6low of His hand/;s/\d/('May ','the ',' up',meet,' you',in,hol,un,on)[$&]/eg;say

```

# Answer
> 1 votes
**Python, 263 chars**

```
t="""01road rise2 to34
01w5d be always at4r back
01s7 sh5e warm284r9ce
The ra5s9ll soft284r fields
And 7til we3 aga5
0God 6d4 5 16low of His hand"""

for k,v in enumerate("May ,the , up, meet, you,in,hol,un,on, fa".split(',')):
    t = t.replace(str(k),v)
print t

```

which was an 'improvement' on my 261-char quick hack, obviously inferior to a simple print.

```
s="""12road rise up to34
12wind be always at4r back
12sun shine warm54r face
The rains fall soft54r fields
And until we3 again
1God hold4 in 2hollow of His hand"""

for k,v in {1:"May ",2:"the ",3:" meet",4:" you",5:" upon"}.items():
    s = s.replace(str(k),v)
print s

```

enumerate() takes almost as many chars in creating the dict/sequence, on a short example like this.

# Answer
> 1 votes
## PHP, 203

Base64 is ASCII only, but I'd still consider this slightly exploitive.

```
<?=gzinflate(base64_decode('TY5BDsMwCATvecV+hcQkRsWmMras/P8jpW5V9bhidodCN3pmNKOEJs4YT3RDYe64bWzlC0ypCTuDdNLtoHVt2Ol4/BgfFZ6lBk2txJLVD3XSwdvSkFSPqAq3s/8jwpp8o7CM2kUx+fMEXdFZissSsml6FyB1KSOrTdiJLI4c9Rc'));

```

Proof it works.

# Answer
> 1 votes
Python, 224 chars

```
print'''1road rise up to meet you
1wind be always at your back
1sun shine warm upon your face
The rains fall soft upon your fields
And until we meet again
May God hold you in the hollow of His hand'''.replace('1','May the ')

```

Instead of wasting characters on for loops or multiple replaces, I only have one replace with the single most common combinations of words `May the`

# Answer
> 0 votes
# Io, 217 bytes

Compressing the string leads to a longer length...

```
"May the road rise up to meet you
May the wind be always at your back
May the sun shine warm upon your face
The rains fall soft upon your fields
And until we meet again
May God hold you in the hollow of His hand"print

```

Try it online!

---
Tags: code-golf, kolmogorov-complexity, printable-ascii
---


# Question
Title: Even a clock that isn't working gets the time right two or three times a day
## Context

When I was a little kid, I watched a Disney movie where Goofy told his son "Boy, even a broken clock is right two or three times a day." (see this youtube clip, courtesy of @Arnauld).

## Rationale

Given the previous statement, we wish to look at a clock that is *stopped* and answer the following question: *is this clock telling the correct time?*, -style. But we will also do it *Goofy* style, assuming a stopped clock gets the correct time 3 times a day.

# Task

Pick some time of the morning with at least minute precision. Call it \\$t\\$.

The function/full program/etc you submit must satisfy the following requirements:

1. if executed at \\$t\text{ am}\\$ and at \\$t\text{ pm}\\$, your code produces an observable output `a` (think *Truthy* in challenges).
2. for every calendar day, there is a third time \\$t\_1\\$ distinct from \\$t\text{ am}\\$ and \\$t\text{ pm}\\$ such that, if your code is ran at that time, your code also deterministically produces the observable output `a`. This means \\$t\_1\\$ may be constant or it may be a function of the day the code is ran at.
3. if ran at any other time of the day, your code produces an observable output `b` that must be distinct from `a` (think *Falsy* in challenges).

Recall that your code should be precise at least to the minute. This means that you may decide that seconds don't matter for your answer, but you might also want to decide that your answer checks up to nanoseconds in order to decide if it is *that* time of the day.

# Input

Either your code takes no input or it takes the "current" time. For the time, acceptable formats include, but are not limited to:

* Any ISO format for date/time strings where time is given at least to the minute;
* An integer list with `[hours, minutes]` or `[hours, minutes, seconds]` or any similar list with further subdivisions of the second; (this order may be reversed but may *not* be shuffled)
* Different arguments, each representing one element from the lists above.

# Output

A single, well-defined, observable output `a` if your code is run at \\$t\text{ am}\\$, at \\$t\text{ pm}\\$, or at \\$t\_1\\$, as specified in your answer. If ran at any other time, your code produces the observable output `b`, distinct from `a`.

# Bonus imaginary internet points

Bonus imaginary internet points will be awarded to the shortest answer for which \\$t\_1\\$ isn't constant. If this question turns out to receive enough attention, this will turn into an actual rep bounty.

---

This is so shortest submission in bytes, wins! If you liked this challenge, consider upvoting it! If you dislike this challenge, please give me your feedback. Happy golfing!

# Answer
# JavaScript (ES6), 13 bytes

Takes input as `(h)(m)`. Returns *true* for `01:00`, `02:00` and `13:00`, or *false* for anything else.

```
h=>m=>26%h<!m

```

Try it online!

### How?

Testing \\$26\bmod h\<\delta\_m\\$ is equivalent to test that we have \\$m=0\\$ and \\$26\equiv 0\pmod h\\$.

For \\$0\<h\le23\\$, we have \\$26\equiv 0\pmod h\\$ iff \\$h\\$ divides \\$26\\$, i.e. \\$h\in\\{1,2,13\\}\\$.

For the edge case \\$h=0\\$, `26%h` results in `NaN` which is neither greater nor lower than any other value, so the test returns *false* as expected, no matter the value of \\$m\\$.

### Other possible values

This program generates all possible values \\$n\<1000\\$ for the expression \\$n\bmod h\\$.

```
for(n = 1; n < 1000; n++) {
  A = [...Array(24)].map((_, x) => x).filter(x => n % x == 0);
  if(A.length == 3 && A.some(x => A.includes(x + 12))) {
    console.log(n, A);
  }
}

```

Try it online!
> 19 votes

# Answer
# Bash \+ Core utilities, ~~26~~ 25 bytes + Bonus imaginary Internet points!

```
egrep '(.)T(11|23|0\1)00'

```

Try it online!

*Thanks to @mypronounismonicareinstate for pointing out that the ISO 8601 allows omitting the colon in the time part, which saves a byte in the code. (ISO 8601 also allows omitting the hyphens in the date, but that doesn't affect the regex.)*

This accepts input on stdin in a format like

`20200319T1018-0700`

which is a basic ISO 8601 format with precision to the minute.

The result is in the exit code: `0` for truthy (one of the three Goofy times), `1` for falsey (everything else).

The three times it outputs `0` are at:

* 11:00 am
* 11:00 pm
* d:00 am where d is the last digit of the date.

So, today, March 19, it would output truthy (exit code 0) for 9 am (because 9 is the last digit of the date 19), 11 am, and 11 pm.
> 11 votes

# Answer
# , 23 bytes

```
function(h,m)26%%h|m|!h

```

Try it online!

Port of Arnauld's solution, go upvote his!

Outputs `FALSE` at 1:00, 13:00 and 2:00, and `TRUE` otherwise.

---

Previous version:

# , 26 bytes

```
function(h,m)!h|m|(h/6)%%1

```

Try it online!

Outputs `FALSE` at the three times:

\\$t\_{am}\\$ = `6:00`
\\$t\_{pm}\\$ = `18:00`
\\$t\_1\\$ = `12:00`

and `TRUE` at any other time.

Indeed, for the output to be `FALSE`, we need `h≠0`, `m=0`, and `h` to be a multiple of 6.
> 4 votes

# Answer
# Japt `-!`, 8 bytes

Inspired by Kevin's choice of times. Input as 2 integers in the order `h, m`. Outputs `true` at `00:00`, `01:01` and `13:01` and `false` otherwise.

```
%C*VÉ©Nx

```

Try it

```
%C*VÉ©Nx     :Implicit input of integers U=h and V=m
%C           :U modulo 12 (=1 if U=1 or U=13)
  *V         :Multiplied by V (=1 if above and V=1)
    É        :Subtract 1 (=0 if all above)
     ©       :Logical AND with
      N      :Array of inputs (i.e., [U,V])
       x     :Reduced by addition (=0 if U=V=0)
             :Implicit output of boolean negation of result

```

---

A port of Arnauld's solution would be 1 byte shorter.

```
26%U<!V

```

Try it
> 3 votes

# Answer
# C (gcc), ~~22~~ \\$\cdots\\$ ~~20~~ 19 bytes

Saved a byte thanks to Arnauld!!!

```
f(h,m){h=26%~h<!m;}

```

Try it online!

Returns `1` for noon, midnight and 1am, `0` otherwise.
Adaptation of Arnauld's formula.
> 3 votes

# Answer
# Ruby, ~~48~~ 44 bytes

*-4 bytes thanks to Value Ink!*

Differs from other answers so far in that it (i) takes no input and (ii) has a unique \\$t\_1\\$ for every day of the year.

```
p (t=*Time.now)[2]%12+t[1]<1||t[1,2]==t[3,2]

```

Try it online! (actual code)

Try it online! (demo version showing the three times that will return `true` on a given date)

Outputs `true` at 00:00, 12:00, and *month*:*day* (03:20 for today, 20 March); `false` otherwise.

`*Time.now` yields an array of the form `[sec, min, hour, day, month, year, wday, yday, isdst, zone]`, of which the first 8 elements are integers (but only *min*, *hour*, *day*, and *month* are used here). Then print `true` if *hour* (mod 12) and *min* are both 0, or if *hour* = *month* and *min* = *day*.
> 3 votes

# Answer
# 05AB1E, ~~16~~ ~~11~~ 10 bytes

Taking input in the format `[minutes, hours]`:

```
`12%*ΘIO_~

```

Try it online.

Without input and using the current time builtins:

```
ža12%žb*Θžažb+_~

```

Try it online (not very useful right now..) or try it online with emulated hours/minutes.

Both programs use the three times:

\\$t\_{am}\\$ = `1:01`
\\$t\_{pm}\\$ = `13:01`
\\$t\_1\\$ = `00:00`

And will output `1` on any of those three times above, and `0` on any other time.

**Explanation:**

```
`           # Push the values in the (implicit) input-pair separated to the stack
 12%        # Take modulo-12 on the hours, to make the 24-hour a 12-hour clock
    *       # Multiply it with the minutes
     Θ      # And check if it's exactly 1 (1 if truhy; 0 if falsey)
I           # Push the input-pair again
 O          # Sum them together
  _         # Check if it's exactly 0 (1 if truhy; 0 if falsey)
      ~     # And then check if either of the two checks is 1
            # (after which the result is output implicitly)

ža          # Push the current hours
  12%       # Modulo 12, to make the 24-hour a 12-hour clock
     žb     # Push the current minutes
       *    # Multiply them together
        Θ   # And check if it's exactly 1 (1 if truthy; 0 if falsey)
žažb        # Push the current hours and minutes again
    +       # Add them together
     _      # Check if it's exactly 0 (1 if truthy; 0 if falsey)
         ~  # And then check if either of the two checks is 1
            # (after which the result is output implicitly)

```
> 2 votes

# Answer
# 05AB1E (legacy), 5 bytes

```
_₂I%›

```

Port of *@Arnauld*'s JavaScript answer, so make sure to upvote him!!

Takes two loose inputs, in the order `minutes`, `hours`.

Will also output `1` for any of these three times below, and `0` on any other time:

\\$t\_{am}\\$ = `01:00`
\\$t\_{pm}\\$ = `13:00`
\\$t\_1\\$ = `02:00`

Try it online or verify some more test cases.

**Explanation:**

```
_     # Check if the (implicit) input-integer (minutes) is 0 (1 if truthy; 0 if falsey)
 ₂    # Push 26
  I   # Push the second input-integer (hours)
   %  # Take 26 modulo-hours (will result in 26 if the hours are 0 in the legacy version)
    › # Check if the first value is larger than the second
      # (after which it is output implicitly as result)

```
> 2 votes

# Answer
# Python 3, ~~35~~ \\$\cdots\\$ ~~22~~ 19 bytes

Saved a byte thanks to Arnauld!!!
Saved 3 bytes thanks to Surculose Sputum!!!

```
lambda h,m:26%~h==m

```

Try it online!

Returns `True` for noon, midnight and 1am, `False` otherwise.
Adaptation of Arnauld's formula.
> 2 votes

# Answer
# Python 3, 21 bytes

```
lambda h,m:26%-~h<m<2

```

Try it online!

**Input**: hour and minute, as integers
**Output**: `True` if the time is `00:01`,`01:01`,`12:01`, otherwise `False`.
> 2 votes

# Answer
# Retina 0.8.2, 28 bytes

```
^.
$&$&$&$&
\G\d
$*
^1{8}:18

```

Try it online! Link includes test cases. Explanation:

```
^.
$&$&$&$&

```

Repeat the hour tens digit four times.

```
\G\d
$*

```

Convert the hour digits to unary.

```
^1{8}:18

```

They must sum to 8 and the minutes must be 18 (arbitrarily chosen to reuse the same digits).
> 1 votes

# Answer
# Perl 5 -lF: , 34 bytes

```
say$F[0]%12&&$F[0]!=1||$F[1]>0?0:1

```

Try it online!

Reads current time input from stdin in hh:mm format. Outputs 1 at 00:00, 01:00, and 12:00; 0 at all other times.
> 1 votes

# Answer
# Charcoal, 10 bytes

```
⁼²№⟦↨Ｓ⁴Ｎ⟧⁹

```

Try it online! Link is to verbose version of code. Takes input as hour and minute separated by a space, on separate lines, or as a JSON list i.e. `[22, 10]`, and outputs `-` for `09 09`, `15 09` and `21 09` only. Explanation:

```
   ⟦    ⟧   List of
     Ｓ      Hours as a string
    ↨ ⁴     Interpreted as base 4
       Ｎ    Minutes
  №      ⁹  Count `9`s
⁼²          Must be 2 of them.

```
> 1 votes

# Answer
# Retina, ~~18~~ 17 bytes + Bonus imaginary Internet points

```
(.)T(11|23|0\1)00

```

Try it online!

*Note that TIO is having technical issues at the moment, so the link that it gave me above may or may not work.*

---

*Thanks to @mypronounismonicareinstate for pointing out that the ISO 8601 allows omitting the colon in the time part, which saves a byte in the code. (ISO 8601 also allows omitting the hyphens in the date, but that doesn't affect the regex.)*

---

I don't really know Retina, but this port of my bash answer appears to be right :) .

The program accepts input on stdin in a format like

20200319T1018-0700

which is a basic ISO 8601 format with precision to the minute.

Like my bash answer, it outputs truthy (0) for 11:00 am, 11:00 pm, and d:00 am where d is the last digit of the current date. It outputs falsey (1) otherwise.
> 1 votes

# Answer
# Ruby, 19 bytes

Returns true at 6:00, 12:00, 18:00.

```
->h,m{h>0&&m|h%6<1}

```

Try it online!
> 1 votes

# Answer
# Jelly,  ~~7~~  6 bytes

Turns out porting Arnauld's answer is a byte shorter than my original answer (which I've kept below)

```
26%<¬}

```

A dyadic Link accepting the hour (an integer in `[0,23]`) on the left and the minute (an integer in `[0,59]`) on the right which yields 1 at three times (not varying by day), `2,0` (02:00), `1,0` (01:00), and `13,0` (13:00).

**Try it online!**

---

**My 7**

```
æle1,98

```

A dyadic Link accepting the hour (an integer in `[0,23]`) on the left and the minute (an integer in `[0,59]`) on the right which yields 1 at three times (not varying by day), `1,1` (01:01), `2,49` (02:49), and `14,49` (14:49).

**Try it online!**
> 1 votes

# Answer
# perl -ple, 18 bytes

```
$_=/(2[01]|08):00/

```

Reads a time in `HH:MM` format from `STDIN` (optionally preceded by a date in `YYYY-MM-DD` format (or anything else which doesn't like a time)).

Print `1` followed by a newline if the time is `08:00`, `20:00` or `21:00`; otherwise, it prints a single newline.
> 1 votes

# Answer
# , 5 bytes

... With True and False swapped around; they're distinctive anyway.

```
♥─y¥•

```

Uncompressed:

```
!26bm>

```

# Explanation

```
!      % Check whether the input is equal to 0
   b   % Push the second input
 26 m  % Push 26 % b
     > % Is input == 0 larger than the above value?

```
> 1 votes

# Answer
# Io, 19 bytes

Port of @Arnauld's answer...

```
method(U,V,26%U>=V)

```

Try it online!
> 0 votes

---
Tags: code-golf, decision-problem, date
---


title: Day of the week of an ambiguous date

text:
# Question
Title: Day of the week of an ambiguous date
# Goal

Write a program or function that returns the day of the week for a date, eg.

```
01/06/2020  ->  Mon

```

However, it's unknown if the date is in the format mm/dd/yyyy or dd/mm/yyyy. If you can be certain of the day of the week, return it. If there is uncertainty, return an error.

```
02/07/2020  ->  Err  (Thu? Fri?)

```

# Input

A date in the format `#/#/####`.

* The numbers can optionally have leading zeros.
* The year should be read verbatim, assume that 19 = 19 AD, not 19 = 2019 AD.
* The separators can be any non-digit character.
* Assume the input date is valid in at least one format (ie. not 13/13/2020).
* At a minimum, support dates from 2000 through 2030 (which are likely covered by any modern OS and language with a date library.)

# Requirements

* If the first and second numbers:
    + are the same (03/03/2020), the date is **unambiguous**.
    + either is greater than 12 (13/09/2020, 09/13/2020), the date is **unambiguous**.
    + are different and both 12 or less (09/11/2020), the date is **ambiguous**.

# Output

* If the date is unambiguous, return the day of the week.
* If the date is ambiguous:
    + If both versions of the date have the same day of the week, return the day of the week.
    + If both versions of the date have a different day of the week, return an error.
* A day of the week should be returned as a string of the day's three-letter abbreviation ("Mon"), case-insensitive.
* An error should be returned as any other three-character string, not all whitespace, eg. "Err", "NaN", "???".

# Test Cases

```
02/07/2020  ->  Err
01/06/2020  ->  Mon
05/05/2020  ->  Tue
24/06/2020  ->  Wed
05/09/2030  ->  Thu
03/13/2020  ->  Fri
29/02/2020  ->  Sat
03/12/2000  ->  Sun

```

# Scoring

The code with the least byte count in a week wins the tick.

# Answer
# Bash \+ GNU utilities, ~~97~~ ~~96~~ ~~93~~ ~~85~~ ~~80~~ ~~76~~ ~~73~~ ~~58~~ ~~56~~ 51 bytes

```
(${d=date +%a -d$3-}$1-$2;$d$2-$1)|uniq|sed N\;cErr

```

Try it online!

*5 bytes off thanks to user41805, who pointed out that I could use sed's `c` command instead of the final `s` command.*

*2 bytes off thanks to Nahuel Fouilleul. (Nahuel also helped by shaving 4 bytes off in an earlier version that has since been revamped.)*

When I noticed that the separators can be any non-digit character, I changed the code to use spaces as the separator.

This is called with a command like

`checkdate 01 06 2020`

The output is on stdout. (There's spurious output on stderr.)
> 9 votes

# Answer
# 05AB1E, ~~88~~ ~~82~~ ~~79~~ ~~76~~ ~~79~~ ~~73~~ 72 bytes

```
#ÂÀ‚Dε`UÐ3‹12*+>₂*T÷s3‹Xα¬Ésт%D4÷O.•A±₁γβCüIÊä6’C•3ôsè}DËiнës€¨13‹WiтëθÏ

```

-3 bytes thanks to *@Arnauld* (initially -6, but +3 bytes again, since Jan./Feb. 2000 would still result in the previous century in the formula).
-7 bytes thanks to *@Grimmy*.

Input is space-separated; and outputs in lowercase with `100` as error.

Try it online or verify all test cases.

**Explanation:**

Since 05AB1E has no Date builtins, we'll have to calculate the *Day of the Week* manually.

The general formula to do this is:

$${\displaystyle h=\left(q+\left\lfloor{\frac{13(m+1)}{5}}\right\rfloor+K+\left\lfloor{\frac{K}{4}}\right\rfloor+\left\lfloor{\frac{J}{4}}\right\rfloor-2J\right){\bmod{7}}}$$

Where for the months March through December:

* \\$q\\$ is the \\$day\\$ of the month (`[1, 31]`)
* \\$m\\$ is the 1-indexed \\$month\\$ (`[3, 12]`)
* \\$K\\$ is the year of the century (\\$year \bmod 100\\$)
* \\$J\\$ is the 0-indexed century (\\$\left\lfloor {\frac {year}{100}}\right\rfloor\\$)

And for the months January and February:

* \\$q\\$ is the \\$day\\$ of the month (`[1, 31]`)
* \\$m\\$ is the 1-indexed \\$month + 12\\$ (`[13, 14]`)
* \\$K\\$ is the year of the century for the previous year (\\$(year - 1) \bmod 100\\$)
* \\$J\\$ is the 0-indexed century for the previous year (\\$\left\lfloor {\frac {year-1}{100}}\right\rfloor\\$)

Resulting in in the day of the week \\$h\\$, where 0 = Saturday, 1 = Sunday, ..., 6 = Friday.
Source: Zeller's congruence

Since the input is guaranteed to be in the year-range \\$\[2000, 2030\]\\$, we can modify \\$+ \left\lfloor{\frac{J}{4}}\right\rfloor - 2J\\$ to a hard-coded \\$-35\\$ to save some bytes. EXCEPT, when it's Jan./Feb. 2000, in which case it's the previous century. For those, we use `¬És`, to add 1 to our hard-coded replacement of \\$J\\$.
In addition, we won't need the \\${\bmod {7}}\\$, since we only use it to index into the string list, and 05AB1E uses modular indexing anyway.

We can save 2 more bytes, by just removing the \\$-35\\$ all together, since it's a multiple of 7 anyway.
And one more byte, by changing the \\$\left\lfloor{\frac{13(m+1)}{5}}\right\rfloor\\$ to \\$\left\lfloor{\frac{26(m+1)}{10}}\right\rfloor\\$, since 05AB1E has a single-byte builtin for `26` and `10` (which are  and `T` respectively).

***Code explanation:***

```
#            # Split the (implicit) input-string by spaces
 Â           # Bifurcate it (short for Duplicate & Reverse copy)
  À          # Rotate the reversed copy once towards the left
   ‚         # Pair the top two values together
             # (we now have a pair [[day,month,year],[month,day,year]])
    D        # Duplicate it
     ε       # Map over both values in this pair:

```

Now comes Zeller's congruence into play:

```
`            #  Push the day, month, and year separated to the stack
 U           #  Pop and save the year in variable `X`
  Ð          #  Triplicate the month
   3‹        #  Check if the month is below 3 (Jan. / Feb.),
             #  resulting in 1 or 0 for truthy/falsey respectively
     12*     #  Multiply this by 12 (either 0 or 12)
        +    #  And add it to the month
             #  This first part was to make Jan. / Feb. 13 and 14

>            #  Month + 1
 ₂*          #  Multiplied by 26
   T÷        #  Integer-divided by 10
s3‹          #  Check if the month is below 3 again (resulting in 1 / 0)
   Xα        #  Take the absolute difference with the year
     ¬       #  Push the first digit (without popping the mYear itself)
      É      #  Check if its odd (1 if 1; 0 if 2)
     s       #  Swap to take the mYear again
      т%     #  mYear modulo-100
D4÷          #  mYear modulo-100, integer-divided by 4
O            #  Take the sum of all values on the stack

```

And then we'll continue:

```
.•A±₁γβCüIÊä6’C•
             #  Push compressed string "satsunmontuewedthufri"
  3ô         #  Split it into parts of size 3: ["sat","sun","mon","tue","wed","thu","fri"]
    s        #  Swap to get the earlier calculated number
     è       #  And index it into this list (0-based and with wrap-around)
}D           # After the map: duplicate the resulting two days
Ëi           # If they are both the same:
  н          #  Leave just one of them
ë            # Else (they are different):
 s           #  Swap, to take the initially duplicated pair of
             #  [[day,month,year],[month,day,year]]
  €¨         #  Remove the year from each
    13‹      #  Check for the remaining values if they are smaller than 13
       W     #  Push the flattened minimum (without popping)
        i    #  If it's truthy (so day and month are both below 13):
         т   #   Push 100 (as error value)
        ë    #  Else:
         θ   #   Pop and leave just the last one (either [0,1] or [1,0])
          Ï  #   And only keep the day at the truthy index
             # (after which the top of the stack is output implicitly)

```

See this 05AB1E tip of mine (section *How to compress strings not part of the dictionary?*) to understand why `.•A±₁γβCüIÊä6’C•` is `"satsunmontuewedthufri"`.
> 8 votes

# Answer
# Perl 6, ~~124~~ 121 bytes

```
{<Err Mon Tue Wed Thu Fri Sat Sun>[2>set($/=|grep ?*,map {try Date.new(|$_).day-of-week},m:g/\d+/[[2,1,0],[2,0,1]])&&$0]}

```

Try it online!
> 4 votes

# Answer
# Red, ~~186~~ ~~169~~ 167 bytes

-2 bytes thanks to Kevin Cruijssen

```
func[d][a: to-date t: load form split d"/"m: min a b:
to-date reduce[t/2 t/1 t/3]either any[a/10 = b/10 t/1 > 12
t/2 > 12][pick[:Mon:Tue:Wed:Thu:Fri:Sat:Sun]m/10][.1]]

```

Try it online!

Takes the input as string, because Red doesn't accept invalid dates in `dd/mm/yyyy` format. That's strange, because the coerce function `to-date` that takes a block of 3 values \[dd mm yyyy\] accepts any integer, including 0 and negative numbers and creates a "correct" date based on them.
> 3 votes

# Answer
# JavaScript (ES6),  ~~136 132~~  131 bytes

Returns `"Err"` for an error.

```
s=>'SunMonTueWedThuFriSatErr'.match(/.../g)[[i,j]=([d,m,y]=s.split`/`).map(M=>new Date(y,M-1,M^m^d).getDay()),d<13?m>12|i==j?i:7:j]

```

Try it online!

### Commented

```
s =>                           // s = input string
  'SunMonTueWedThuFriSatErr'   // lookup string
  .match(/.../g)[              // split it and pick the relevant entry:
    [i, j] =                   //   (i, j) = day-of-week indices
      ([d, m, y] = s.split`/`) //   split s into (d, m, y)
      .map(M =>                //   for each value M in there (ignoring y):
        new Date(              //     create a date:
          y,                   //       using y as the year
          M - 1,               //       using M - 1 as the 0-indexed month
          M ^ m ^ d            //       using the other value as the day
        )                      //     end of Date()
        .getDay()              //     get the day-of-week index (Sun:0, ..., Sat:6)
      ),                       //   end of map()
    d < 13 ?                   //   if d is a valid month:
      m > 12 | i == j ? i      //     non-ambiguous if m is an invalid month or i = j
                      : 7      //     ambiguous otherwise (-> "Err")
    :                          //   else:
      j                        //     use j
  ]                            // end of lookup

```
> 3 votes

# Answer
# Perl 5 -MPOSIX -naF/, 125 bytes

```
sub d{substr ctime(mktime 6,0,0,$_[0],$_[1]-1,$_[2]-1900),0,3}@G=@F[1,0,2];say$F[0]>12?d@F:$F[1]>12?d@G:d(@F)eq d(@G)?d@F:Err

```

Try it online!

Not completely happy with this one, but haven't thought up a better way (yet).
> 2 votes

# Answer
# Python, ~~180~~ ~~164~~ 158 bytes

Saved 3 bytes thanks to Kevin Cruijssen and Arnauld!!!
Saved 3 bytes thanks to Surculose Sputum!!!

```
lambda a,b,c:(x:=d(a,b,c))==(y:=d(b,a,c))and x or(x and y and.1)or y or x
from datetime import*
def d(a,b,y):
 try:return date(y,a,b).strftime("%a")
 except:0

```

Try it online!

Assumes we can input the date as three separate arguments and returns `0.1` if ambiguous.

**Date as string**

# Python, ~~197~~ 191 bytes

Ditto the above saves and thanks! :D

```
lambda s:(x:=d(s))==(y:=d(s,1))and x or(x and y and.1)or y or x
from datetime import*
def d(s,q=0):
 a,b,c=map(int,s.split('/'))
 if q:a,b=b,a
 try:return date(c,a,b).strftime("%a")
 except:0

```

Try it online!
> 2 votes

# Answer
# PHP, 115 bytes

```
foreach(['/','-']as$s){if($x=strtotime(strtr($argn,'/',$s)))$o=date('D',$x);if($p&&$o!=$p)die('err');$p=$o;}echo$p;

```

Try it online!

Uses the peculiarity that the builtin `strtotime` parses dates as either European or American format according to whether the delimiter is either slash or dash.

Takes input as `a/b/Y` and returns `err` for an error condition.
> 2 votes

# Answer
# Python 3.8 (pre-release), 125 bytes

*Improvement over @Noodle9's answer*

```
lambda a,b,y:[.1,w:=g(y,a,b)][w==g(y,b,a)]
g=lambda y,m,d:m<13and date(y,m,d).strftime("%a")or g(y,d,m)
from datetime import*

```

Try it online!

**Input**: 3 integers representing date, month, and year.
**Output**: A 3-character abbreviation of a weekday, or `0.1` if the weekday is ambiguous.

**How:**

* `date(y,m,d).strftime("%a")` returns the abbreviated weekday of the date `d/m/y`.
* `g(y,m,d)` returns the weekday if the date is valid, otherwise returns the weekday of the date where month and day are swapped. Thus if `g(y,a,b)` and `g(y,b,a)` are the same, then the weekday is not ambiguous. Otherwise, the weekday is ambiguous.
* `[.1,w:=g(y,a,b)][w==g(y,b,a)]` evaluates to `g(y,a,b)` if the weekday is not ambiguous, or `0.1` if the weekday is ambiguous.
> 1 votes

# Answer
# Perl 5 `-MTime::Local=timegm_modern -pF'/'`, ~~116~~ ~~113~~ 108 bytes

```
sub f{$_[1]--;eval{timegm_modern 0,0,9,@_}}$_=($a=f@g=@F)*($b=f@F[1,0,2])&$a-$b?Err:substr gmtime($a|$b),0,3

```

Try it online!

Tries converting both formats into an epoch time. The `eval` traps the error that would occur for an invalid date. Multiplies the two epoch times together to make sure that one is 0, and checks that they are not the same with substraction. Uses their bitwise `or` to convert back to an actual date, then picks off the day of the week from that.
> 1 votes

# Answer
## Excel, 85 Bytes

```
=IF(OR(DAY(A1)>12,MOD(A1-DATE(YEAR(A1),DAY(A1),MONTH(A1)),7)=0),TEXT(A1,"ddd"),"???")

```

Input the date into cell A1

Since Excel will automatically evaluate the date into a valid form for us, we can first check if the `Day` is \>12, since this would immediately make the date unambiguous.

We then work out if difference between the "dd/mm/yyyy" and "mm/dd/yyyy" versions is a multiple of 7, using `MOD`, since this would mean both Weekdays are the same

If either of these conditions are `True`, then the Weekday is unambiguous.
> 1 votes

# Answer
# Ruby `-apl`, 102 bytes

Takes input as a line of input from STDIN with space as the separator. Outputs `false` if the dates are ambiguous and the days of week don't match.

In order to make sure we get a correct date the first time, we sort the first two arguments to ensure the smaller of the two (which is guaranteed to be less than 13) is placed in the month field. We then reverse the arguments when comparing the days of week using `wday` (if it would be a valid date, done by checking `b>12` first), and if they match (or the date was unambiguous) we use `strftime("%a")` to output the day of the week in a human-readable format.

`-p` takes each line of input and outputs the contents of `$_` at the end of a program run.

`-a` is the autosplit flag, which will split the input on spaces and save into `$F`.

`-l` makes the input ignore newlines (they are included by default for Ruby's input function).

```
*x,y=$F.map &:to_i
d=Time.gm y,*x.sort!
a,b=x
$_=(b>12||d.wday==Time.gm(y,b,a).wday)&&d.strftime("%a")

```

Try it online!
> 1 votes

---
Tags: code-golf, kolmogorov-complexity, date
---


# Question
Title: Random ASCII Art of the Day #5: Diamond Tilings
## Mash Up Time!

This is instalment #5 of both my Random Golf of the Day and Optimizer's ASCII Art of the Day series. Your submission(s) in this challenge will count towards both leaderboards (which you can find the linked posts). Of course, you may treat this like any other code golf challenge, and answer it without worrying about either series at all.

## Hole 5: Diamond Tilings

A regular hexagon can always be tiled with diamonds like so:

We will use an ASCII art representation of these tilings. For a hexagon of side-length 2, there are 20 such tilings:

```
   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____
  /\_\_\   /\_\_\   /\_\_\   /\_\_\   /_/\_\   /_/\_\   /\_\_\   /_/\_\   /_/\_\   /_/\_\
 /\/\_\_\ /\/_/\_\ /\/_/_/\ /\/_/\_\ /\_\/\_\ /\_\/_/\ /\/_/_/\ /\_\/\_\ /\_\/_/\ /_/\/\_\
 \/\/_/_/ \/\_\/_/ \/\_\_\/ \/_/\/_/ \/\_\/_/ \/\_\_\/ \/_/\_\/ \/_/\/_/ \/_/\_\/ \_\/\/_/
  \/_/_/   \/_/_/   \/_/_/   \_\/_/   \/_/_/   \/_/_/   \_\/_/   \_\/_/   \_\/_/   \_\/_/
   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____
  /_/_/\   /\_\_\   /_/\_\   /_/_/\   /_/\_\   /_/\_\   /_/_/\   /_/_/\   /_/_/\   /_/_/\
 /\_\_\/\ /\/_/_/\ /_/\/_/\ /\_\_\/\ /\_\/_/\ /_/\/_/\ /_/\_\/\ /\_\_\/\ /_/\_\/\ /_/_/\/\
 \/\_\_\/ \/_/_/\/ \_\/\_\/ \/_/\_\/ \/_/_/\/ \_\/_/\/ \_\/\_\/ \/_/_/\/ \_\/_/\/ \_\_\/\/
  \/_/_/   \_\_\/   \_\/_/   \_\/_/   \_\_\/   \_\_\/   \_\/_/   \_\_\/   \_\_\/   \_\_\/

```

Given a side length `N`, you should generate such a tiling for a hexagon of side length `N` at random. The exact distribution doesn't matter, but each tiling must be returned with non-zero probability.

For `N ≤ 4`, your submission must produce a tiling within 1 minute at least 80% of the time and at least 80% of the tilings must potentially be generated within 1 minute. Most approaches won't have to worry about this rule (it's very lenient) - this is just to rule out very naive rejection-based algorithms that generate arbitrary strings until one happens to be a tiling.

You might like to know that the total number of possible tilings for given N can be found in OEIS A008793.

You may write a full program or a function and take input via STDIN (or closest alternative), command-line argument or function argument and produce output via STDOUT (or closest alternative), function return value or function (out) parameter.

You must not output more leading spaces than necessary to align the hexagon (that is the left corner of the hexagon should have no spaces in front of it). Each line may contain up to `N` trailing spaces (not necessarily consistently, so you could e.g. have a rectangular output, printing the hexagon's bounding box).

This is code golf, so the shortest submission (in bytes) wins. And of course, the shortest submission per user will also enter into the overall leaderboard of the series.

## Leaderboards

**The first post of each series generates a leaderboard.**

To make sure that your answers show up, please start every answer with a headline, using the following Markdown template:

```
# Language Name, N bytes

```

where `N` is the size of your submission. If you improve your score, you *can* keep old scores in the headline, by striking them through. For instance:

```
# Ruby, <s>104</s> <s>101</s> 96 bytes

```

*(The language is not currently shown, but the snippet does require and parse it, and I may add a by-language leaderboard in the future.)*

# Answer
> 10 votes
# CJam, 105 bytes

```
ri:A" __"e*A,2f*:B,[W1]{J+B:):B,{N1$S*"\/"J%A2*4$-:D*
0{;B{_1&!2mr+J*m1e>D(2*e<}%__:)&}g:B{'_t}/+@J+}*}fJ;

```

Newline added to avoid scrolling. Try it online

**Explanation:**

This solution starts each line as a zigzag, then places N underscores on it, based on their position on the previous line and a couple of rules. I got this from a series of observations while looking at the output as a plain 2D matrix of characters:

* each line has exactly N underscores
* the underscores can be replaced with / or \ to make a perfectly repeating zigzag pattern (`/\` in the top half, `\/` in the bottom half)
* underscores can not touch the sides, and can't be adjacent to another underscore
* when going to the next line, the position of each underscore changes by -1, 0 or 1
* more than that, `/_/` can only change by -1 or 0, and `\_\` can only change by 0 or 1
* for the initial underscore positions we can either use a `"_ "` pattern or a `" _"` pattern, both are fine
* the above rules are sufficient to obtain all the tilings

So I decided to implement it by keeping the previous underscore positions, modifying them with a random factor (2 choices for each underscore) and repeating until the rules are satisfied. In the process of optimizing, I switched to underscore positions relative to the left side of the hexagon (not including spaces).

```
ri:A" __"e*       read the input (A) and generate the top line
A,2f*:B           make an array [0 2 4 ... 2A-2] and store in B
                  these are the initial positions for the underscores
,                 B's length = A, used as the initial number of leading spaces
                  let's call it C
[W1]{…}fJ         for J in [-1 1] (top half, bottom half)
  J+              add J to C
  B:):B           increment the underscore positions (adjustment before each half)
  ,{…}*           repeat A times
    N1$S*         add a newline and C spaces
    "\/"J%        take "\/" and reverse it if J=-1 (zigzag pattern)
    A2*4$-:D*     calculate D=A*2-C and repeat the pattern
    0             dummy value (for the next loop)
    {…}g          do-while
      ;B          pop last value and push B
      {…}%        apply block to each item (say x)
        _1&!      duplicate x and calculate !(x&1) (for /_/ vs \_\)
        2mr+      randomly add 0 or 1
        J*m       multiply by J and subtract from x
        1e>       limit the minimum value to 1
        D(2*e<    and the maximum value to 2*(D-1)
      __:)&       check if the modified array has any adjacent values
    :B            store the new positions in B
    {'_t}/        place underscores over the zigzag pattern
    +@J+          bring C to the top and add J to it
;                 pop C

```

**Old "3D" version, 189 bytes:**

```
ri:A" __"e*aA4*S*aA2**+[0-2XXW1]:C;"/\_\\\/_/":D;A3m*{{C2/.f*:.+~
A(2*+:V;A+:U;2{UI+1$1$=4{_V+D4/I=@=t}/t}fI}:F~}/[0Y1WWW]:C;
"/_/\\\_\/":D;AaA*:B;A{A[_{_BI=e<)mr}fI]:B;{BQ={[PQR]F}fR}fQ}fPN*

```

Try it online

# Answer
> 6 votes
# Python 2, ~~337~~ ~~335~~ ~~324~~ ~~318~~ ~~311~~ ~~300~~ 296 bytes

```
from random import*
n=input()
R=range(n*2)
b=[]
l=[]
for i in R:o=abs(i-n)-(i<n);b+=[o];l+=[list(' '*o+'\//\\'[i<n::2]*(n*2-o))]
for i in R[:n]:
 o=1;p=n+i*2
 for j in R:r=randint(0,p<n*3+i*2-j);p+=(r or-1)*(o==r);q=p<=b[j];o=r|q;p+=q;l[j][p]='_';b[j]=p+1
for s in[' '*n+'__'*n]+l:print''.join(s)

```

The idea is to first create a hexagon of diamonds, like this:

```
  ____
 /\/\/\
/\/\/\/\
\/\/\/\/
 \/\/\/

```

And then fill it up with downward paths of underscores, like this:

```
  ____                          ____
 /_/\/\                        /\_\/\
/_/\/\/\    or maybe this:    /\/_/\/\
\_\/\/\/                      \/_/\/\/
 \_\/\/                        \_\/\/

```

The final result with all paths added would then look something like this:

```
  ____                          ____
 /_/\_\                        /\_\_\
/_/\/_/\    or maybe this:    /\/_/\_\
\_\/_/\/                      \/_/\/_/
 \_\_\/                        \_\/_/

```

Quite a bit of code goes into making sure these paths don't go out of bounds or cross eachother.

## The ungolfed code:

```
# Initialize l with all diamonds
blocked = []
l = [[] for _ in range(n*2)]
for i in range(n*2):
    offset = n-i-1 if i<n else i-n
    blocked.append(offset)
    l[i] += ' '*offset + ('/\\' if i<n else '\/')*(2*n - offset)

# Generate the random _'s
for i in range(n):
    oldright = True
    pos = n + i*2
    for j in range(n*2):
        # Go randomly right (true) or left (false), except when you out of bounds on the right side
        right = randint(0, 1) and pos < n*3 + i*2 - j
        if right == oldright:
            pos += 1 if right else -1
        if pos <= blocked[j]:
            right = True
            pos += 1
        l[j][pos] = '_'
        blocked[j] = pos + 1
        oldright = right

# Print the result
print ' '*n + '__'*n
for s in l:
    print ''.join(s)

```

# Answer
> 5 votes
# Perl, ~~174 168 166~~ 161

```
#!perl -n
for$l(-$_..$_){$t=/_/?join'',map'/_'x($%=rand
1+(@z=/__?/g)).'/\\'.'_\\'x(@z-$%),split/\/\\/:__
x$_;$l>0&&$t!~s!^.(\\.*/).$!$1!?redo:print$"x abs$l-.5,$_=$t.$/}

```

Try me.

# Answer
> 3 votes
# JavaScript (*ES6*), 376 ~~416 494~~

Just to be there ...

This build all the tilings, then choose a random one. Time for the 232848 tilings for N=4 is ~45 sec on my laptop. I did not try N=5.

Being EcmaScript 6 it runs on Firefox only.

```
F=n=>{
  for(i=s=r=b='';i<n;i++)
    s='\n'+b+'/\\'[R='repeat'](n-i)+'_\\'[R](n)+s,
    r+='\n'+b+'\\/'[R](n-i)+'_/'[R](n),
    b+=' ';
  for(h=[t=0],x=[s+r];s=x[t];t++)
    for(d='';!d[n*3];d+='.')
      if(l=s.match(r=RegExp("(\n"+d+"/)\\\\_(.*\n"+d+"\\\\)/_","g")))
        for(j=2<<l.length;j-=2;h[z]||(h[z]=x.push(z)))
          z=s.replace(r,(r,g,h)=>(k+=k)&j?g+'_/'+h+'_\\':r,k=1);
  return b+'__'[R](n)+x[Math.random()*t|0]
}

function go()
{
  var n = N.value | 0,
  t0 = performance.now(),
  r = F(n),
  t1 = performance.now();

  O.innerHTML = r+'\n\nTime (msec): '+(t1-t0)
}
```

```
N: <input id=N value=3><button onclick="go()">GO</button>
<pre id=O></pre>
```

# Answer
> 1 votes
# SmileBASIC, 241 bytes

```
INPUT N
T=N*2CLS?" "*N;"__"*N
DIM B[T]FOR I=-1TO N-1O=1P=N+I*2FOR J=0TO T-1IF I<0THEN O=ABS(J0N+.5)<<0B[J]=O?" "*O;MID$("\/\",J<N,2)*(T-O)ELSE R=P<N*3+I*2-J&&RND(2)P=P+(R*2-1)*(O==R)A=P<=B[J]R=R||A:P=P+A:LOCATE P,J+1?"_"B[J]=P+1O=R
NEXT
NEXT

```

Heavily based off of Matty's answer

# Answer
> 1 votes
# x86 machine code, 155 bytes

Hexdump:

```
60 8b fa 51 b0 20 f3 aa 59 51 b0 5f 03 c9 f3 aa
5e b0 0a aa 57 5f 57 b7 2f 8d 14 36 8b ce 2b ca
75 03 80 f7 73 7d 02 f7 d1 51 b0 20 f3 aa 59 8a
c7 aa 8b ee 53 6b d9 fe 8d 5c b3 ff 53 6b de fc
8b 5c 1f fe 8b 47 fe 80 fc 5f 74 23 8a c4 34 73
3c 2f 75 0a 80 ff 5f 74 3e 80 ff 5c 74 37 c1 eb
08 66 81 fb 2f 5c 74 2f 0f c7 f3 d1 eb 72 24 aa
3c 5f 75 01 4d 5b 4b 75 c3 5b 85 ed 75 97 32 c7
3c 73 75 91 b0 20 f3 aa b0 0a aa 4a 75 8e 88 17
5f 61 c3 b3 5f 8a fb 8a c7 eb d4

```

Explanation:

It's a `fastcall` function. It takes the size of the hexagon, `n`, in `ecx`, and a pointer to output string in `edx`.

First of all, it prints the first line: a few spaces and a few underscores. Then, it goes into a double loop: outer loop of lines, and inner loop of chars.

Each line starts with a few spaces and a border char (either `/` or `\`, depending on whether we are in upper or lower half of the output). Last chars in each line are spaces and a newline byte. The chars in the middle are generated according to the following rules. They guarantee that the output is a valid tiling.

1. If previous char is `_`, current char must be the same as the one to the left of it:

```
(case 1) /_/

(case 2) \_\

```
2. If previous char is `\` and upper char is `_`, current char must be `_`:

```
 _
\_

```
3. If previous and upper chars are `\`, current char must be equal to upper-left char:

```
(case 1) _\
         \_

(case 2) /\
         \/

```
4. If upper char is `/` and upper-right char is `\`, current char must be `\`:

```
/\
\

```
5. If none of the above holds, choose one of the following two possibilities for current char randomly:

* Underscore `_`
    * Slash with opposite direction from the previous slash: `/\` or `\/`

To implement these rules, it loads 4 bytes from the upper line into `ebx` and 4 bytes from current line into `eax`. Then, `ah` is the previous char, while `al` is the one preceding it. Also, `bl` is the upper-left char, `bh` is the upper char, and the byte in `ebx` above `bh` is the upper-right char. After taking into account the upper-left char, it shifts `ebx` right by 8 bits so the upper-right char becomes accessible in `bh`.

To flip the direction of a slash, it does `XOR` with `0x73`.

After finishing a line, it checks two conditions:

1. Last char must be a slash in the appropriate direction (opposite to the direction of the first slash in line)
2. There must be exactly `n` underscores in the line

If either condition is violated, it starts over from first line. So for large `n`, the output will be very slow, because successful execution requires luck in each line. The following example output for `n = 8` takes about a minute to calculate:

```
        ________________
       /_/_/_/\_\_\_\_\_\
      /_/_/_/\/_/\_\_\_\_\
     /_/_/\_\/\_\/_/_/_/\_\
    /_/_/\/\_\/_/_/_/_/\/_/\
   /_/\_\/\/_/_/_/\_\_\/_/\/\
  /\_\/\_\/_/\_\_\/_/_/_/\/\/\
 /\/_/\/_/\_\/_/\_\_\_\_\/\/\/\
/\/\_\/_/\/_/\_\/_/_/\_\_\/\/\/\
\/\/_/\_\/\_\/\_\_\_\/\_\_\/\/\/
 \/_/\/_/\/\_\/_/_/_/\/_/\_\/\/
  \_\/_/\/\/_/_/_/\_\/_/\/_/\/
   \_\_\/\/_/\_\_\/\_\_\/_/\/
    \_\_\/_/\/\_\_\/_/_/_/\/
     \_\_\_\/\/_/_/_/_/_/\/
      \_\_\_\/_/\_\_\_\_\/
       \_\_\_\_\/_/_/_/_/

```

Here is assembly source code mixed with disassembly. I took it while stopped at a breakpoint in Visual Studio.

```
        pushad;
10014190 60                   pushad
        mov edi, edx;
10014191 8B FA                mov         edi,edx

        push ecx;
10014193 51                   push        ecx
        mov al, ' ';
10014194 B0 20                mov         al,20h
        rep stosb;
10014196 F3 AA                rep stos    byte ptr es:[edi]
        pop ecx;
10014198 59                   pop         ecx

        push ecx;
10014199 51                   push        ecx
        mov al, '_';
1001419A B0 5F                mov         al,5Fh
        add ecx, ecx;
1001419C 03 C9                add         ecx,ecx
        rep stosb;
1001419E F3 AA                rep stos    byte ptr es:[edi]
        pop esi; // esi = n
100141A0 5E                   pop         esi

        mov al, '\n';
100141A1 B0 0A                mov         al,0Ah
        stosb;
100141A3 AA                   stos        byte ptr es:[edi]

        push edi;
100141A4 57                   push        edi
    again:
        pop edi;
100141A5 5F                   pop         edi
        push edi;
100141A6 57                   push        edi

        mov bh, '/'; // bh = first char in line
100141A7 B7 2F                mov         bh,2Fh
        lea edx, [esi + esi]; // edx = line index
100141A9 8D 14 36             lea         edx,[esi+esi]

    line_loop:
        mov ecx, esi;
100141AC 8B CE                mov         ecx,esi
        sub ecx, edx;
100141AE 2B CA                sub         ecx,edx
        jnz skip1;
100141B0 75 03                jne         doit+25h (100141B5h)
        xor bh, '\\' ^ '/';
100141B2 80 F7 73             xor         bh,73h
    skip1:
        jge skip2;
100141B5 7D 02                jge         doit+29h (100141B9h)
        not ecx;    // ecx = spaces before and after chars
100141B7 F7 D1                not         ecx
    skip2:

        push ecx;
100141B9 51                   push        ecx
        mov al, ' ';
100141BA B0 20                mov         al,20h
        rep stosb;
100141BC F3 AA                rep stos    byte ptr es:[edi]
        pop ecx;
100141BE 59                   pop         ecx

        mov al, bh;
100141BF 8A C7                mov         al,bh
        stosb;
100141C1 AA                   stos        byte ptr es:[edi]

        mov ebp, esi; // ebp = underscore counter
100141C2 8B EE                mov         ebp,esi

        push ebx;
100141C4 53                   push        ebx
        imul ebx, ecx, -2;
100141C5 6B D9 FE             imul        ebx,ecx,0FFFFFFFEh
        lea ebx, [ebx + 4 * esi - 1]; // ebx = char counter
100141C8 8D 5C B3 FF          lea         ebx,[ebx+esi*4-1]

    i_loop:
        push ebx;
100141CC 53                   push        ebx

        imul ebx, esi, -4;
100141CD 6B DE FC             imul        ebx,esi,0FFFFFFFCh
        mov ebx, [edi + ebx - 2];
100141D0 8B 5C 1F FE          mov         ebx,dword ptr [edi+ebx-2]
        mov eax, [edi - 2];
100141D4 8B 47 FE             mov         eax,dword ptr [edi-2]

        cmp ah, '_';
100141D7 80 FC 5F             cmp         ah,5Fh
        je x_done;
100141DA 74 23                je          doit+6Fh (100141FFh)
        mov al, ah;
100141DC 8A C4                mov         al,ah
        xor al, '/' ^ '\\';
100141DE 34 73                xor         al,73h

        cmp al, '/';
100141E0 3C 2F                cmp         al,2Fh
        jne al_diff;
100141E2 75 0A                jne         doit+5Eh (100141EEh)

        cmp bh, '_';
100141E4 80 FF 5F             cmp         bh,5Fh
        je mov_al_bh;
100141E7 74 3E                je          skip5+22h (10014227h)

        cmp bh, '\\';
100141E9 80 FF 5C             cmp         bh,5Ch
        je mov_al_bl;
100141EC 74 37                je          skip5+20h (10014225h)

    al_diff:
        shr ebx, 8;
100141EE C1 EB 08             shr         ebx,8
        cmp bx, '\\' << 8 | '/';
100141F1 66 81 FB 2F 5C       cmp         bx,5C2Fh
        je mov_al_bh;
100141F6 74 2F                je          skip5+22h (10014227h)

        rdrand ebx;
100141F8 0F C7 F3             rdrand      ebx
        shr ebx, 1;
100141FB D1 EB                shr         ebx,1
        jc mov_al_underscore;
100141FD 72 24                jb          skip5+1Eh (10014223h)

    x_done:
        stosb;
100141FF AA                   stos        byte ptr es:[edi]
        cmp al, '_';
10014200 3C 5F                cmp         al,5Fh
        jne skip5;
10014202 75 01                jne         skip5 (10014205h)
        dec ebp;
10014204 4D                   dec         ebp

    skip5:
        pop ebx;
10014205 5B                   pop         ebx
        dec ebx;
10014206 4B                   dec         ebx
        jnz i_loop;
10014207 75 C3                jne         doit+3Ch (100141CCh)

        pop ebx;
10014209 5B                   pop         ebx
        test ebp, ebp;
1001420A 85 ED                test        ebp,ebp
        jne again;
1001420C 75 97                jne         doit+15h (100141A5h)
        xor al, bh;
1001420E 32 C7                xor         al,bh
        cmp al, '/' ^ '\\';
10014210 3C 73                cmp         al,73h
        jne again;
10014212 75 91                jne         doit+15h (100141A5h)

        mov al, ' ';
10014214 B0 20                mov         al,20h
        rep stosb;
10014216 F3 AA                rep stos    byte ptr es:[edi]

        mov al, '\n';
10014218 B0 0A                mov         al,0Ah
        stosb;
1001421A AA                   stos        byte ptr es:[edi]

        dec edx;
1001421B 4A                   dec         edx
        jne line_loop;
1001421C 75 8E                jne         doit+1Ch (100141ACh)

        mov [edi], dl; // terminating zero byte
1001421E 88 17                mov         byte ptr [edi],dl

        pop edi;
10014220 5F                   pop         edi
        popad;
10014221 61                   popad
        ret;
10014222 C3                   ret

    mov_al_underscore:
        mov bl, '_';
10014223 B3 5F                mov         bl,5Fh
    mov_al_bl:
        mov bh, bl;
10014225 8A FB                mov         bh,bl
    mov_al_bh:
        mov al, bh;
10014227 8A C7                mov         al,bh
        jmp x_done;
10014229 EB D4                jmp         doit+6Fh (100141FFh)

```

Here is C++ code which I used to develop my assembly code:

```
#include <stdio.h>
#include <iostream>
#include <random>
#include <set>
#include <string>

#define MY 1

std::random_device rd;
std::mt19937 gen(rd());
std::bernoulli_distribution distr(0.5);

#if MY
__declspec(naked) void __fastcall doit(int, char*)
{
    _asm {
        pushad;
        mov edi, edx;

        push ecx;
        mov al, ' ';
        rep stosb;
        pop ecx;

        push ecx;
        mov al, '_';
        add ecx, ecx;
        rep stosb;
        pop esi; // esi = n

        mov al, '\n';
        stosb;

        push edi;
    again:
        pop edi;
        push edi;

        mov bh, '/'; // bh = first char in line
        lea edx, [esi + esi]; // edx = line index

    line_loop:
        mov ecx, esi;
        sub ecx, edx;
        jnz skip1;
        xor bh, '\\' ^ '/';
    skip1:
        jge skip2;
        not ecx;    // ecx = spaces before and after chars
    skip2:

        push ecx;
        mov al, ' ';
        rep stosb;
        pop ecx;

        mov al, bh;
        stosb;

        mov ebp, esi; // ebp = underscore counter

        push ebx;
        imul ebx, ecx, -2;
        lea ebx, [ebx + 4 * esi - 1]; // ebx = char counter

    i_loop:
        push ebx;

        imul ebx, esi, -4;
        mov ebx, [edi + ebx - 2];
        mov eax, [edi - 2];

        cmp ah, '_';
        je x_done;
        mov al, ah;
        xor al, '/' ^ '\\';

        cmp al, '/';
        jne al_diff;

        cmp bh, '_';
        je mov_al_bh;

        cmp bh, '\\';
        je mov_al_bl;

    al_diff:
        shr ebx, 8;
        cmp bx, '\\' << 8 | '/';
        je mov_al_bh;

        rdrand ebx;
        shr ebx, 1;
        jc mov_al_underscore;

    x_done:
        stosb;
        cmp al, '_';
        jne skip5;
        dec ebp;

    skip5:
        pop ebx;
        dec ebx;
        jnz i_loop;

        pop ebx;
        test ebp, ebp;
        jne again;
        xor al, bh;
        cmp al, '/' ^ '\\';
        jne again;

        mov al, ' ';
        rep stosb;

        mov al, '\n';
        stosb;

        dec edx;
        jne line_loop;

        mov [edi], dl; // terminating zero byte

        pop edi;
        popad;
        ret;

    mov_al_underscore:
        mov bl, '_';
    mov_al_bl:
        mov bh, bl;
    mov_al_bh:
        mov al, bh;
        jmp x_done;
    }
}
#else // not MY
void doit(int n, char* s)
{
    for (int i = 0; i < n; ++i)
        *s++ =' ';
    for (int i = 0; i < n * 2; ++i)
        *s++ ='_';
    *s++ ='\n';
    char* save = s;
again:
    for (int line = 2 * n; line > 0; --line)
    {
        int spaces = n - line;
        char border1 = '\\';
        if (n - line < 0)
        {
            border1 = '/';
            spaces = ~spaces;
        }
        for (int i = 0; i < spaces; ++i)
            *s++ = ' ';
        *s++ = border1;
        int check = n;
        for (int i = 4 * n - 1 - 2 * spaces; i; --i)
        {
            char al = s[-2];
            char ah = s[-1];
            char bl = s[-4 * n - 2];
            char bh = s[-4 * n - 1];
            char bk = s[-4 * n - 0];

            if (ah == '_')
                goto x_done;
            al = ah ^ '/' ^ '\\';
            if (al != '/')
                goto al_diff;
            if (bh == '_')
            {
                al = bh;
                goto x_done;
            }
            else if (bh == '\\')
            {
                al = bl;
                goto x_done;
            }

        al_diff:
            bl = bh;
            bh = bk;
            if (bl == '/' && bh == '\\')
            {
                al = bh;
            }
            else if (distr(gen))
            {
                al = '_';
            }

        x_done:
            *s++ = al;
            if (al == '_')
                --check;
        }
        if (check)
        {
            s = save;
            goto again;
        }
        if (s[-1] != (border1 ^ '/' ^ '\\'))
        {
            s = save;
            goto again;
        }
        for (int i = 0; i < spaces; ++i)
            *s++ = ' ';
        *s++ ='\n';
    }
    *s++ ='\0';
}
#endif // MY

int main(void)
{
    char s[1000];
    std::set<std::string> results;
    while (true)
    {
        doit(3, s);
        if (!results.count(s))
        {
            puts(s);
            results.insert(s);
            std::cout << results.size() << '\n';
        }
    }
}

```

---
Tags: code-golf, ascii-art, combinatorics, random, tiling
---