7
\$\begingroup\$

Tesco Burger Relish BBE: 20140

Given a date between 2010-01-01 and 2099-12-31 as three integers (please state your order if not [year,month,day]), answer with Tesco's corresponding five-digit Burger Relish Best Before End date number.

The format is simply the last two digits of the year, followed immediately by three digits representing the day of that year, between 000 and 365.

Cookies if you can do this using only numeric operations and comparisons. You may put such code separately from your golfed code, if it isn't also the shortest code you have.

Test cases

[year,month,day]BRBBED:

[2010,1,1]10000

[2019,7,5]19185

[2020,5,20]20140

[2096,12,31]96365

[2099,12,31]99364

\$\endgroup\$
  • \$\begingroup\$ "Cookies if you can do this using only numeric operations." Good luck handling dates without e.g. comparison operators... \$\endgroup\$ – Erik the Outgolfer Jul 5 at 16:08
  • 1
    \$\begingroup\$ @EriktheOutgolfer Addressed. \$\endgroup\$ – Adám Jul 5 at 16:11
  • \$\begingroup\$ Closely related \$\endgroup\$ – Arnauld Jul 5 at 16:22
  • 2
    \$\begingroup\$ @Arnauld But that's a do-X-without-Y with an input domain that makes things harder. \$\endgroup\$ – Adám Jul 5 at 16:33
  • 1
    \$\begingroup\$ @wizzwizz4 It was in the news recently: independent.co.uk/life-style/… : The supermarket’s unusual labelling choice came to light on Sunday after customer Matthew Stock shared a photograph on Twitter featuring a burger relish that had an expiration date of “20140” and asked Tesco to “please explain” it. \$\endgroup\$ – seventyeightist Jul 6 at 19:41

17 Answers 17

6
\$\begingroup\$

PowerShell, 74 70 67 bytes

param($y,$m,$d)-join"$y 00$((date "$m/$d/$y"|% d*r)-1)"[2,3+-3..-1]

Try it online!

Exactly what it says on the tin (but formatted weirdly). Takes in $year, $month, $day, plucks out the last two digits of the $year, gets a .NET datetime object of the specified day, then gets the dayofyear (with |% d*r) thereof. Subtracts one to make it zero-indexed, then uses string formatting and slicing to make it three-padded (e.g., 000 instead of 0), and then -joins it all together into a single string with implicit output.

Note this is culture dependent due to the datetime formatting. This works in en-us, which is what TIO also uses.

-3 bytes thanks to mazzy

\$\endgroup\$
  • \$\begingroup\$ -1 byte \$\endgroup\$ – mazzy Jul 5 at 18:25
  • 1
    \$\begingroup\$ @mazzy Don't need the parens in -join(...) since it's a single string slice, then. So that's another -2. Thanks! \$\endgroup\$ – AdmBorkBork Jul 5 at 18:37
4
\$\begingroup\$

C# (Visual C# Interactive Compiler), 88 78 73 71 59 57 bytes

a=>a[0]%100*1000+new DateTime(a[0],a[1],a[2]).DayOfYear-1

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ (y,m,d)=>y%100*1000+new DateTime(y,m,d).DayOfYear-1 for 51 bytes? \$\endgroup\$ – Ed T Jul 6 at 1:59
  • 1
    \$\begingroup\$ @EdT well it depends on your interpretation of the rules, I was aware of it but didn't do it, can be 51 curried also \$\endgroup\$ – Expired Data Jul 6 at 2:04
3
\$\begingroup\$

Ruby, 40 bytes

->d{Time.gm(*d).strftime('%y%j').to_i-1}

Try it online!

So close to being a built-in format, but %j is 1-indexed.

In a happier coincidence, though, Tesco Time (.gm) is one character shorter than local time (.new).

\$\endgroup\$
3
\$\begingroup\$

PowerShell, 48 45 39 bytes

Port of Expired Data's answer for C#

$args[0]*1E3+("$args"|date|% d*r)-2E6-1

Try it online!


PowerShell, 60 58 52 bytes

-2 bytes thanks @AdmBorkBork

-join"$args 00$(("$args"|date|% d*r)-1)"[2,3+-3..-1]

Try it online!

Explanation:

  • The script takes three integers [year,month,day]
  • "$args" makes a string like YYYY MM DD
  • "YYYY MM DD"|date converts string to [DateTime]. I don't know why it works. Can you explain?
  • ("YYYY MM DD"|date|% d*r)-1 calculates dayOfYear
  • the script makes a result string like YYYY MM DD 00### where ### is dayOfYear
  • finally the script extracts chars from positions [2,3+-3..-1] of the result string and joins this chars to result
\$\endgroup\$
  • 1
    \$\begingroup\$ Clever use of $args. \$\endgroup\$ – AdmBorkBork Jul 5 at 18:39
  • 1
    \$\begingroup\$ Just like with my answer, you only have a single string slice, so you don't need parens in -join(...) for -2 bytes. Try it online! \$\endgroup\$ – AdmBorkBork Jul 5 at 18:41
  • 1
    \$\begingroup\$ Nice port! I knew there'd be a good way in PowerShell, but I didn't think it'd be that good \$\endgroup\$ – Expired Data Jul 5 at 19:38
2
\$\begingroup\$

Python 2, 63 61 57 bytes

lambda y,m,d:y%100*1000+(153*m-2)/5+[m+1,1>y%4][2<m]+d-33

Try it online!

Returns the result as an integer.

Neil found that his Charcoal approach turned out to be lucky after some rearrangement.

Pure arithmetic and comparison solution (61 bytes):

lambda y,m,d:y%100*1000+30*m+m/2+(8<m<12)+~(0<y%4)*(2<m)+d-31
\$\endgroup\$
  • \$\begingroup\$ Seems to be a day off for January and February? \$\endgroup\$ – Neil Jul 5 at 20:32
  • \$\begingroup\$ @Neil Oh LOL I just noticed I was subtracting the extra day February doesn't have even when that month hasn't passed yet. EDIT: should be fixed. \$\endgroup\$ – Erik the Outgolfer Jul 5 at 20:33
  • \$\begingroup\$ I ported my Charcoal solution, and then golfed it down to 57 bytes: y%100*1000+(153*m-2)/5+[m+1,1>y%4][2<m]+d-33. (Sadly this rearrangement has the same byte count in Charcoal.) \$\endgroup\$ – Neil Jul 5 at 20:43
  • \$\begingroup\$ @Neil LOL Charcoal thinking beats Python thinking 10/10 I guess. :D I'll add it and see what I can further do, if I can. \$\endgroup\$ – Erik the Outgolfer Jul 5 at 20:52
2
\$\begingroup\$

Python 3, 87 85 74 bytes

lambda y,m,d:sum([y*1000-2000029+28*m,3,y%4==0,3,2,3,2,3,3,2,3,2,3][:m])+d

Try it online!

This is using only numeric operations and comparisons.

\$\endgroup\$
  • \$\begingroup\$ -5: y%4==0 -> 1>y%4 and splitting up the long array into ([y*1000-2000029+28*m,3,1>y%4]+[3,2,3,2,3]*2) \$\endgroup\$ – ar4093 Aug 9 at 11:41
1
\$\begingroup\$

Charcoal, 33 bytes

IΣ⟦×φ﹪θ¹⁰⁰⊖ζ÷⊕×¹⁵³⊖η⁵⎇›η²⊖⊖¬﹪θ⁴⊖η

Try it online! Link is to verbose version of code. Try it online! Link includes test suite. I don't think Charcoal has any date functions, so here's a mathematical solution. Explanation:

   ×φ﹪θ¹⁰⁰                          Year * 1000
          ⊖ζ                        Day - 1
            ÷⊕×¹⁵³⊖η⁵               Days in previous months
                     ⎇›η²            For months after Februrary
                         ⊖⊖¬﹪θ⁴     Adjust for leap years else
                               ⊖η   Adjust for short Februrary
 Σ⟦                                 Take the sum
I                                   Cast to string for implicit print
\$\endgroup\$
1
\$\begingroup\$

Jelly, 30 bytes

4ḍȯ2⁽¢wB+30¤_2¦ŻḣS+⁵’+³×ȷ¤_2ȷ6

A full program taking arguments y m d.
Jelly has no built-in date functionality.

Try it online!

How?

4ḍȯ2⁽¢wB+30¤_2¦ŻḣS+⁵’+³×ȷ¤_2ȷ6 - Main Link
           ¤                   - nilad followed by link(s) as a nilad:
    ⁽¢w                        -   1370
       B                       -   to binary = [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0]
        +30                    -   add 30   = [31,30,31,30,31,30,31,31,30,31,30]
              ¦                - sparse application...
             2                 -   to indices: [2]
            _                  -   action: subtract...
4ḍ                             -     four divides y? -> 1 or 0
  ȯ2                           -     OR 2               1 or 2
               Ż               - prepend 0 = [0,31,29|28,31,30,31,30,31,31,30,31,30]
                ḣ              - head to index m
                 S             - sum
                  +⁵           - add d
                    ’          - subtract one
                         ¤     - nilad followed by link(s) as a nilad:
                      ³        -   y
                        ȷ      -   1000
                       ×       -   multiply
                     +         - add
                           2ȷ6 - 2000000
                          _    - subtract
\$\endgroup\$
1
\$\begingroup\$

[R], 66 bytes

 function(a,b,c)as.numeric(strftime(paste(a,b,c,sep='-'),'%y%j'))-1

taking 3 integers and pasting them into a string strftime can recognize and extract the wanted parts. 0 indexing costs 14 bytes and another conversion to numeric

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

Ruby, 79 81 79 78 bytes

->y,m,d{(y%100*k=1000)+[d-1,l=31,y%4<1?29:28,l,s=30,l,s,l,l,s,l,s][0,m].sum%k}

Cookies version. Saved a few bytes by including the -1 and day in the array that gets summed, since those spaces were spare anyway.

EDIT: I realised that using "...%03d"%... wasn't really in the spirit of 'numerical and comparison operators only' so I've updated this answer (and gone up by 2 bytes).

EDIT-2: ... and recovered them by using the alternative sub-array index format [start,length], which in turn allowed me to combine the first two entries in the array.

EDIT-3: y%4==0 can be shortened to y%4<1

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

JavaScript, 70 57 bytes

(y,m,d,U=Date.UTC)=>y%100*1e3+(U(y,m-1,d)-U(y,0,1))/864e5

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ 59 bytes? \$\endgroup\$ – Arnauld Jul 5 at 19:24
  • 1
    \$\begingroup\$ @Arnauld y%100*1e3 works because they have the same precedence. \$\endgroup\$ – Neil Jul 5 at 20:01
  • \$\begingroup\$ Heh, I was overcomplicating it by using string concatenation when simple arithmetic is all that was needed. Thanks @Arnauld and @Neil! \$\endgroup\$ – darrylyeo Jul 5 at 20:36
  • \$\begingroup\$ @darrylyeo something in the back of my head said -2000 was 1 byte too many but %100 was far too obvious! \$\endgroup\$ – Expired Data Jul 5 at 21:19
0
\$\begingroup\$

Perl 6, 45 bytes

{@_.[0]%100*1000-1+Date.new(|@_).day-of-year}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ 42 bytes \$\endgroup\$ – Jo King Jul 6 at 22:18
  • \$\begingroup\$ @joking I have no idea why .[0] was bombing in TIO when I did it. Good catch on 1e3, I'll update when I get to a computer \$\endgroup\$ – guifa Jul 6 at 22:45
0
\$\begingroup\$

Red, 54 bytes

func[y m d][y % 100 * 1000 - 1 + pick to now[d m y]11]

Try it online!

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

8th, 77 71 bytes

Code

needs date/utils : f third -rot d:ymd> doy n:1- swap 100 mod 1000 * + ;

Return the result on TOS

Usage

ok> 2010 1 1 f .
10000
ok> 2019 7 5 f .
19185
ok> 2020 5 20 f .
20140
ok> 2096 12 31 f .
96365
ok> 2099 12 31 f .
99364
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 29 26 23 bytes

¦¦₄*•ΘÏF•ºS₂+I<£O¹4ÖI<O

Try it online or verify all test cases.

Takes three loose inputs in the order \$year\$, \$month\$, \$day\$.

Explanation:

¦¦             # Remove the first two digits of the (implicit) input-year
               #  i.e. year=2024 → 24
  ₄*           # Multiply it by 1000
               #  → 24000
•ΘÏF•          # Push compressed integer 5254545
     º         # Mirror it vertically to 52545455454525
      S        # Convert it to a list of digits: [5,2,5,4,5,4,5,5,4,5,4,5,2,5]
       ₂+      # Add 26 to each: [31,28,31,30,31,30,31,31,30,31,30,31,28,31]
         I<    # Push the second input-month decremented by 1
           £   # Leave the first month-1 amount of values from the list
            O  # Sum this list
               #  i.e. month=4 → [31,28,31] → 90
¹              # Push the first input-year again
 4Ö            # Check if it's divisible by 4
               #  2024 → 1 (truthy)
I<             # Push the third input-days, decremented by 1
               #  i.e. days=3 → 2
O              # Sum everything on the stack together
               #  24000,90,1,2 → 24093
               # (which is output implicitly as result)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why •ΘÏF• is 5254545.

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

Elm 0.19, 112 bytes

t y m d=1000*(y-2000)+List.sum(List.take m[d-1,31,if modBy 4 y<1 then 29 else 28,31,30,31,30,31,31,30,31,30,31])

Verify all test cases here.

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

Japt, 23 bytes

Takes input as 3 individual strings, assuming that's allowed.

¤+@ÐUTX ŶÐN Å}as ùT3 É

Try it

Very unhappy with this (there must be a better way to get the day of the year!) but it's been a long day. A port of darrylyeo's JS solution would be 2 bytes shorter but, for some reason, despite Japt being JavaScript, floating point inaccuracies abound.

¤+@ÐUTX ŶÐN Å}as ùT3 É     :Implicit input of strings U=y, V=d & W=d (N=[U,V,W])
¤                           :Slice the first 2 characters off U
 +                          :Append
  @                         :  Function taking an integer X as its argument
   ÐUTX                     :    Construct a Date object with U as the year, 0 as the month & X as the day
        Å                   :    Convert to date string ("yyyy-mm-dd")
         ¶                  :    Test for equality with
          ÐN Å              :    Construct a Date object from N and convert to a date string
              }             :  End function
               a            :  Return the first integer that returns true when passed through that function
                s           :  Convert to string
                  ùT3       :  Left pad with 0 to length 3
                      É     :Subtract 1
\$\endgroup\$

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.