33
\$\begingroup\$

Tonight, 31 January 2020, Brexit will happen and the United Kingdom will leave the European Union, the first time that the number of EU member states will decrease.

Your job is to take a date and output the number of EU1 members on that date, according to the following table:

| Start      | End        | Number of members 
| 0          | 1957-12-31 | 0
| 1958-01-01 | 1972-12-31 | 6
| 1973-01-01 | 1980-12-31 | 9
| 1981-01-01 | 1985-12-31 | 10
| 1986-01-01 | 1994-12-31 | 12
| 1995-01-01 | 2004-04-30 | 15
| 2004-05-01 | 2006-12-31 | 25
| 2007-01-01 | 2013-06-30 | 27
| 2013-07-01 | 2020-01-31 | 28
| 2020-02-01 | Inf        | 27

Input may take one of the following forms:

  • your language's date format
  • any ordering of integers for year, month and day with any separator (e.g. YYYYMMDD or DD/MM/YYYY)
  • number of days lapsed since some epoch.

This is , so shortest code wins!

1. or EEC before 1993

\$\endgroup\$
  • 1
    \$\begingroup\$ I see the Python answer is using an input as the number of days since 1957-12-31 and the JavaScript answer is taking an input in the format yyyyMM without the dd. Are these both allowed according to the "in any reasonable format"? Both would save bytes in my answer as well. \$\endgroup\$ – Kevin Cruijssen Jan 31 at 12:35
  • 10
    \$\begingroup\$ I feel like in any reasonable format is not objective enough... \$\endgroup\$ – Luis Mendo Jan 31 at 13:19
  • 1
    \$\begingroup\$ @LuisMendo I think it's OK. It just has to uniquely specify the day. Are you worried there is some possible loophole? \$\endgroup\$ – Anush Jan 31 at 14:31
  • 3
    \$\begingroup\$ @Anush The problem is how to tell if a format qualifies as "reasonable" or not. For instance, I wouldn't have guessed that Number of days since some epoch (or even months?) does. So a clearer specification is needed \$\endgroup\$ – Luis Mendo Jan 31 at 15:58
  • 2
    \$\begingroup\$ @LuisMendo I have clarified the input format. \$\endgroup\$ – Robin Ryder Jan 31 at 17:09

12 Answers 12

12
\$\begingroup\$

Javascript, 85 83 Bytes

a=d=>d<0?0:d<180?6:d<276?9:d<336?10:d<444?12:d<556?15:d<588?25:d<666?27:d<745?28:27

It takes an input as a float as the months / fractions of months passed since 1958-01-01
(0 for 1958-01-01T00:00:00 and a negative number for any previous date)

(Since number of days from some epoch is allowed, I assume that also a number of months is valid, as well)

Try it Online


80 Bytes

(credits: Arnauld)

a=d=>d<0?0:d<180?6:d<276?9:d<336?10:d<444?12:d<556?15:d<588?25:27+(d>=666&d<745)

Sad to see you go, UK

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Awesome Arnauld! \$\endgroup\$ – Fabrizio Calderan Jan 31 at 15:28
  • 3
    \$\begingroup\$ I have clarified what counts as a reasonable input format for dates; number of days since an epoch is allowed but not number of months. Your input format was creative! But it was a loophole, which I have now closed. Your previous version based on number of days would be fine. \$\endgroup\$ – Robin Ryder Jan 31 at 19:31
  • 3
    \$\begingroup\$ since JavaScript can't compete with many other golfing languages I wanted to at least be creative. :) \$\endgroup\$ – Fabrizio Calderan Jan 31 at 19:39
9
\$\begingroup\$

05AB1E, 29 27 26 25 33 bytes

¨12βŽ₅b-‘´`<lp€¸‘Ç.¥@•¿“0p•12в<*O

Try it online!

Input is in the form [yyyy, mm, dd].

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ The most impressive part about this answer is that you thought about using floats as input-format so the compressed integers can all be much shorter. :D \$\endgroup\$ – Kevin Cruijssen Jan 31 at 13:43
  • 3
    \$\begingroup\$ @KevinCruijssen I actually took this idea from the JS answer. I added credit to my answer. \$\endgroup\$ – Grimmy Jan 31 at 13:45
  • 1
    \$\begingroup\$ @KevinCruijssen yes it was impressive, lol \$\endgroup\$ – Fabrizio Calderan Jan 31 at 13:47
  • 2
    \$\begingroup\$ I have clarified what counts as a reasonable input format for dates; number of days since an epoch is allowed but not number of months. \$\endgroup\$ – Robin Ryder Jan 31 at 19:30
7
\$\begingroup\$

Python 2, 110 97 bytes

lambda d:ord('069:<?IKLK'[sum(d>i for i in(0,5479,8401,10227,13514,16922,17897,20270,22676))])-48

Try it online!

-13 bytes, thanks to Jonathan Allan

Takes input as number of days since 1957-12-31 (so 1958-01-01 is day 1)


Python 3, 93 bytes

lambda d:b'069:<?IKLK'[sum(d>i for i in(0,5479,8401,10227,13514,16922,17897,20270,22676))]-48

Try it online!

-4 bytes, thanks to mypetlion

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Save 13 by avoiding the import of bisect \$\endgroup\$ – Jonathan Allan Jan 31 at 22:06
  • 1
    \$\begingroup\$ Python 3 port saves 4 bytes by replacing ord('069... with b'069... \$\endgroup\$ – mypetlion Jan 31 at 23:45
  • \$\begingroup\$ @JonathanAllan Thanks! \$\endgroup\$ – TFeld Feb 4 at 12:37
  • \$\begingroup\$ @mypetlion Thanks :) \$\endgroup\$ – TFeld Feb 4 at 12:37
6
\$\begingroup\$

05AB1E, 42 36 bytes

•AÂʒë.š¡ε%ž·7í•ŽL}в.¥›O•=γ1sæΔ•₆вsè<

Input as number of days since 1957-12-31 (so 1957-12-30 is day -1; 1957-12-31 is day 0; 1958-01-01 is day 1; etc.)

Try it online or verify some more test cases.

Old 42 bytes answer taking input in the format yyyyMMdd:

¨¨•a3|}\§λ’Iœg½þ•ŽOΩв•32Ø•+@O•=γ1sæΔ•₆вsè<

Try it online or verify some more test cases.

•a3|}\§λ’Iœg½þ•ŽOΩв•32Ø•+ can alternatively be •Me1εä~.=ΔΩ»•Ž5ãв.¥•32Ù•+ for the same byte-count: Try it online or verify some more test cases.

Explanation:

•AÂʒë.š¡ε%ž·7í•    # Push compressed integer 813218926689775697373196902446
  ŽL}              # Push compressed integer 5480
     в             # Convert the larger integer to base-5480 as list:
                   #  [5479,2922,1826,3287,3408,975,2373,2406]
      .¥           # Undelta it with leading 0:
                   #  [0,5479,8401,10227,13514,16922,17897,20270,22676]
        ›          # Check for each if it's larger than the (implicit) input-integer
         O         # Take the sum to get the amount of truthy values
•=γ1sæΔ•           # Push compressed integer 122116126451824
 ₆в                # Convert it to base-36 as list:
                   #  [1,7,10,11,13,16,26,28,29,28]
   sè              # Swap to get the sum, and use it to index into this list
     <             # And decrease it by 1
                   # (since a compressed integer/list cannot contain a leading 0)
                   # (after which the result is output implicitly)

¨¨                 # Remove the last two digits from the (implicit) input (the "dd")
  •a3|}\§λ’Iœg½þ•  # Push compressed integer 2722385715080006519908031109868
   ŽOΩ             # Push compressed integer 6203
      в            # Convert the larger integer to base-6203 as list:
                   #  [1,1501,2301,2801,3701,4605,4901,5507,6202]
       •32Ø•       # Push compressed integer 195800
            +      # Add it to each value in the list:
                   #  [195801,197301,198101,198601,199501,200405,200701,201307,202002]
             @     # Check for each if it's larger than or equal to the input minus "dd"
O•=γ1sæΔ•₆вsè<     # Same as above

See this 05AB1E tip of mine (sections How to compress large integers? and How to compress integer lists?) to understand how the compression works.

| improve this answer | |
\$\endgroup\$
6
\$\begingroup\$

Turing Machine Code, 972 1009 bytes

My input is the date in the format specified in the test cases YYYY-MM-DD.

0 0 0 * halt
* 1 _ r €
€ 9 _ r %
* 2 _ r $
$ 0 _ r £
* I 2 r ¢
% 5 _ r ^
% 6 6 r c
% 7 _ r x
% 8 _ r B
% 9 _ r i
% * _ r c
^ * 0 r c
^ 8 6 r c
^ 9 6 r c
B 0 9 r c
B 1 1 r r
B 2 1 r r
B 3 1 r r
B 4 1 r r
B 5 1 r r
B * 1 r e
r * 0 r c
e * 2 r c
x 0 6 r c
x 1 6 r c
x 2 6 r c
x * 9 r c
i 0 1 r 🇪🇺
i 1 1 r 🇪🇺
i 2 1 r 🇪🇺
i 3 1 r 🇪🇺
i 4 1 r 🇪🇺
i * 1 r t
t * 5 r c
🇪🇺 * 2 r c
£ 0 _ r 🇬🇧
£ 1 _ r ★
£ 2 _ r 👑
👑 0 _ r !
👑 * 2 r ¢
! - _ r ~
~ 0 _ r 1
1 1 2 r ☆
1 * 2 r ¢
★ 0 2 r ¢ 
★ 1 2 r ¢
★ 2 2 r ¢
★ 3 _ r &
★ * 2 r ☆
& - _ r @
@ 0 _ r 6
6 0 2 r ¢
6 1 2 r ¢
6 2 2 r ¢
6 3 2 r ¢
6 4 2 r ¢
6 5 2 r ¢
6 6 2 r ¢
6 * 2 r ☆
☆ * 8 r c
🇺🇰 * 5 r c
🇬🇧 1 1 r 🇺🇰
🇬🇧 2 1 r 🇺🇰
🇬🇧 3 1 r 🇺🇰
🇬🇧 4 _ r +
🇬🇧 5 2 r t
🇬🇧 6 2 r t
🇬🇧 * 2 r ¢
¢ * 7 r c
+ - _ r ¬
¬ 0 _ r 4
¬ * 2 r t
4 0 1 r t
4 1 1 r t
4 2 1 r t
4 3 1 r t
4 4 1 r t
4 * 2 r t
6 _ 6 l c
c * _ r c
c _ _ * halt


 

Try it online!

Added a few bytes thanks to Grimmy being a bit more thorough in testing my code than I was.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Seems like it’s all good now! \$\endgroup\$ – Grimmy Jan 31 at 20:32
  • 4
    \$\begingroup\$ What's the point of the 👑 emoji and other multibyte characters? Can they be replaced with characters with lower bytecounts? \$\endgroup\$ – caird coinheringaahing Jan 31 at 22:55
  • \$\begingroup\$ @cairdcoinheringaahing, It's the queen's crown. All of the multibyte characters were chosen for the occassion. \$\endgroup\$ – ouflak Feb 1 at 14:11
4
\$\begingroup\$

Charcoal, 48 bytes

I⌕γ§ &)*,/9;<;LΦ⪪”)¶↶⌕βγ⦄J≦σν{:Xδp⁴E⊙≕⍘H⊙βg”⁶‹ιθ

Try it online! Link is to verbose version of code. Takes input as YYYYMMDD. Explanation:

                 ”...”      Compressed string of YYYYMM values
                ⪪     ⁶     Split into substrings of length 6
              LΦ       ‹ιθ  Count those that appear before the input
   § &)*,/9;<;              Look the count up in a translation table
I⌕γ                         Subtract 32 from the ASCII code
| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

Python 2, 158 150 bytes

i=int(input()[:6]);print((((((((27,28)[202002>i>201306],25)[i<200701],15)[i<200405],12)[i<199501],10)[i<198601],9)[i<198101],6)[i<197301],0)[i<195801]

Try it online!

Takes input as a string in YYYYMMDD format

Alternative Python 2 approach without imports. Simply uses nested list indexing to create the equivalent of a big if/elif structure.

NB: Posted by a British guy who is sorry to see us leave. I'm still all for the Community and working together (whether EU or here).

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Here’s some improvements \$\endgroup\$ – Grimmy Jan 31 at 20:04
  • \$\begingroup\$ Hey @Grimmy, that's well smart and different enough for you to post as your own answer. Fine by me. Same priciple, much cooler solution. I'll certainly upvote. \$\endgroup\$ – ElPedro Jan 31 at 21:52
3
\$\begingroup\$

Jelly, 38 37 bytes

“€ɓ⁴5O/ṖṪOṁṪḋg’ḃ⁽×ỵÄŻ>⁸Sị“÷ñıЀ½µ©¡ñ‘

Try it online!

A monadic link taking the zero-indexed count of days since 1958-01-01 as a integer argument and returning an integer.

Thanks to @JonathanAllan for saving a byte!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ @RobinRyder revised to use days \$\endgroup\$ – Nick Kennedy Jan 31 at 20:07
  • 1
    \$\begingroup\$ >⁸TḢị“¡©µ½€Ðıñ÷ñ‘ -> >⁸Sị“÷ñıЀ½µ©¡ñ‘ saves one (maybe with an off by 1 error to fix?) \$\endgroup\$ – Jonathan Allan Jan 31 at 22:23
  • \$\begingroup\$ Ah no, looks good, I was using wrong origin date. (d-1,d,d+1) :) \$\endgroup\$ – Jonathan Allan Jan 31 at 22:35
1
\$\begingroup\$

AWK, 98 bytes

{m=$1*12+$2-23496}1,$0=m<1?0:m<181?6:m<277?9:m<337?10:m<445?12:m<557?15:m<589?25:27+(m>666&&m<746)

Try it online!

Input format: YYYY MM DD

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 95 bytes

Expects a number of days since 1957-12-31.

n=>[x=0,5479,2922,1826,3287,3408,975,2373,2406].map((d,i)=>x-=(n-=d)>0&&~('52012910'[i]||~1))|x

Try it online!

This is however a bit longer than @FabrizioCalderan's answer, even if it is fixed to use days instead of months.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

x86 (32-bit) assembly, 43 bytes (13 bytes code + 30 bytes data)

This routine expects input in ax as a signed short giving number of days since 1950-01-01, and returns output in al (clobbering edi along the way).

    .text
    .globl eu_members
eu_members: 
    mov $.Ltbl-1, %edi
.Lloop:
    inc %edi
    scas (%edi), %ax
    jg .Lloop
    mov (%edi), %al
    ret
    .section .rodata
.Ltbl:
    .short 2921
    .byte 0
    .short 8400
    .byte 6
    .short 11322
    .byte 9
    .short 13148
    .byte 10
    .short 16435
    .byte 12
    .short 19843
    .byte 15
    .short 20818
    .byte 25
    .short 23191
    .byte 27
    .short 25597
    .byte 28
    .short 32767
    .byte 27

Exact opcodes of the code part (in a linked context so that the relocation of .Ltbl doesn't confuse things):

0804930b <eu_members>:
 804930b:       bf 49 a0 04 08          mov    $0x804a049,%edi
 8049310:       47                      inc    %edi
 8049311:       66 af                   scas   %es:(%edi),%ax
 8049313:       7f fb                   jg     8049310 <eu_members+0x5>
 8049315:       8a 07                   mov    (%edi),%al
 8049317:       c3                      ret    

And here's the test harness I used (note that the assembly code is not PIC safe, so on Debian or Ubuntu systems you will need to pass -no-pie to gcc):

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>

unsigned char eu_members_wrap(short days_since_1950_01_01) {
    unsigned char res;
    __asm__("call eu_members" : "=a"(res) : "0"(days_since_1950_01_01) : "edi", "cc");
    return res;
}

int main(int argc, char* argv[]) {
  struct tm tm;
  time_t epoch, req;
  short days_since_epoch;
  memset(&tm, 0, sizeof(tm));
  tm.tm_year = 50;
  tm.tm_mon = 0;
  tm.tm_mday = 1;
  epoch = mktime(&tm);
  memset(&tm, 0, sizeof(tm));
  tm.tm_year = atoi(argv[1]) - 1900;
  tm.tm_mon = atoi(argv[2]) - 1;
  tm.tm_mday = atoi(argv[3]);
  req = mktime(&tm);
  days_since_epoch = (((unsigned int) (req - epoch)) / (24 * 60 * 60));
  /* printf("epoch = %ld, req = %ld\n", epoch, req);
  printf("Raw number of days: %hd\n", days_since_epoch); */
  printf("EU members: %hhu\n", eu_members_wrap(days_since_epoch));
  return 0;
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Could you use lods (%edi), %al instead of mov (%edi),%al? I am not sure about assembly syntax, but the opcode should work. \$\endgroup\$ – anatolyg Feb 2 at 16:19
  • \$\begingroup\$ No, lods can only read from (%esi) \$\endgroup\$ – Daniel Schepler Feb 2 at 20:51
-3
\$\begingroup\$

Perl 5, 46 bytes

($q,%d)=split;$q--while!exists$d{$q};say$d{$q}

Try it online!

...or try like this on some decent command line:

query=19730101
data="0 0 19580101 6 19730101 9 19810101 10 19860101 12 19950101 15 20040501 25 20070101 27 20130701 28 20200201 27"
echo "$query $data" | perl -nE '($q,%d)=split;$q--while!exists$d{$q};say$d{$q}'
| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ The data is supposed to be contained in the code, not passed as input. \$\endgroup\$ – Arnauld Feb 1 at 17:48
  • \$\begingroup\$ Data is data, code is code, but sometimes code is data and data is code and E=mc² \$\endgroup\$ – Kjetil S. Feb 3 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.