109 lines
1.7 KiB
Go
109 lines
1.7 KiB
Go
package q04
|
|
|
|
import (
|
|
_ "embed"
|
|
"fmt"
|
|
"math/rand"
|
|
"strconv"
|
|
"strings"
|
|
"text/template"
|
|
|
|
"github.com/hhhapz/codequest/models"
|
|
"github.com/hhhapz/codequest/question"
|
|
)
|
|
|
|
type boolgen struct {
|
|
src *rand.Rand
|
|
cache int64
|
|
remaining int
|
|
}
|
|
|
|
func (b *boolgen) Bool() bool {
|
|
if b.remaining == 0 {
|
|
b.cache, b.remaining = b.src.Int63(), 63
|
|
}
|
|
|
|
result := b.cache&0x01 == 1
|
|
b.cache >>= 1
|
|
b.remaining--
|
|
|
|
return result
|
|
}
|
|
|
|
func init() {
|
|
t := template.New("island")
|
|
var err error
|
|
t, err = t.Parse(q03Text)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
question.Register(
|
|
&question.Question{
|
|
ID: "island",
|
|
Name: "Island Analysis",
|
|
Text: t,
|
|
Level: question.Level2,
|
|
Generate: func(u *models.User) string {
|
|
inp := generate(u)
|
|
res := make([]string, 0, rows)
|
|
|
|
for _, row := range inp {
|
|
res = append(res, string(row))
|
|
}
|
|
return strings.Join(res, "\n")
|
|
},
|
|
Validate: func(u *models.User, part question.Part, solution string) bool {
|
|
return Validate(u, part, solution)
|
|
},
|
|
})
|
|
}
|
|
|
|
const (
|
|
rows = 90
|
|
cols = 50
|
|
)
|
|
|
|
func generate(u *models.User) [][]rune {
|
|
res := make([][]rune, rows)
|
|
|
|
b := boolgen{
|
|
src: question.UserRandom(u),
|
|
}
|
|
|
|
for i := 0; i < rows; i++ {
|
|
res[i] = make([]rune, cols)
|
|
for j := 0; j < cols; j++ {
|
|
m := 'X'
|
|
if b.Bool() {
|
|
m = ' '
|
|
}
|
|
res[i][j] = m
|
|
}
|
|
}
|
|
|
|
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", u.Name, p, sol)
|
|
fmt.Println("actual", u.Name, p, n)
|
|
|
|
return strconv.Itoa(n) == sol
|
|
}
|
|
|
|
//go:embed q04.md
|
|
var q03Text string
|