27
\$\begingroup\$

Input

A calendar year from 927 to 2022.

Output

You can use any three distinguishable outputs. As an example,

“K” (short for King)

or

“Q” (short for Queen)

depending on which of the two England had in that year. If there was both a King and Queen in that year you can output either.

If there was no King or Queen for the whole of that year, your code must output something that is not one of those two messages.

Dates

Kings: 927-1553, 1603-1649, 1660-1702, 1714-1837, 1901-1952, 2022

Queens: 1553-1603, 1689-1694, 1702-1714, 1837-1901, 1952-2022

Neither: 1650-1659

\$\endgroup\$
1
  • 10
    \$\begingroup\$ For those wondering "Why 927?" (instead of 886 or 1066), that's the year that Æthelstan officially became king of "the English" instead of "the Anglo-Saxons". \$\endgroup\$
    – dan04
    Sep 19, 2022 at 17:11

13 Answers 13

42
\$\begingroup\$

Squire, 194 characters

d=tally(inquire())i=\(d,s,e)=>s<=d&&d<=e;o=𝔎𝔦𝔫𝔤;if i(d,MDCL,MDCLIX){o=𝔏𝔬𝔯𝔡 𝔓𝔯𝔬𝔱𝔢𝔠𝔱𝔬𝔯}alas if i(d,MCMLII,MMXXII)||i(d,MDCCCXXXVII,MCMI)||i(d,MDCCII,MDCCXIV)||i(d,MDLIII,MDCIII){o=𝔔𝔲𝔢𝔢𝔫}proclaim(o)

This contest doth be marvelously suited for ye medieval-inspired parlance, Squire. Whilst Squire doth hath a veritable cornucopia of features, lamentably suitability for golfing doth be nary amongst them.

Squire only has roman numeral literals, as well as some fairly length constructs (e.g. inquire, tally, proclaim), so it's not as short as other languages. On the plus side, squire has bare words—however only when the strings are comprised entirely exclusively of the unicode fraktur characters or whitespace.

Unfortunately, the interpreter is not able to fit onto TIO or anything else, so if you want to test it you'll need to build locally...

Ungolfed, the program is:

N.B. Journeys are functions, and you get a reward for returning from them.
journey in(date, start, end) {
    reward start <= date && date <= end
}

N.B. `tally` converts to a number, `inquire` reads from stdin. 
N.B. In addition to roman numerals, `tally` also reads arabic ones too.
date = tally(inquire())

N.B. Using the fraktur literals, set the default value for `whom`.
N.B. This is sugar for "King".
whom = 𝔎𝔦𝔫𝔤; N.B. The `;` is needed here because the parser is bad lol

N.B. Check to see if the date is within Cromwell's time.
if in(date, MDCL, MDCLIX) { 
    whom = 𝔏𝔬𝔯𝔡 𝔓𝔯𝔬𝔱𝔢𝔠𝔱𝔬𝔯
} alas if
    in(date, MCMLII, MMXXII)
    || in(date, MDCCCXXXVII, MCMI)
    || in(date, MDCCII, MDCCXIV)
    || in(date, MDLIII, MDCIII)
{
    whom = 𝔔𝔲𝔢𝔢𝔫
}

N.B. The printing press wasn't around way back when. So instead we have
N.B. the town crier proclaim our outputs.
proclaim("The {whom} reigned during the year {date}")
\$\endgroup\$
9
  • \$\begingroup\$ Definitely a very suitable answer! \$\endgroup\$
    – user108721
    Sep 18, 2022 at 8:18
  • 1
    \$\begingroup\$ Surely that "is" should also be "doth be", and maybe change "the" to "ye" while you're at it? \$\endgroup\$
    – Neil
    Sep 18, 2022 at 10:35
  • \$\begingroup\$ Trying to build Squire on WSL gives: fatal error: ffi/ffi.h: No such file or directory \$\endgroup\$
    – naffetS
    Sep 18, 2022 at 18:42
  • \$\begingroup\$ I get the same error in a Docker container, even with apt-get install libffi-dev. \$\endgroup\$
    – naffetS
    Sep 18, 2022 at 19:05
  • 3
    \$\begingroup\$ @Neil As I understand it, "ye" is actually a pronoun form. The use of it as "the" is a french misreading of the word spelled Þe. Þ (thorn) is one of the lost English letters, pronounced as soft "th. \$\endgroup\$
    – David G.
    Sep 19, 2022 at 0:58
21
\$\begingroup\$

JavaScript (Node.js), 50 bytes

Returns \$0\$ for Queen, \$1\$ for King, or \$2\$ for neither.

This code includes some unprintable characters.

y=>2132%Buffer(`2/
+{@3`).find(c=>(y-=c)<1542)&3

Try it online!

How?

The ASCII codes of the data string are:

[ 11, 50, 47, 10, 43, 12, 123, 64, 51 ]

They represent the number of years to be added to get the exclusive upper bound of the next interval, starting at \$1542\$.

Once the correct interval has been identified, we apply the following formula to its encoding number \$N\$ to figure out whether it was a King, a Queen or neither:

$$(2132 \bmod N)\bmod 4$$

The last interval is not explicitly encoded. For any input greater than \$1952\$, find() returns undefined which is turned into NaN. But because we use a bitwise AND with \$3\$ rather than an actual modulo \$4\$, it is eventually coerced to \$0\$ -- the expected result for Queen Elizabeth II.

N Exclusive upper bound Interval 2132 mod N and 3 Result
11 1553 927 - 1552 9 1 King
50 1603 1553 - 1602 32 0 Queen
47 1650 1603 - 1649 17 1 King
10 1660 1650 - 1659 2 2 Neither
43 1703 1660 - 1702 25 1 King
12 1715 1703 - 1714 8 0 Queen
123 1838 1715 - 1837 41 1 King
64 1902 1838 - 1901 20 0 Queen
51 1953 1902 - 1952 41 1 King
undefined n/a 1953 - ... NaN 0 Queen
\$\endgroup\$
3
  • \$\begingroup\$ When does this imply the monarch will change next? \$\endgroup\$
    – Simd
    Jan 23 at 9:40
  • \$\begingroup\$ @Simd Once we reach \$N>1952\$, the output does not change anymore. So this code is not doing any prediction about future monarchs. \$\endgroup\$
    – Arnauld
    Jan 23 at 15:21
  • \$\begingroup\$ That's sad, but understandable. \$\endgroup\$
    – Simd
    Jan 23 at 15:30
11
\$\begingroup\$

Python 3, 60 bytes

A function that returns 0 for King, 1 for Queen, and 2 for Neither.

lambda n:sum(c>n-ord('ؑٱڦޟܭ'[c%5])>0for c in b'2@I')

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Ooh this looks clever! \$\endgroup\$
    – user108721
    Sep 18, 2022 at 10:18
8
\$\begingroup\$

Knight (v2.0-alpha), 78 bytes

O I|>927=xP?GxF3'165'0I|&<1553x<1603x|&<1702x<1714x|&<1837x<1901x&<1952x<2022x

Try it online!

Nothing special, just check for ranges with < and >. Since we have to output just three distinct things, 0 is for when it's neither, true for a queen and false for a king. Slightly unminified:

O I|>927=xP?GxF3'165'0
  I|&<1553x<1603x
   |&<1702x<1714x
   |&<1837x<1901x
    &<1952x<2022x
\$\endgroup\$
1
  • 1
    \$\begingroup\$ A Knight of the realm. \$\endgroup\$
    – user108721
    Sep 18, 2022 at 8:18
6
\$\begingroup\$

Python 3.8,  58  57 bytes

lambda y:9%(6-sum((y:=y-v)<1500for v in b'61/\n+|?4'))%2

(Contains an unprintable byte between + and |.)

An unnamed function that accepts an integer from \$[927,2022]\$ and:

  • produces a ZeroDivisionError for years when neither a king nor queen reigned;
  • returns \$0\$ if a king was on the throne during the year (except Charles III (2022)); or
  • returns \$1\$ otherwise (when a queen was on the throne the entire year, or 2022)

Try it online!

How?

The byte-string b'61/\n+|?4' encodes the integers [54,49,47,10,43,11,124,63,52]. The for loop subtracts each from the year, y, cumulatively by employing the walrus operator, :=, and counts, with sum(...), how many are less than 1500 (\$54\$ years before the first lone queen). To force an error for the sixth period (no monarch) and two distinct values otherwise arithmetic is employed:

years sum=N 6-N 9 mod (6-N) (9 mod (6-N)) mod 2 identifies
927-1553 9 -3 0 0 king
1554-1602 8 -2 -1 1 queen
1603-1649 7 -1 0 0 king
1650-1659 6 0 err err none
1660-1702 5 1 0 0 king
1703-1713 4 2 1 1 queen
1714-1837 3 3 0 0 king
1738-1900 2 4 1 1 queen
1901-1953 1 5 4 0 king
1954-2022 0 6 3 1 queen

Non-erroring alternative, 57 bytes

lambda y:2**sum((y:=y-v)<1500for v in b'61/\n+|?4')%40%3

Returns \$2\$ for King, \$1\$ for Queen, or \$0\$ for neither.

Try it online!

How?

Same sum as before with different arithmetic:

years sum=N 2**N (2**N) mod 40 ((2**N) mod 40) mod 3 identifies
927-1553 9 512 32 2 king
1554-1602 8 256 16 1 queen
1603-1649 7 128 8 2 king
1650-1659 6 64 24 0 none
1660-1702 5 32 32 2 king
1703-1713 4 16 16 1 queen
1714-1837 3 8 8 2 king
1738-1900 2 4 4 1 queen
1901-1953 1 2 2 2 king
1954-2022 0 1 1 1 queen
\$\endgroup\$
4
  • \$\begingroup\$ Is erroring acceptable? \$\endgroup\$
    – Seggan
    Sep 18, 2022 at 21:17
  • \$\begingroup\$ It says "any three distinguishable outputs", so I don't see why not. \$\endgroup\$ Sep 18, 2022 at 21:28
  • 2
    \$\begingroup\$ @Seggan I've added a non-erroring alternative that ties. \$\endgroup\$ Sep 18, 2022 at 23:24
  • \$\begingroup\$ The non-erroring version is great. \$\endgroup\$
    – user108721
    Sep 19, 2022 at 0:57
5
\$\begingroup\$

x86-64 machine code, 38 32 31 bytes

48 B9 64 12 33 20 9F A1 52 B8 31 C0 99 B6 06 88 EA 48 C1 C1 07 14 04 29 D7 99 79 F3 24 05 C3

Try it online!

Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes the year number in EDI and returns a value in EAX: 4 for kings, 0 for queens, and 1 for the interregnum.

In assembly:

f:
    mov rcx, 18<<8 | 50<<1 | 46<<58 | 10<<51 | 42<<44 | 12<<37 | 124<<30 | 64<<23 | 51<<16
                    # Put this constant in RCX.
    xor eax, eax    # Set EAX to 0.
    cdq             # Set EDX to 0 by sign-extending EAX.
    mov dh, 6       # Set the second-lowest byte of EDX to 6.
repeat:
    mov dl, ch      # Set the low byte of EDX to the second-lowest byte of RCX.
    rol rcx, 7      # Rotate RCX left by 7 bits.
    adc al, 4       # Add 4+CF to AL.
    sub edi, edx    # Subtract EDX from EDI.
    cdq             # Set EDX to 0 by sign-extending EAX.
    jns repeat      # Jump back to repeat if the subtraction's result is nonnegative.
    and al, 5       # Keep only the 1s bit and the 4s bit of AL.
    ret             # Return.

The basic way this works is to decrease the given number by 1554, 50, 46, 10, 42, 12, 124, 64, 51, 137, stopping when the result is negative, so that the loop executes a different number of times for each period of constant output.

The years of change were assigned to make all the period lengths even, except the last two. This allows the values to be stored in 7 bits each, so that nine can fit into a 64-bit register, while extracting 8 bits at a time (which includes the previous value's low bit) and still functioning correctly.

The 10th value extracted (for Elizabeth II's reign) entirely overlaps the 1st and 9th values, so we can only control its high bit, by assigning the year 1952. But because only years up to 2022 have to be handled, it is OK for this value to be higher than necessary.

The 1st value, which is 1554, is created by setting the second-lowest byte before the loop and then inserting the low byte within the loop (saving 2 bytes compared to pre-setting the whole thing).

To handle the interregnum, notice that the low bit of RCX ends up being 1 only when the given year is during the interregnum or the king period that follows it, and that is the same bit that gets copied into CF by the ROL instruction. An ADC instruction adds 4+CF to AL with each iteration, so that the 4s bit alternates between 0 and 1, while the 1s bit stays 0 initially, then becomes 1 for the interregnum and becomes 0 again for the next period, and stays 0 thereafter. At the end, an AND instruction picks out those two bits.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Awesome! Not that I understand it fully. \$\endgroup\$
    – user108721
    Sep 18, 2022 at 17:27
4
\$\begingroup\$

Retina 0.8.2, 118 117 bytes

165.
LP
155[4-9]|15[6-9].|160[0-2]|170[3-9]|171[0-3]|183[89]|18[4-9].|1900|195[3-9]|19[4-9].|20[01].|202[01]
Q
...+
K

Try it online! Link includes some test cases. Outputs K if there was ever a King in that year, otherwise Q if there was ever a Queen in that year, otherwise LP, as the Cromwells used the title "Lord Protector" for some of that period. Edit: Saved 1 byte thanks to @pxeger.

\$\endgroup\$
4
  • \$\begingroup\$ I think ....? can be shortened to ...+, and, if you make the output for Oliver Cromwell one character only, just ..+ \$\endgroup\$
    – pxeger
    Sep 18, 2022 at 9:27
  • \$\begingroup\$ @pxeger It's not just Oliver! \$\endgroup\$
    – user108721
    Sep 18, 2022 at 10:01
  • \$\begingroup\$ @graffe You know what I mean! \$\endgroup\$
    – pxeger
    Sep 18, 2022 at 10:02
  • \$\begingroup\$ @pxeger yes of course \$\endgroup\$
    – user108721
    Sep 18, 2022 at 10:03
4
\$\begingroup\$

Jelly,  25 23  22 bytes

⁽£4;“1/½+¿|?4‘Ä<⁸SḂ⁻¡3

A monadic Link that accepts an integer in \$[927,2022]\$ and yields:

  • \$0\$ if there was a king on the throne at any point during the year (except for Charles III (2022));
  • \$3\$ if neither a king nor queen reigned; or
  • \$1\$ otherwise (if a queen and only a queen reigned all year or Charles III succeeded (2022)).

Try it online! Or see all years.

How?

⁽£4;“1/½+¿|?4‘Ä<⁸SḂ⁻¡3 - Link: integer, Y
⁽£4                    - 1553
    “1/½+¿|?4E‘        - code-page indices = [49,47,10,43,11,124,63,52]
   ;                   - concatenate -> [1553,49,47,10,43,11,124,63,52]
              Ä        - accumulate -> [1553,1602,1649,1659,1702,1713,1837,1900,1952]
               <⁸      - less than Y? (vectorises)
                 S     - sum -> S
                    ¡  - repeat...
                   ⁻ 3 - ...number of times: not equal to three
                                             (leave as 3 when no monarch)
                  Ḃ    - ...action: mod 2
                                    -> 0 if a king during the year except 2022; or
                                       1 otherwise
\$\endgroup\$
1
  • \$\begingroup\$ Very happy to have a Jelly answer! \$\endgroup\$
    – user108721
    Sep 18, 2022 at 17:29
2
\$\begingroup\$

Perl 5 -Mutf8 -MList::Util=pairgrep -p, 67 bytes

$_=/^165/?N:pairgrep{$a<$_&&$_<$b}unpack"U*","ؑكڙڞڦڲܭݭޠߦ"

Try it online!

Outputs 1 for a Queen, 0 for a King, or N for none.

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

Zsh, 67 bytes

>$1<165?&&bye 2
< (1(<553-603>|6<89-94>|7<2-14>|<837-901>)|<1952->)

Attempt This Online!

Outputs via exit code: 0 for queen, 1 for king, and 2 for neither.

Explanation:

  • >$1: create a file named according to the input
  • <165?: search for a file beginning with 165 (as there was no monarch during that decade)
    • &&bye 2: if one exists, exit early with exit code 2
  • <: otherwise, search for a file matching the long pattern of periods when there was a queen
    • <x-y> is a Zsh pattern searching for a number in the range \$ [x, y] \$
  • Zsh will then exit with 1 if no file matches that pattern, and 0 otherwise
\$\endgroup\$
1
  • \$\begingroup\$ Very impressive! \$\endgroup\$
    – user108721
    Sep 18, 2022 at 9:28
1
\$\begingroup\$

C (gcc), 59 bytes

*p;f(y){for(p=L"2/\n+{@3,//";y>1552;)y-=*p++;y=2704%*p&3;}

Try it online!

-2 bytes thanks to ceilingcat!!

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

Python 3, 131 bytes

a=[1553,1603,1689,1694,1702,1714,1837,1901,1952,2022]
f=lambda x:"AKQ"[any(i for i in range(5)if a[2*i]<x<a[2*i+1])*2or x//10!=165]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ 93: Try it online!. (Outputs with False/True/2 instead of A/K/Q, as there's no reason to use meaningful formats) \$\endgroup\$
    – pxeger
    Sep 18, 2022 at 10:02
  • 1
    \$\begingroup\$ @pxeger Maybe that should be a separate answer? \$\endgroup\$
    – user108721
    Sep 18, 2022 at 17:30
0
\$\begingroup\$

Python 3, 120 bytes

r=lambda s,l:{*range(s,s+l)}
f=lambda y:2*(y in r(1650,10))+(y in r(1553,51)|r(1689,6)|r(1702,13)|r(1837,65)|r(1952,71))

Try it online!

Interpreting the output: 0 = King, 1 = Queen, 2 = Neither.

Nothing too fancy here. Commented version of f:

f=lambda y:(
  2

  # y in r(1650,10) = is neither king nor queen
  * (y in r(1650,10))

  # y in ... = is queen
  + (y in r(1553,51)|r(1689,6)|r(1702,13)|r(1837,65)|r(1952,71))
)
\$\endgroup\$
1
  • \$\begingroup\$ You could save 3 bytes by switching to Python 2 where range results in a list and so you can just concatenate them together. \$\endgroup\$
    – Neil
    Sep 21, 2022 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.