-1

The program is to generate all possible results of eight queens. I use a list which cotains row numbers as the data structure. But when I run it, I got wrong results. Here is my Code:

(define (queens board-size)
  (define (safe? k position)
    (define (iter last-element front-lst col-num k)
      (define (ok? l-e car-lst)
    (and (not (= l-e car-lst))
         (not (= (abs (- l-e car-lst)) (abs (- k col-num))))))
      (if (null? front-lst)
      true
      (and (ok? last-element (car front-lst))
           (iter last-element (cdr front-lst) (++ col-num) k))))
    (let ((l-e (car (my-reverse position)))
      (f-l (my-remove (car (my-reverse position)) position)))
      (iter l-e f-l 1 k)))

  (define empty-board nil)

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

  (define (queen-cols k)
    (if (= k 0)
    (list empty-board)
    (filter
     (lambda (positions) (safe? k positions))
     (my-flatmap
      (lambda (rest-of-queens)
        (map (lambda (new-row)
           (adjoin-position new-row k rest-of-queens))
         (enumerate-interval 1 board-size)))
      (queen-cols (-- k))))))
  (queen-cols board-size))
Ray
  • 1
  • 1
  • 4
    Try commenting your code first. I doubt much people have time to try to understand what you wanted to do. And since there's a bug, you might even find it out! – Axioplase Sep 11 '12 at 07:36
  • 2
    What did you get, and what did you expect to get? – Justin Ethier Sep 11 '12 at 20:02
  • Stack overflow usually frowns upon people simply uploading there code and saying it produces "wrong results". What kind of wrong results? Which part of the code is broken? Etc. Consider editing your question, and reading the page that stackoverflow serves you before you post a question. – Spenser Truex Jul 21 '16 at 00:25

2 Answers2

1

I suspect your approach this is too complicated. What you need to do is:

find a new line number for the next queen that matches the two criteria: 1) it is not already contained 2) the distence between the new line number and any already used lines number is not equal to the distance of the two rows.

Do this in recursion.

My CL-solution for reference:

(defun fits (p list)
  (and (not (member p list))
       (loop for i in list as j from 1
            never (eql (abs (- p i)) j))))

(defun backtrack (list)
  (if (eql (length list) 8)
      (print list)
      (loop for i from 1 to 8
         when (fits i list)
           do (backtrack (cons i list)))))

run with

(backtrack nil)
Patrick
  • 508
  • 2
  • 9
1

I just today finished this question in SICP, so I'll try to help here:

I tested your code with this my-remove:

(define (my-remove num num-list)
    (cond   ((null? num-list) nil)
            ((= num (car num-list)) (cdr num-list))
            (else (cons (car num-list) (my-remove num (cdr num-list))))))

tested with:

(let ((result (queens 8)))
(display (length result))(newline)
(map (lambda (possible-solution) (display possible-solution)(newline)) result)
)

returned 92 . . (3 7 2 8 5 1 4 6) (3 7 2 8 6 4 1 5) . .

92 results, one of which is the solution in the book

Here's a part of your code (slightly) refactored, I got rid of my-remove, and used a let*. I'm not going to refactor the whole thing, but I atleast tried to add meaning in the variable names. with these changes it was somewhat faster: (also added some comments)

;no major refactoring, essentially removed my-remove and some refactors
(define (queens board-size)
  (define (safe? k position)
    (define (iter last-element front-lst col-num k)
        ;what's ok?
      (define (ok? l-e car-lst)
            (and (not (= l-e car-lst))
                (not (= (abs (- l-e car-lst)) (abs (- k col-num))))))
      (if (null? front-lst)
      true
      (and (ok? last-element (car front-lst))
           (iter last-element (cdr front-lst) (++ col-num) k))))
    ;queens means a list of rows, each representing a queen position
    ;that is, when queens[col] = row  that means there's a queen in row 'row and 
    ;column 'col

    ;reimplementing removing the queen, and the let turned to let*
    (let* ((reverse-column-queens (my-reverse position))
           (last-queen (car reverse-column-queens))
        ;remove that queen from the list
        ;btw 'position is actually 'positions
        (all-other-queens (my-reverse (cdr reverse-column-queens))))
      (iter last-queen all-other-queens 1 k)))
.
.
.

so, I guess the my-remove you used might have been wrong.

Now, the names of your variables are not very discriptive, so it would add to an already confusing code (no offence meant to the author of this exercise or you).

user1651640
  • 181
  • 4