hackathon/question/q02/q02.go

95 lines
1.6 KiB
Go

package q02
import (
_ "embed"
"math"
"math/big"
"strconv"
"strings"
"text/template"
"github.com/hhhapz/codequest/models"
"github.com/hhhapz/codequest/question"
)
func init() {
t := template.New("saturnalia")
var err error
t, err = t.Parse(q02Text)
if err != nil {
panic(err)
}
question.Register(
&question.Question{
ID: "saturnalia",
Name: "Saturnalia's Problem",
Text: t,
Level: question.Level1,
Generate: func(u *models.User) string {
inp := generate(u)
var res []string
for _, n := range inp {
res = append(res, strconv.Itoa(n))
}
return strings.Join(res, "\n")
},
Validate: func(u *models.User, part question.Part, solution string) bool {
return Validate(u, part, solution)
},
})
}
func bigLCM(a, b *big.Int) *big.Int {
return big.NewInt(0).Div(big.NewInt(0).Mul(a, b), big.NewInt(0).GCD(nil, nil, a, b))
}
const (
ships = 25
minNum = 3
maxNum = 100
)
var maxLCM = big.NewInt(math.MaxInt64 / 100)
func generate(u *models.User) []int {
res := make([]int, 0, ships)
r := question.UserRandom(u)
lcm := big.NewInt(1)
for len(res) != cap(res) {
n := r.Intn(maxNum-minNum) + minNum
nLcm := bigLCM(lcm, big.NewInt(int64(n)))
if nLcm.Cmp(maxLCM) > 0 {
continue
}
lcm = nLcm
res = append(res, n)
}
return res
}
func Validate(u *models.User, p question.Part, sol string) bool {
inp := generate(u)
var t int64
switch p {
case question.Part1:
t = solveP1(inp)
case question.Part2:
t = solveP2(inp)
default:
return false
}
return strconv.FormatInt(t, 10) == sol
}
//go:embed q02.md
var q02Text string