package q03 import ( _ "embed" "fmt" "math/rand" "strconv" "strings" "text/template" "github.com/hhhapz/codequest/models" "github.com/hhhapz/codequest/question" ) type weightedChoice struct { weight int value int } func weightedRandom(choices []weightedChoice, r *rand.Rand) int { var total int for _, c := range choices { total += c.weight } rnd := r.Intn(total) for _, c := range choices { if rnd < c.weight { return c.value } rnd -= c.weight } panic("unreachable") } func init() { t := template.New("dragon") var err error t, err = t.Parse(q03Text) if err != nil { panic(err) } question.Register( &question.Question{ ID: "dragon", Name: "The Dragon Festival", Text: t, Level: question.Level1, Generate: func(u *models.User) string { inp := generate(u) res := make([]string, rows) for i, row := range inp { for _, n := range row { res[i] += strconv.Itoa(n) } } return strings.Join(res, "\n") }, Validate: func(u *models.User, part question.Part, solution string) bool { return Validate(u, part, solution) }, }) } const ( rows = 120 cols = 80 ) var numWeights = []weightedChoice{ {weight: 1, value: 0}, {weight: 4, value: 1}, {weight: 4, value: 2}, {weight: 4, value: 3}, {weight: 4, value: 4}, {weight: 4, value: 5}, {weight: 4, value: 6}, {weight: 2, value: 7}, {weight: 2, value: 8}, {weight: 1, value: 9}, } func generate(u *models.User) [][]int { res := make([][]int, rows) r := question.UserRandom(u) for i := 0; i < rows; i++ { res[i] = make([]int, cols) for j := 0; j < cols; j++ { res[i][j] = weightedRandom(numWeights, r) } } return res } func Validate(u *models.User, p question.Part, sol string) bool { inp := generate(u) var n int switch p { case question.Part1: n = solveP1(inp) case question.Part2: n = solveP2(inp) default: return false } fmt.Println("submitted", sol) fmt.Println("actual", n) return strconv.Itoa(n) == sol } //go:embed q03.md var q03Text string