8
\$\begingroup\$

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

3 Answers 3

3
\$\begingroup\$

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.

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

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
\$\endgroup\$
5
  • \$\begingroup\$ I was able to significantly reduce the size by converting the Select Case into Choose() \$\endgroup\$
    – Gaffi
    Commented Apr 10, 2012 at 18:24
  • \$\begingroup\$ 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/… \$\endgroup\$ Commented May 29, 2012 at 19:39
  • \$\begingroup\$ @w0lf Not a bad idea! \$\endgroup\$
    – Gaffi
    Commented May 29, 2012 at 19:40
  • \$\begingroup\$ 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 \$\endgroup\$ Commented May 31, 2017 at 14:55
  • \$\begingroup\$ Oh and whenever you have a For i=1 To 5 or like loop that can be condensed to For I=1To 5 \$\endgroup\$ Commented May 31, 2017 at 14:56
2
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ I see that as 499 characters (with the args at the end of your single line version)... Am I missing something? \$\endgroup\$
    – Gaffi
    Commented Apr 11, 2012 at 20:20
  • \$\begingroup\$ @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! \$\endgroup\$
    – Ed James
    Commented Apr 11, 2012 at 21:19

Your Answer

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

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