20.03.21 © 2024 Программизд 02
 
Форумы / Общение / Ну чо, будем решать задачу про расстановку ферзей. или чо
Сообщения: 57 / Страницы: 1  2  3  все  
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3448
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
Дырокол  20.09.2020, 18:16
т.е. наше отображение будет выглядеть так:
Код
1.
2.
3.
4.
(map (lambda (new-row)
                  (adjoin-position
                   new-row k rest-of-queens))
               (enumerate-interval 1 board-size))
теперь можно приступить к генерации:
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
> (map (lambda (new-row)
                    (adjoin-position
                     new-row 2 '((1 1))))
                 (enumerate-interval 1 8))
'(((1 1) (1 2))
  ((1 1) (2 2))
  ((1 1) (3 2))
  ((1 1) (4 2))
  ((1 1) (5 2))
  ((1 1) (6 2))
  ((1 1) (7 2))
  ((1 1) (8 2)))
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
> (map (lambda (new-row)
                    (adjoin-position
                     new-row 2 '((2 1))))
                 (enumerate-interval 1 8))
'(((2 1) (1 2))
  ((2 1) (2 2))
  ((2 1) (3 2))
  ((2 1) (4 2))
  ((2 1) (5 2))
  ((2 1) (6 2))
  ((2 1) (7 2))
  ((2 1) (8 2)))
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
> (map (lambda (new-row)
                    (adjoin-position
                     new-row 2 '((3 1))))
                 (enumerate-interval 1 8))
'(((3 1) (1 2))
  ((3 1) (2 2))
  ((3 1) (3 2))
  ((3 1) (4 2))
  ((3 1) (5 2))
  ((3 1) (6 2))
  ((3 1) (7 2))
  ((3 1) (8 2)))
выше приведены отдельные map-ы, генерирующие нужные списки в зависимости от параметров - предыдущего сгенерённого списка, номера строки, номера столбца.

чтобы увязать результат рекурсивной генерации в единый список, нужно накапливать результат на каждом шаге рекурсии.

поэтому нам нужна некая процедура вида
Код
1.
2.
(define (flatmap proc seq)
  (accumulate append nil (map proc seq)))
т.е. у нас есть некая процедура proc - в нашем случае это процедура вида
Код
1.
2.
3.
(lambda (new-row)
                    (adjoin-position
                     new-row 2 '((3 1))))
есть последовательность seq - в нашем случае это
Код
1.
(enumerate-interval 1 8)
мы хотем аккумулировать результаты этих map-ов, начав с пустого nil.

то-есть нам нужна некоторая функция аккумулирования accumulate, которую мы запускаем с параметрами
Код
1.
(accumulate append nil (map proc seq))
Изменено: 25.09.2020, 07:51 - Дырокол
Рейтинг: 0 / 0
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3449
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
ничего не мешает нам реализовать подобное накопление в самом общем виде, когда на вход функции накопления мы подаём
1) операцию накопления
2) начальное значение
3) последовательность, элементы которой и нужно накопить, применив к ним операцию накопления:
Код
1.
2.
3.
4.
5.
(define (accumulate op initial sequence)
  (if (null? sequence)
    initial
    (op (car sequence)
       (accumulate op initial (cdr sequence)))))
Код
1.
2.
(accumulate + 0 (list 1 2 3 4 5))
15
Код
1.
2.
(accumulate * 1 (list 1 2 3 4 5))
120
Код
1.
2.
(accumulate cons nil (list 1 2 3 4 5))
(1 2 3 4 5)
 
Рейтинг: 0 / 0
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3450
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
Дырокол  18.09.2020, 15:10
разберёмся с предикатом

нам нужно отфильтровать, оставляя только те, где
ферзь на k-й вертикали не бьется ни одним из остальных.

т.е. предикат должен на вход брать множество позиций и возвращать результат работы
некоторой функции сравнения, которая для этого множества позиций определяет,
находится ли ферзь с k-й вертикали в безопасности от остальных.
назовём эту функцию сравнения safe?
Код
1.
2.
3.
4.
5.
6.
  (define (queen-cols k)
    (if (= k 0)
       (list empty-board)
       (filter
          (λ (positions) (safe? k positions))
          расширенный набор позиций)))
после всех этих приготовлений счастье наконец пришло в наш дом
и мы можем написать алгоритм целиком:
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  (define (queen-cols k)
    (if (= k 0)
       (list empty-board)
       (filter
        (λ (positions) (safe? k positions))
        (flatmap
         (λ (rest-of-queens)
           (map (lambda (new-row)
                  (adjoin-position
                   new-row k rest-of-queens))
               (enumerate-interval 1 board-size)))
         (queen-cols (- k 1))))))
 
Рейтинг: 0 / 0
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3451
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
исходная задача формулируется в терминах нахождения расстановки в зависимости от размера доски, поэтому обернём нашу функцию так:
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
(define (queens board-size)
  (define (queen-cols k)
    (if (= k 0)
       (list empty-board)
       (filter
        (λ (positions) (safe? k positions))
        (flatmap
         (λ (rest-of-queens)
           (map (lambda (new-row)
                  (adjoin-position
                   new-row k rest-of-queens))
               (enumerate-interval 1 board-size)))
         (queen-cols (- k 1))))))
  (queen-cols board-size))
 
Рейтинг: 0 / 0
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3452
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
весь код выглядит так (map я не стал выписывать ещё раз, потому что он реализован в стандартной библиотеке и любой интерпретатор его понимает)
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
(define (queens board-size)
  (define (queen-cols k)
    (if (= k 0)
       (list empty-board)
       (filter
        (λ (positions) (safe? k positions))
        (flatmap
         (λ (rest-of-queens)
           (map (lambda (new-row)
                  (adjoin-position
                   new-row k rest-of-queens))
               (enumerate-interval 1 board-size)))
         (queen-cols (- k 1))))))
  (queen-cols board-size))

; nil
(define nil '())

; enumerate integers
(define (enumerate-interval low high)
  (if (> low high)
     nil
     (cons low (enumerate-interval (+ low 1) high))))

; filter
(define (filter predicate sequence)
  (if (null? sequence)
     sequence
     (if (predicate (car sequence))
        (cons (car sequence) (filter predicate (cdr sequence)))
        (filter predicate (cdr sequence)))))

; accumulate
(define (accumulate op init sequence)
  (cond ((null? sequence) init)
       (else (op (car sequence) (accumulate op init (cdr sequence))))))

; flatmap
(define (flatmap proc seq)
  (accumulate append nil (map proc seq)))

(define empty-board nil)

(define (adjoin-position new-row k rest-of-queens)
  (append rest-of-queens (list (list new-row k))))

(define row-column-neighborhood?
  (λ (a b)
    (and
     (not (equal? a nil))
     (or (= (car a) (car b)) (= (cadr a) (cadr b)))
     ;(not (and (= (car a) (car b)) (= (cadr a) (cadr b)))))))
     (not (equal? a b)))))

(define (diagonal-neighborhoods item)
  (define (neighborhoods item min max direction)
    (let ((x (car item))
          (y (cadr item))
          (x-operation (if (or (equal? direction "SE") (equal? direction "SW")) + -))
          (y-operation (if (or (equal? direction "SE") (equal? direction "NE")) + -)))
      (if (and (>= x min) (<= x max) (>= y min) (<= y max))
         (cons item (neighborhoods (list (x-operation x 1) (y-operation y 1)) min max direction))
         '())))
  (append
   (remove item (neighborhoods item 1 8 "NE"))
   (remove item (neighborhoods item 1 8 "NW"))
   (remove item (neighborhoods item 1 8 "SE"))
   (remove item (neighborhoods item 1 8 "SW"))))

(define (safe? k positions)
  (let ((item (car (filter (λ (x) (= (cadr x) k)) positions))))
    (equal? (filter (λ (x) (row-column-neighborhood?  item x)) positions)
           (filter (λ (x) (diagonal-neighborhoods?  item x)) positions))))

(define diagonal-neighborhoods?
  (λ (a b)
    (not (equal? nil
                (filter (λ (x) (equal? a x))
                       (diagonal-neighborhoods b))))))
 
Рейтинг: 0 / 0
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3453
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
проверяем
Код
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
> (queens 8)
'(((1 1) (5 2) (8 3) (6 4) (3 5) (7 6) (2 7) (4 8))
  ((1 1) (6 2) (8 3) (3 4) (7 5) (4 6) (2 7) (5 8))
  ((1 1) (7 2) (4 3) (6 4) (8 5) (2 6) (5 7) (3 8))
  ((1 1) (7 2) (5 3) (8 4) (2 5) (4 6) (6 7) (3 8))
  ((2 1) (4 2) (6 3) (8 4) (3 5) (1 6) (7 7) (5 8))
  ((2 1) (5 2) (7 3) (1 4) (3 5) (8 6) (6 7) (4 8))
  ((2 1) (5 2) (7 3) (4 4) (1 5) (8 6) (6 7) (3 8))
  ((2 1) (6 2) (1 3) (7 4) (4 5) (8 6) (3 7) (5 8))
  ((2 1) (6 2) (8 3) (3 4) (1 5) (4 6) (7 7) (5 8))
  ((2 1) (7 2) (3 3) (6 4) (8 5) (5 6) (1 7) (4 8))
  ((2 1) (7 2) (5 3) (8 4) (1 5) (4 6) (6 7) (3 8))
  ((2 1) (8 2) (6 3) (1 4) (3 5) (5 6) (7 7) (4 8))
  ((3 1) (1 2) (7 3) (5 4) (8 5) (2 6) (4 7) (6 8))
  ((3 1) (5 2) (2 3) (8 4) (1 5) (7 6) (4 7) (6 8))
  ((3 1) (5 2) (2 3) (8 4) (6 5) (4 6) (7 7) (1 8))
  ((3 1) (5 2) (7 3) (1 4) (4 5) (2 6) (8 7) (6 8))
  ((3 1) (5 2) (8 3) (4 4) (1 5) (7 6) (2 7) (6 8))
  ((3 1) (6 2) (2 3) (5 4) (8 5) (1 6) (7 7) (4 8))
  ((3 1) (6 2) (2 3) (7 4) (1 5) (4 6) (8 7) (5 8))
  ((3 1) (6 2) (2 3) (7 4) (5 5) (1 6) (8 7) (4 8))
  ((3 1) (6 2) (4 3) (1 4) (8 5) (5 6) (7 7) (2 8))
  ((3 1) (6 2) (4 3) (2 4) (8 5) (5 6) (7 7) (1 8))
  ((3 1) (6 2) (8 3) (1 4) (4 5) (7 6) (5 7) (2 8))
  ((3 1) (6 2) (8 3) (1 4) (5 5) (7 6) (2 7) (4 8))
  ((3 1) (6 2) (8 3) (2 4) (4 5) (1 6) (7 7) (5 8))
  ((3 1) (7 2) (2 3) (8 4) (5 5) (1 6) (4 7) (6 8))
  ((3 1) (7 2) (2 3) (8 4) (6 5) (4 6) (1 7) (5 8))
  ((3 1) (8 2) (4 3) (7 4) (1 5) (6 6) (2 7) (5 8))
  ((4 1) (1 2) (5 3) (8 4) (2 5) (7 6) (3 7) (6 8))
  ((4 1) (1 2) (5 3) (8 4) (6 5) (3 6) (7 7) (2 8))
  ((4 1) (2 2) (5 3) (8 4) (6 5) (1 6) (3 7) (7 8))
  ((4 1) (2 2) (7 3) (3 4) (6 5) (8 6) (1 7) (5 8))
  ((4 1) (2 2) (7 3) (3 4) (6 5) (8 6) (5 7) (1 8))
  ((4 1) (2 2) (7 3) (5 4) (1 5) (8 6) (6 7) (3 8))
  ((4 1) (2 2) (8 3) (5 4) (7 5) (1 6) (3 7) (6 8))
  ((4 1) (2 2) (8 3) (6 4) (1 5) (3 6) (5 7) (7 8))
  ((4 1) (6 2) (1 3) (5 4) (2 5) (8 6) (3 7) (7 8))
  ((4 1) (6 2) (8 3) (2 4) (7 5) (1 6) (3 7) (5 8))
  ((4 1) (6 2) (8 3) (3 4) (1 5) (7 6) (5 7) (2 8))
  ((4 1) (7 2) (1 3) (8 4) (5 5) (2 6) (6 7) (3 8))
  ((4 1) (7 2) (3 3) (8 4) (2 5) (5 6) (1 7) (6 8))
  ((4 1) (7 2) (5 3) (2 4) (6 5) (1 6) (3 7) (8 8))
  ((4 1) (7 2) (5 3) (3 4) (1 5) (6 6) (8 7) (2 8))
  ((4 1) (8 2) (1 3) (3 4) (6 5) (2 6) (7 7) (5 8))
  ((4 1) (8 2) (1 3) (5 4) (7 5) (2 6) (6 7) (3 8))
  ((4 1) (8 2) (5 3) (3 4) (1 5) (7 6) (2 7) (6 8))
  ((5 1) (1 2) (4 3) (6 4) (8 5) (2 6) (7 7) (3 8))
  ((5 1) (1 2) (8 3) (4 4) (2 5) (7 6) (3 7) (6 8))
  ((5 1) (1 2) (8 3) (6 4) (3 5) (7 6) (2 7) (4 8))
  ((5 1) (2 2) (4 3) (6 4) (8 5) (3 6) (1 7) (7 8))
  ((5 1) (2 2) (4 3) (7 4) (3 5) (8 6) (6 7) (1 8))
  ((5 1) (2 2) (6 3) (1 4) (7 5) (4 6) (8 7) (3 8))
  ((5 1) (2 2) (8 3) (1 4) (4 5) (7 6) (3 7) (6 8))
  ((5 1) (3 2) (1 3) (6 4) (8 5) (2 6) (4 7) (7 8))
  ((5 1) (3 2) (1 3) (7 4) (2 5) (8 6) (6 7) (4 8))
  ((5 1) (3 2) (8 3) (4 4) (7 5) (1 6) (6 7) (2 8))
  ((5 1) (7 2) (1 3) (3 4) (8 5) (6 6) (4 7) (2 8))
  ((5 1) (7 2) (1 3) (4 4) (2 5) (8 6) (6 7) (3 8))
  ((5 1) (7 2) (2 3) (4 4) (8 5) (1 6) (3 7) (6 8))
  ((5 1) (7 2) (2 3) (6 4) (3 5) (1 6) (4 7) (8 8))
  ((5 1) (7 2) (2 3) (6 4) (3 5) (1 6) (8 7) (4 8))
  ((5 1) (7 2) (4 3) (1 4) (3 5) (8 6) (6 7) (2 8))
  ((5 1) (8 2) (4 3) (1 4) (3 5) (6 6) (2 7) (7 8))
  ((5 1) (8 2) (4 3) (1 4) (7 5) (2 6) (6 7) (3 8))
  ((6 1) (1 2) (5 3) (2 4) (8 5) (3 6) (7 7) (4 8))
  ((6 1) (2 2) (7 3) (1 4) (3 5) (5 6) (8 7) (4 8))
  ((6 1) (2 2) (7 3) (1 4) (4 5) (8 6) (5 7) (3 8))
  ((6 1) (3 2) (1 3) (7 4) (5 5) (8 6) (2 7) (4 8))
  ((6 1) (3 2) (1 3) (8 4) (4 5) (2 6) (7 7) (5 8))
  ((6 1) (3 2) (1 3) (8 4) (5 5) (2 6) (4 7) (7 8))
  ((6 1) (3 2) (5 3) (7 4) (1 5) (4 6) (2 7) (8 8))
  ((6 1) (3 2) (5 3) (8 4) (1 5) (4 6) (2 7) (7 8))
  ((6 1) (3 2) (7 3) (2 4) (4 5) (8 6) (1 7) (5 8))
  ((6 1) (3 2) (7 3) (2 4) (8 5) (5 6) (1 7) (4 8))
  ((6 1) (3 2) (7 3) (4 4) (1 5) (8 6) (2 7) (5 8))
  ((6 1) (4 2) (1 3) (5 4) (8 5) (2 6) (7 7) (3 8))
  ((6 1) (4 2) (2 3) (8 4) (5 5) (7 6) (1 7) (3 8))
  ((6 1) (4 2) (7 3) (1 4) (3 5) (5 6) (2 7) (8 8))
  ((6 1) (4 2) (7 3) (1 4) (8 5) (2 6) (5 7) (3 8))
  ((6 1) (8 2) (2 3) (4 4) (1 5) (7 6) (5 7) (3 8))
  ((7 1) (1 2) (3 3) (8 4) (6 5) (4 6) (2 7) (5 8))
  ((7 1) (2 2) (4 3) (1 4) (8 5) (5 6) (3 7) (6 8))
  ((7 1) (2 2) (6 3) (3 4) (1 5) (4 6) (8 7) (5 8))
  ((7 1) (3 2) (1 3) (6 4) (8 5) (5 6) (2 7) (4 8))
  ((7 1) (3 2) (8 3) (2 4) (5 5) (1 6) (6 7) (4 8))
  ((7 1) (4 2) (2 3) (5 4) (8 5) (1 6) (3 7) (6 8))
  ((7 1) (4 2) (2 3) (8 4) (6 5) (1 6) (3 7) (5 8))
  ((7 1) (5 2) (3 3) (1 4) (6 5) (8 6) (2 7) (4 8))
  ((8 1) (2 2) (4 3) (1 4) (7 5) (5 6) (3 7) (6 8))
  ((8 1) (2 2) (5 3) (3 4) (1 5) (7 6) (4 7) (6 8))
  ((8 1) (3 2) (1 3) (6 4) (2 5) (5 6) (7 7) (4 8))
  ((8 1) (4 2) (1 3) (3 4) (6 5) (2 6) (7 7) (5 8)))
расстановка с картинки здесь вроде попала на 27-ю строку.

число расстановок:
Код
1.
2.
> (length (queens 8))
92
Изменено: 25.09.2020, 08:19 - Дырокол
Рейтинг: 0 / 0
Ну чо, будем решать задачу про расстановку ферзей. или чо
    #3454
Дырокол
Скрыть профиль Поместить в игнор-лист
Участник
должно работать на любом интерпретаторе

я использую racket
Код
1.
2.
sudo add-apt-repository ppa:plt/racket
sudo apt install racket
консольные интерпретаторы рубят юникод, поэтому красивую лямбду (λ (a b)) зарубят. в этом случае пишем топорно (lambda (a b))

если запускать не racket, а gui-шный drracket, то будет норм.
 
Рейтинг: 0 / 0
Форумы / Общение / Ну чо, будем решать задачу про расстановку ферзей. или чо
Сообщения: 57 / Страницы: 1  2  3  все  
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые участники ...
Найденые участники ...
x
x
Закрыть


Просмотр
Close
Debug Console [Select Text]