Tesco's Burger Relish Best Before End date number

7

1

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

Adám

Posted 2019-07-05T15:47:16.693

Reputation: 37 779

"Cookies if you can do this using only numeric operations." Good luck handling dates without e.g. comparison operators... – Erik the Outgolfer – 2019-07-05T16:08:33.783

1@EriktheOutgolfer Addressed. – Adám – 2019-07-05T16:11:33.723

Closely related – Arnauld – 2019-07-05T16:22:09.830

2@Arnauld But that's a do-X-without-Y with an input domain that makes things harder. – Adám – 2019-07-05T16:33:35.093

Oh indeed. I missed that rule in the linked challenge. – Arnauld – 2019-07-05T16:38:14.980

Huh, I always wondered how that number translates to a date – Beta Decay – 2019-07-05T20:27:51.277

Must our output use 0-indexing for the days of the year or may we choose 1-indexing instead? – Shaggy – 2019-07-05T22:28:27.093

@Adám It's on many other products; not just this one! Why is the title so specific? – wizzwizz4 – 2019-07-06T15:16:35.763

1

@wizzwizz4 It was in the news recently: https://www.independent.co.uk/life-style/tesco-expiry-date-20140-julian-calendar-relish-twitter-a8973931.html : 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.

– seventyeightist – 2019-07-06T19:41:28.943

@seventyeightist Oh. I thought it was one of those elitist things, and felt so pleased with myself for figuring it out after only 5 weeks and setting my laptop's clock to show the date. – wizzwizz4 – 2019-07-06T20:56:58.623

@Shaggy It has to be that silly format. – Adám – 2019-07-06T23:33:33.463

Answers

6

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

AdmBorkBork

Posted 2019-07-05T15:47:16.693

Reputation: 41 581

-1 byte – mazzy – 2019-07-05T18:25:05.337

1@mazzy Don't need the parens in -join(...) since it's a single string slice, then. So that's another -2. Thanks! – AdmBorkBork – 2019-07-05T18:37:59.750

4

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!

Expired Data

Posted 2019-07-05T15:47:16.693

Reputation: 3 129

1(y,m,d)=>y%100*1000+new DateTime(y,m,d).DayOfYear-1 for 51 bytes? – Ed T – 2019-07-06T01:59:11.413

1@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 – Expired Data – 2019-07-06T02:04:43.020

3

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).

histocrat

Posted 2019-07-05T15:47:16.693

Reputation: 20 600

3

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

mazzy

Posted 2019-07-05T15:47:16.693

Reputation: 4 832

1Clever use of $args. – AdmBorkBork – 2019-07-05T18:39:15.730

1

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!

– AdmBorkBork – 2019-07-05T18:41:40.240

1Nice port! I knew there'd be a good way in PowerShell, but I didn't think it'd be that good – Expired Data – 2019-07-05T19:38:45.627

2

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

Erik the Outgolfer

Posted 2019-07-05T15:47:16.693

Reputation: 38 134

Seems to be a day off for January and February? – Neil – 2019-07-05T20:32:07.707

@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. – Erik the Outgolfer – 2019-07-05T20:33:30.853

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.) – Neil – 2019-07-05T20:43:50.657

@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. – Erik the Outgolfer – 2019-07-05T20:52:14.413

2

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.

Dat

Posted 2019-07-05T15:47:16.693

Reputation: 879

-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) – ar4093 – 2019-08-09T11:41:14.373

2

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

Jonathan Allan

Posted 2019-07-05T15:47:16.693

Reputation: 67 804

1

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

Neil

Posted 2019-07-05T15:47:16.693

Reputation: 95 035

1

[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

Zahiro Mor

Posted 2019-07-05T15:47:16.693

Reputation: 371

1

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

DaveMongoose

Posted 2019-07-05T15:47:16.693

Reputation: 231

0

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!

darrylyeo

Posted 2019-07-05T15:47:16.693

Reputation: 6 214

159 bytes? – Arnauld – 2019-07-05T19:24:35.320

1@Arnauld y%100*1e3 works because they have the same precedence. – Neil – 2019-07-05T20:01:47.330

Heh, I was overcomplicating it by using string concatenation when simple arithmetic is all that was needed. Thanks @Arnauld and @Neil! – darrylyeo – 2019-07-05T20:36:38.503

@darrylyeo something in the back of my head said -2000 was 1 byte too many but %100 was far too obvious! – Expired Data – 2019-07-05T21:19:25.140

0

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

Shaggy

Posted 2019-07-05T15:47:16.693

Reputation: 24 623

0

Red, 54 bytes

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

Try it online!

Galen Ivanov

Posted 2019-07-05T15:47:16.693

Reputation: 13 815

0

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

Chaos Manor

Posted 2019-07-05T15:47:16.693

Reputation: 521

0

Perl 6, 45 bytes

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

Try it online!

user0721090601

Posted 2019-07-05T15:47:16.693

Reputation: 928

42 bytes – Jo King – 2019-07-06T22:18:37.273

@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 – user0721090601 – 2019-07-06T22:45:07.217

0

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.

Kevin Cruijssen

Posted 2019-07-05T15:47:16.693

Reputation: 67 575

0

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.

O.O.Balance

Posted 2019-07-05T15:47:16.693

Reputation: 1 499