Как я могу сделать эти функции рекурсивными?

#scheme #racket

#схема #ракетка

Вопрос:

Мне нужно вернуть значение всех координат, функции get-initial-state и get-final-state возвращают cons (1.1) и ((-строки 2).(- столбцы 2)) соответственно.

 (define (generate-coordinates rows columns)
  (define all-coordinates (for*/list ([i rows][j columns]) (cons i j)))
  (let ([initial-state (get-initial-state)]
        [end-state (get-end-state rows columns)])
  (remove initial-state (remove end-state all-coordinates))))
 

Результат должен быть примерно таким:
‘((0 . 0) (0 . 1) (0 . 2) (0 . 3) (0 . 4) (1 . 0) (1 . 2) (1 . 3) (1 . 4)
Как вы можете видеть, пара (1 . 1) удаляется так же, как и пара со значениями (строки-2 . столбцы-2).
Формат должен быть списком пар.
Есть идеи?

Ответ №1:

 #lang racket

(require rackunit)
 

Позвольте мне сначала начать с вывода all-coordinates как функции и записи get-initial-state get-end-state функций and:

 (define (generate-coordinates rows columns)
  (let ([initial-state (get-initial-state)]
        [end-state (get-end-state rows columns)])
    (remove initial-state (remove end-state (all-coordinates rows columns)))))

(define (all-coordinates rows columns)
  (for*/list ([i rows] [j columns])
    (cons i j)))


(define (get-initial-state)
  (cons 1 1))


(define (get-end-state rows columns)
  (cons (- rows 2) (- columns 2)))
 

Понимая, что for*/list это похоже на повторение натуральных чисел — строк и столбцов, мы можем рекурсивно переписать все координаты. Повторяющиеся в строке-1 или столбцах-1, пока они не достигнут 0, и объединяются в один список:

 (define (all-coordinates.v2 rows cols)
  (cond [(= rows 0) empty]
        [else (append (all-coordinates.v2 (sub1 rows) cols)
                      (row-coordinates (sub1 rows) cols))]))

(define (row-coordinates thisrow cols)
  (cond [(= cols 0) empty]
        [else (append  (row-coordinates thisrow (sub1 cols))
                       (list (cons thisrow (sub1 cols))))]))
 

Наконец, тесты:

 (check-equal? (all-coordinates 3 3) (all-coordinates.v2 3 3))
(check-equal? (all-coordinates 0 0) (all-coordinates.v2 0 0))
(check-equal? (all-coordinates 1 0) (all-coordinates.v2 0 1))
(check-equal? (all-coordinates 2 3) (all-coordinates.v2 2 3))
(check-equal? (all-coordinates 3 2) (all-coordinates.v2 3 2))
(check-equal? (all-coordinates 2 2) (all-coordinates.v2 2 2))