88 lines
1.5 KiB
Go
88 lines
1.5 KiB
Go
|
package q02
|
||
|
|
||
|
import (
|
||
|
_ "embed"
|
||
|
"math"
|
||
|
"math/big"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/hhhapz/codequest/models"
|
||
|
"github.com/hhhapz/codequest/question"
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
question.Register(
|
||
|
&question.Question{
|
||
|
ID: "saturnalia",
|
||
|
Name: "Saturnalia's Problem",
|
||
|
Text: q02Text,
|
||
|
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
|