Did I win the lotto?

8

I just submitted an answer to this question, and then looked about at some news stories about the MegaMillions lottery craze going on right now in the US. This news article stated that an individual purchased $20,000 worth of tickets at one time (that's 20,000 sets of numbers to confirm!) to try and test their luck.

That led me to thinking about how one might quickly determine whether or not they'd won any prize, not just a jackpot, on a large lot of tickets that they had purchased.

The challenge then is this:

Overview:

Write a function or program that will accept a string of numbers as an argument (STDIN, or read in from a file, your choice), and return the numbers of the tickets with at least the minimum payout awarded.

Code Details:

  • The input will consist of a series of lines, one for each ticket purchased. The winning numbers will be prefixed with a 0, while the drawn numbers will be prefixed with an incremented number starting at 1. (see example)
  • The input should be a completely random set of numbers each time, including draws and winning numbers.
  • The input should accept any number of tickets n where 1 <= n <= 20,000. (Assume no 0 ticket runs.)
  • Each line of input will have 7 numbers per line. One for the prefix noted above, 5 for the standard balls, and one additional for the 'match' ball. (see Lotto Details below)
  • The input can be delimited any way you wish (whitespace, semicolon, etc.)
  • The output should be a listing of all winning draws and the winning amount. (So you know which to turn in.)
  • The output listing should be ordered by win amount. (Who cares if you won $2 on one ticket if you also won $10,000 on another???)
  • When more than one ticket wins the same amount, the order of those tickets is irrelevant.
  • The output should also give a listing of the total amount won.

Lotto Details:

  • Standard rules for the MegaMillions game will apply, since that's what's so hot right now.
  • Draws consist of six numbers from two separate pools of numbers - five different numbers from 1 to 56 and one number (the match ball) from 1 to 46.
  • The jackpot is won by matching all six winning numbers in a drawing.
  • Awards for non-jackpot wins are awarded as follows (see image below).

    (Main) + (Match) = (Payout)
    5 + 1 = Jackpot
    5 + 0 = $250,000
    4 + 1 = $10,000
    4 + 0 = $150
    3 + 1 = $150
    3 + 0 = $7
    2 + 1 = $10
    1 + 1 = $3
    0 + 1 = $2

  • Assume current jackpot is $1,000,000 (one million).

  • Assume only one jackpot winner, unless your random draw pulls the same jackpot pick more than once (are you cheating?).
  • Assume no multiplier/California rules are in-play.

Awarded amounts

Challenge Details:

  • This is code golf, so shortest code wins.
  • In the event of a tie, I'll take the highest upvoted answer. I know this is somewhat subjective, but the main point is still the score.

Example:

Input:

0   2   4   23  38  46  23  
1   17  18  22  23  30  40  
2   2   5   24  37  45  23  
3   4   23  38  40  50  9  
4   2   4   23  38  46  17  
5   5   16  32  33  56  46  

Output:

4 - $250,000  
3 - $7  
2 - $3  
Total Winnings: $250,010 

Gaffi

Posted 2012-03-31T06:30:10.227

Reputation: 3 411

5Can you repeat the lottery rules here? I think questions should be self-contained. And also I can't access gambling sites from work. – ugoren – 2012-04-01T11:29:04.187

1Sure... adding above in a minute! – Gaffi – 2012-04-01T14:47:43.743

Isn't the Jackpot split between all winning tickets? – ceased to turn counterclockwis – 2012-04-01T16:09:53.480

@leftaroundabout Fixed. – Gaffi – 2012-04-01T17:34:12.773

No... I win.... – Steve Robbins – 2012-04-05T22:48:28.050

I'm hoping someone else will submit an answer. Perhaps I should extend the deadline? – Gaffi – 2012-04-10T17:15:28.803

Getting to the end. Looks like hallvabo's going to win this one... – Gaffi – 2012-04-12T22:39:39.080

Answers

3

Python, 239 chars

import sys
a=map(eval,sys.stdin)
w=lambda x:(0,2,0,3,0,10,7,150,150,1e4,25e4,1e6)[2*len(set(x[1:-1])&set(a[0][1:-1]))+(x[6]==a[0][6])]
s=0
for e in sorted(a[1:],cmp,w,1):
    t=w(e);s+=t
    if t:print e[0],"- $%u"%t
print"Total Winnings: $%u"%s

Assuming the input numbers are comma separated.

hallvabo

Posted 2012-03-31T06:30:10.227

Reputation: 1 640

Thanks for the math idea: 1e4, etc. (I should have known it from the start!) – Gaffi – 2012-04-02T20:14:33.887

Do newlines count in python? what about indentation? – Joel Cornett – 2012-04-08T14:37:33.450

Yes, both counts. Newlines count as 1 char each. Indentation can be minimized by interleaving spaces and tabs: 1st level=<space>, 2nd level=<tab>, 3rd level=<tab><space> etc. – hallvabo – 2012-04-10T11:49:36.030

2

VBA (660 535 Chars)

Assuming delimiter is a space (" ")...

Sub a(b)
c=Split(b,vbCr)
Set l=New Collection
Set n=New Collection
d=Split(c(0)," ")
For e=1 To UBound(c)
f=Split(c(e)," ")
p=f(0)
i=1
For g=1 To 5:For h=1 To 5
i=i-(d(g)=f(h))
Next:Next
k=IIf(d(6)=f(6),Choose(i,2,3,10,150,10^4,10^6),Choose(i,0,0,0,7,150,500^2))
If k>0 Then
o=1
For m=1 To l.Count
If k>=l(m) Then l.Add k,p,m:n.Add p,p,m:o=0:m=99999
Next
If o Then l.Add k,p:n.Add p,p
End If
Next
For m=1 To l.Count
r=r & n(m) & ":" & Format(l(m),"$#,##0") & vbCr
q=q+l(m)
Next
MsgBox r & "Total Winnings:" & Format(q,"$#,##0")
End Sub

Gaffi

Posted 2012-03-31T06:30:10.227

Reputation: 3 411

I was able to significantly reduce the size by converting the Select Case into Choose() – Gaffi – 2012-04-10T18:24:09.743

Great trick! it's been so many years since I heard of Choose()... This is a nice thing to post on http://codegolf.stackexchange.com/questions/5175/tips-for-golfing-in-vba

– Cristian Lupascu – 2012-05-29T19:39:28.030

@w0lf Not a bad idea! – Gaffi – 2012-05-29T19:40:53.970

you can loose quite a few chars by replacing the second to last line with Debug.?r& "Total Winnings:" &Format(q,"$#,##0") and removing whitespace in concatenations – Taylor Scott – 2017-05-31T14:55:59.017

Oh and whenever you have a For i=1 To 5 or like loop that can be condensed to For I=1To 5 – Taylor Scott – 2017-05-31T14:56:44.343

2

Javascript, 353 Bytes

(function(t){u={"51":1e6,"50":25e4,"41":1e4,"40":150,"31":150,"30":7,"21":10,"11":3,"01":2},a=t.split('\n'),l=a.length-1,m=a[0].split(' '),w=m.slice(1,6),h=0;for(;l--;){s=a[l+1].split(' '),i=s.slice(1,6).filter(function(n){return!!~w.indexOf(n)}),n=i.length+''+(s[6]==m[6]?1:0),v=u[n];if(v){h+=v;console.log(l+'-$'+v)}}console.log('Total Winnings: $'+h)})("0 2 4 23 38 46 23\n" + "1 17 18 22 23 30 40\n" + "2 2 5 24 37 45 23\n" + "3 4 23 38 40 50 9\n" + "4 2 4 23 38 46 17\n" + "5 5 16 32 33 56 46")

ungolfed:

(function (t) {
    u = {
        "51": 1e6,
        "50": 25,
        "41": 1e4,
        "40": 150,
        "31": 150,
        "30": 7,
        "21": 10,
        "11": 3,
        "01": 2
    },
    a = t.split('\n'),
    l = a.length - 1,
    m = a[0].split(' '),
    w = m.slice(1, 6),
    h = 0;
    for (; l--; ) {
        s = a[l + 1].split(' '),
        i = s.slice(1, 6).filter(function (n) { return !! ~w.indexOf(n) }),
        n = i.length + '' + (s[6] == m[6] ? 1 : 0),
        v = u[n];
        if (v) {
            h += v;
            console.log(l + ' - $' + v)
        }
    }
    console.log('Total Winnings: $' + h)
})("0 2 4 23 38 46 23\n" +
"1 17 18 22 23 30 40\n" +
"2 2 5 24 37 45 23\n" +
"3 4 23 38 40 50 9\n" +
"4 2 4 23 38 46 17\n" +
"5 5 16 32 33 56 46")

Could probably knock a few chars off that :D

Ed James

Posted 2012-03-31T06:30:10.227

Reputation: 171

I see that as 499 characters (with the args at the end of your single line version)... Am I missing something? – Gaffi – 2012-04-11T20:20:01.397

@Gaffi Yes, that's interesting... I wrapped it in a function and "toString().length"ed it, and got 517, but a straight char count comes in at 499... Thanks for pointing that out! – Ed James – 2012-04-11T21:19:18.687