Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions cmd/lottery/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ import (
)

var (
flagPlaTinumCount int
flagGoldCount int
flagSilverCount int
flagGoldCount int
flagSilverCount int
flagLunchCount int
flagDrinkCount int
)

func init() {
flag.IntVar(&flagPlaTinumCount, "p", 2, "counts of platinum plan")
flag.IntVar(&flagGoldCount, "g", 2, "counts of gold plan")
flag.IntVar(&flagSilverCount, "s", 18, "counts of silver plan")
flag.IntVar(&flagGoldCount, "g", 6, "counts of gold plan")
flag.IntVar(&flagSilverCount, "s", 12, "counts of silver plan")
flag.IntVar(&flagLunchCount, "l", 2, "counts of lunch plan")
flag.IntVar(&flagDrinkCount, "d", 2, "counts of drink plan")
}

func main() {
Expand All @@ -35,9 +37,10 @@ func run() error {
}

l := &sponsors.Lottery{
PlaTinumCount: flagPlaTinumCount,
GoldCount: flagGoldCount,
SilverCount: flagSilverCount,
GoldCount: flagGoldCount,
SilverCount: flagSilverCount,
LunchCount: flagLunchCount,
DrinkCount: flagDrinkCount,
}

result := l.Do(applicants)
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module github.com/GoCon/sponsors

go 1.25rc1
go 1.26.2

require github.com/tenntenn/golden v0.5.5

require (
github.com/google/go-cmp v0.7.0 // indirect
github.com/josharian/mapfs v0.0.0-20210615234106-095c008854e6 // indirect
github.com/josharian/txtarfs v0.0.0-20240408113805-5dc76b8fe6bf // indirect
github.com/tenntenn/golden v0.5.5 // indirect
golang.org/x/tools v0.33.0 // indirect
)
37 changes: 19 additions & 18 deletions lottery.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sponsors

import (
"errors"
"fmt"
"io"
"math/rand/v2"
Expand All @@ -9,19 +10,22 @@ import (
)

type Lottery struct {
PlaTinumCount int
GoldCount int
SilverCount int
GoldCount int
SilverCount int
LunchCount int
DrinkCount int
}

func (l *Lottery) Limit(p Plan) int {
switch p {
case PlanPlaTinum:
return l.PlaTinumCount
case PlanGold:
return l.GoldCount
case PlanSilver:
return l.SilverCount
case PlanLunch:
return l.LunchCount
case PlanDrink:
return l.DrinkCount
}
return -1
}
Expand All @@ -31,8 +35,7 @@ func (l *Lottery) Do(applicants map[Plan][]*Applicant) LotteryResult {
doLotteries := make([]func() (Plan, []*Applicant), 0, len(plans))
for _, plan := range plans {
doLotteries = append(doLotteries, func() (Plan, []*Applicant) {
sponsors, nexts := l.doPlan(applicants[plan], l.Limit(plan))
applicants[plan.Next()] = append(applicants[plan.Next()], nexts...)
sponsors := l.doPlan(applicants[plan], l.Limit(plan))
return plan, sponsors
})
}
Expand All @@ -46,7 +49,7 @@ func (l *Lottery) Do(applicants map[Plan][]*Applicant) LotteryResult {
return result
}

func (l *Lottery) doPlan(as []*Applicant, n int) (sponsors, nexts []*Applicant) {
func (l *Lottery) doPlan(as []*Applicant, n int) (sponsors []*Applicant) {
rand.Shuffle(len(as), func(i, j int) {
as[i], as[j] = as[j], as[i]
})
Expand All @@ -59,16 +62,10 @@ func (l *Lottery) doPlan(as []*Applicant, n int) (sponsors, nexts []*Applicant)
sponsors = slices.Clone(as[:n])

if len(as)-n <= 0 {
return sponsors, nil
return sponsors
}

for _, a := range as[n:] {
if a.Next {
nexts = append(nexts, a)
}
}

return sponsors, nexts
return sponsors
}

type LotteryResult map[Plan][]*Applicant
Expand All @@ -78,7 +75,11 @@ func (r LotteryResult) Show(w io.Writer) {
if !plan.IsLottery() {
continue
}
fmt.Fprintf(w, "==== %s sponsor ====\n", plan.Title())
title, err := plan.Title()
if err, ok := errors.AsType[ErrUnknownPlan](err); ok {
title = err.Error()
}
fmt.Fprintf(w, "==== %s sponsor ====\n", title)
for _, applicant := range r[plan] {
r.printApplicant(w, applicant.Name, r.PlanDelay(plan))
}
Expand All @@ -89,7 +90,7 @@ func (r LotteryResult) Show(w io.Writer) {

func (r LotteryResult) PlanDelay(p Plan) time.Duration {
switch p {
case PlanPlaTinum:
case PlanLunch:
return 1 * time.Second
case PlanGold:
return 1 * time.Second
Expand Down
12 changes: 8 additions & 4 deletions lottery_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ func TestLotteryResult_Show(t *testing.T) {
result sponsors.LotteryResult
}{
"normal": {result: sponsors.LotteryResult{
sponsors.PlanPlaTinum: []*sponsors.Applicant{
{Name: "PlaTinum 01", Plan: sponsors.PlanPlaTinum, Next: true},
{Name: "PlaTinum 02", Plan: sponsors.PlanPlaTinum, Next: true},
},
sponsors.PlanGold: []*sponsors.Applicant{
{Name: "GoldTinum 01", Plan: sponsors.PlanGold, Next: true},
{Name: "GoldTinum 02", Plan: sponsors.PlanGold, Next: true},
Expand All @@ -41,6 +37,14 @@ func TestLotteryResult_Show(t *testing.T) {
{Name: "SilverTinum 02", Plan: sponsors.PlanSilver, Next: true},
{Name: "SilverTinum 03", Plan: sponsors.PlanSilver, Next: true},
},
sponsors.PlanLunch: []*sponsors.Applicant{
{Name: "LunchTinum 01", Plan: sponsors.PlanLunch, Next: true},
{Name: "LunchTinum 02", Plan: sponsors.PlanLunch, Next: true},
},
sponsors.PlanDrink: []*sponsors.Applicant{
{Name: "DrinkTinum 01", Plan: sponsors.PlanDrink, Next: true},
{Name: "DrinkTinum 02", Plan: sponsors.PlanDrink, Next: true},
},
}},
}

Expand Down
58 changes: 30 additions & 28 deletions plan.go
Original file line number Diff line number Diff line change
@@ -1,62 +1,64 @@
package sponsors

import "fmt"

type Plan string

func Plans() []Plan {
return []Plan{
PlanPlaTinum,
PlanGold,
PlanSilver,
PlanBronze,
PlanFree,
PlanLunch,
PlanDrink,
}
}

const (
PlanPlaTinum Plan = "platinum"
PlanGold Plan = "gold"
PlanSilver Plan = "silver"
PlanBronze Plan = "bronze"
PlanFree Plan = "free"
PlanGold Plan = "gold"
PlanSilver Plan = "silver"
PlanLunch Plan = "lunch"
PlanDrink Plan = "drink"
)

func (p Plan) IsLottery() bool {
switch p {
case PlanPlaTinum, PlanGold, PlanSilver:
case PlanGold, PlanSilver, PlanLunch, PlanDrink:
return true
default:
return false
}
}

func (p Plan) Title() string {
type ErrUnknownPlan struct{}

func (e ErrUnknownPlan) Error() string {
return "unknown plan"
}

func (p Plan) Title() (string, error) {
switch p {
case PlanPlaTinum:
return `Platinum "Go"ld`
case PlanGold:
return `"Go"ld`
return `"Go"ld`, nil
case PlanSilver:
return "Silver"
case PlanBronze:
return "Bronze"
case PlanFree:
return "Free"
return "Silver", nil
case PlanLunch:
return "Lunch", nil
case PlanDrink:
return "Drink", nil
default:
return "unknown plan", fmt.Errorf("unknown plan: %s", p)
}

return "unknown plan"
}

func (p Plan) Next() Plan {
func (p Plan) Next() (Plan, error) {
switch p {
case PlanPlaTinum:
return PlanGold
case PlanGold:
return PlanSilver
return PlanSilver, nil
case PlanSilver:
return PlanBronze
case PlanBronze:
return PlanBronze
return PlanLunch, nil
case PlanLunch:
return PlanDrink, nil
default:
return PlanFree
return "", fmt.Errorf("unknown plan: %s", p)
}
}
12 changes: 8 additions & 4 deletions testdata/TestLotteryResult_Show/normal.golden
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
==== Platinum "Go"ld sponsor ====
PlaTinum 01
PlaTinum 02

==== "Go"ld sponsor ====
GoldTinum 01
GoldTinum 02
Expand All @@ -12,3 +8,11 @@ SilverTinum 01
SilverTinum 02
SilverTinum 03

==== Lunch sponsor ====
LunchTinum 01
LunchTinum 02

==== Drink sponsor ====
DrinkTinum 01
DrinkTinum 02

36 changes: 18 additions & 18 deletions testdata/practice.csv
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
company,plan,next
株式会社Gopher1,free,FALSE
株式会社Gopher2,platinum,TRUE
株式会社Gopher2,lunch,TRUE
株式会社Gopher3,gold,TRUE
株式会社Gopher4,silver,TRUE
株式会社Gopher5,bronze,FALSE
株式会社Gopher5,drink,FALSE
株式会社Gopher6,gold,TRUE
株式会社Gopher7,gold,TRUE
株式会社Gopher8,gold,TRUE
株式会社Gopher9,bronze,TRUE
株式会社Gopher9,drink,TRUE
株式会社Gopher10,gold,TRUE
株式会社Gopher11,bronze,FALSE
株式会社Gopher11,drink,FALSE
株式会社Gopher12,gold,TRUE
株式会社Gopher13,gold,TRUE
株式会社Gopher14,platinum,TRUE
株式会社Gopher15,platinum,TRUE
株式会社Gopher14,lunch,TRUE
株式会社Gopher15,lunch,TRUE
株式会社Gopher16,silver,TRUE
株式会社Gopher17,bronze,FALSE
株式会社Gopher18,platinum,TRUE
株式会社Gopher19,bronze,FALSE
株式会社Gopher20,bronze,TRUE
株式会社Gopher21,platinum,TRUE
株式会社Gopher17,drink,FALSE
株式会社Gopher18,lunch,TRUE
株式会社Gopher19,drink,FALSE
株式会社Gopher20,drink,TRUE
株式会社Gopher21,lunch,TRUE
株式会社Gopher22,silver,TRUE
株式会社Gopher23,gold,TRUE
株式会社Gopher24,platinum,TRUE
株式会社Gopher24,lunch,TRUE
株式会社Gopher25,silver,TRUE
株式会社Gopher26,silver,FALSE
株式会社Gopher27,gold,TRUE
株式会社Gopher28,platinum,TRUE
株式会社Gopher28,lunch,TRUE
株式会社Gopher29,gold,TRUE
株式会社Gopher30,silver,TRUE
株式会社Gopher31,gold,TRUE
株式会社Gopher32,platinum,TRUE
株式会社Gopher32,lunch,TRUE
株式会社Gopher33,gold,TRUE
株式会社Gopher34,platinum,FALSE
株式会社Gopher34,lunch,FALSE
株式会社Gopher35,gold,TRUE
株式会社Gopher36,silver,TRUE
株式会社Gopher37,gold,TRUE
株式会社Gopher38,silver,TRUE
株式会社Gopher39,gold,TRUE
株式会社Gopher40,gold,TRUE
株式会社Gopher41,gold,TRUE
株式会社Gopher42,bronze,FALSE
株式会社Gopher42,drink,FALSE
株式会社Gopher43,gold,TRUE
株式会社Gopher44,gold,TRUE
株式会社Gopher45,gold,TRUE
Expand All @@ -50,5 +50,5 @@ company,plan,next
株式会社Gopher49,silver,TRUE
株式会社Gopher50,silver,TRUE
株式会社Gopher51,silver,TRUE
株式会社Gopher52,bronze,TRUE
株式会社Gopher53,platinum,TRUE
株式会社Gopher52,drink,TRUE
株式会社Gopher53,lunch,TRUE