package question import ( _ "embed" "fmt" "math" "math/rand" "strconv" "strings" "github.com/hhhapz/codequest/models" ) func move(x, y int, dir byte, step int) (int, int) { switch dir { case 'N': return x, y + step case 'S': return x, y - step case 'E': return x + step, y case 'W': return x - step, y } return x, y } func q1P1(steps []string) (x int, y int) { for _, step := range steps { dir := step[0] amt, _ := strconv.Atoi(step[1:]) x, y = move(x, y, dir, amt) } return } func q1P2(steps []string) (x int, y int) { known := make(map[int]map[int]bool) for _, step := range steps { dir := step[0] amt, _ := strconv.Atoi(step[1:]) x, y = move(x, y, dir, amt) if known[x] == nil { known[x] = make(map[int]bool) } if known[x][y] { return } known[x][y] = true } return } func q1Total(a, b int) int { if a < 0 { a = -a } if b < 0 { b = -b } return a + b } func init() { const directions = "NSWE" var q *Question q = &Question{ ID: "directions", Text: q01Text, Level: Level1, Generate: func(u *models.User) string { res := make([]string, 0, 100) r := userRandom(u) known := make(map[int]map[int]bool) var x, y int for i := 0; i < 100; i++ { dir := directions[r.Intn(4)] steps := r.Intn(30) + 1 newX, newY := move(x, y, dir, steps) if known[newX] == nil { known[newX] = make(map[int]bool) } if known[newX][newY] { i-- continue } known[newX][newY] = true x, y = newX, newY res = append(res, fmt.Sprintf("%c%d", dir, steps)) } n := rand.Intn(20) + 10 locX, locY := q1P1(res[:n]) dup := rand.Intn(20) + 35 lastX, lastY := q1P1(res[:dup]) fmt.Println(locX, locY) fmt.Println(lastX, lastY) fmt.Println(dup) dX := math.Max(float64(locX), float64(lastX)) - math.Min(float64(locX), float64(lastX)) if locX > lastX { res[dup] = fmt.Sprintf("E%d", int(dX)) dup++ } else if locX < lastX { res[dup] = fmt.Sprintf("W%d", int(dX)) dup++ } fmt.Println(res[dup-1]) fmt.Println("!!") if locY > lastY { res[dup] = fmt.Sprintf("N%d", int(math.Max(float64(locY), float64(lastY))-math.Min(float64(locY), float64(lastY)))) } else if locY < lastY { res[dup] = fmt.Sprintf("S%d", int(math.Max(float64(locY), float64(lastY))-math.Min(float64(locY), float64(lastY)))) } return strings.Join(res, "\n") }, Validate: func(u *models.User, level Part, input string) bool { inp := q.Generate(u) lastX, lastY := q1P1(strings.Split(inp, "\n")) if level == Part1 { total := q1Total(lastX, lastY) return strconv.Itoa(total) == input } lastX, lastY = q1P2(strings.Split(inp, "\n")) if level == Part2 { total := q1Total(lastX, lastY) return strconv.Itoa(total) == input } return false }, } Register(q) } //go:embed prompts/q01.md var q01Text string