Did I win the lotto?

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. 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
• Can you repeat the lottery rules here? I think questions should be self-contained. And also I can't access gambling sites from work. – ugoren Apr 1 '12 at 11:29
• Sure... adding above in a minute! – Gaffi Apr 1 '12 at 14:47
• Isn't the Jackpot split between all winning tickets? – ceased to turn counterclockwis Apr 1 '12 at 16:09
• @leftaroundabout Fixed. – Gaffi Apr 1 '12 at 17:34
• No... I win.... – Steve Robbins Apr 5 '12 at 22:48

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[1:-1]))+(x==a)]
s=0
for e in sorted(a[1:],cmp,w,1):
t=w(e);s+=t
if t:print e,"- $%u"%t print"Total Winnings:$%u"%s

Assuming the input numbers are comma separated.

• Thanks for the math idea: 1e4, etc. (I should have known it from the start!) – Gaffi Apr 2 '12 at 20:14
• Do newlines count in python? what about indentation? – Joel Cornett Apr 8 '12 at 14:37
• 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 Apr 10 '12 at 11:49

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
Next
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
• I was able to significantly reduce the size by converting the Select Case into Choose() – Gaffi Apr 10 '12 at 18:24
• Great trick! it's been so many years since I heard of Choose()... This is a nice thing to post on codegolf.stackexchange.com/questions/5175/… – Cristian Lupascu May 29 '12 at 19:39
• @w0lf Not a bad idea! – Gaffi May 29 '12 at 19:40
• 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 May 31 '17 at 14:55 • 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 May 31 '17 at 14:56 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.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==m?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.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 == m ? 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

• I see that as 499 characters (with the args at the end of your single line version)... Am I missing something? – Gaffi Apr 11 '12 at 20:20
• @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 Apr 11 '12 at 21:19