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\$
17
  • 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\$ Jan 31, 2020 at 12:35
  • 10
    \$\begingroup\$ I feel like in any reasonable format is not objective enough... \$\endgroup\$
    – Luis Mendo
    Jan 31, 2020 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\$
    – user9207
    Jan 31, 2020 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, 2020 at 15:58
  • 2
    \$\begingroup\$ @LuisMendo I have clarified the input format. \$\endgroup\$ Jan 31, 2020 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

\$\endgroup\$
3
  • \$\begingroup\$ Awesome Arnauld! \$\endgroup\$ Jan 31, 2020 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\$ Jan 31, 2020 at 19:31
  • 3
    \$\begingroup\$ since JavaScript can't compete with many other golfing languages I wanted to at least be creative. :) \$\endgroup\$ Jan 31, 2020 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].

\$\endgroup\$
4
  • 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\$ Jan 31, 2020 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, 2020 at 13:45
  • 1
    \$\begingroup\$ @KevinCruijssen yes it was impressive, lol \$\endgroup\$ Jan 31, 2020 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\$ Jan 31, 2020 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

\$\endgroup\$
4
  • 3
    \$\begingroup\$ Save 13 by avoiding the import of bisect \$\endgroup\$ Jan 31, 2020 at 22:06
  • 1
    \$\begingroup\$ Python 3 port saves 4 bytes by replacing ord('069... with b'069... \$\endgroup\$
    – mypetlion
    Jan 31, 2020 at 23:45
  • \$\begingroup\$ @JonathanAllan Thanks! \$\endgroup\$
    – TFeld
    Feb 4, 2020 at 12:37
  • \$\begingroup\$ @mypetlion Thanks :) \$\endgroup\$
    – TFeld
    Feb 4, 2020 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.

\$\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.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Seems like it’s all good now! \$\endgroup\$
    – Grimmy
    Jan 31, 2020 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\$ Jan 31, 2020 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, 2020 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
\$\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).

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Here’s some improvements \$\endgroup\$
    – Grimmy
    Jan 31, 2020 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, 2020 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!

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

\$\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.

\$\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;
}
\$\endgroup\$
2
  • \$\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, 2020 at 16:19
  • \$\begingroup\$ No, lods can only read from (%esi) \$\endgroup\$ Feb 2, 2020 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}'
\$\endgroup\$
2
  • 3
    \$\begingroup\$ The data is supposed to be contained in the code, not passed as input. \$\endgroup\$
    – Arnauld
    Feb 1, 2020 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, 2020 at 14:22

Your Answer

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

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