N-Queens Scheme: trying to print out chessboard - vector

It is working fine and I've checked manually that everything is running, but I now need to figure out how to print out the answer in a chessboard like fashion, where I have an nxn board of 0's and 1's, where 1's are the queens. I am using vectors and for example lets say I run nq-bt for a 5x5 board I get the answer: #(0 2 4 1 3)
nq-bt is the method that gives me the answer above
Here is my pseudocode for trying to get this to work:
(define (print-answer n)
(make n equal to the returned vector of method (nq-bt))
(loop until it hits end of the returned vector_length)
(set value equal to (vector ref of n (*variable used for first loop)))
(loop again the length of returned vector_length)
(print 0's until hits vector ref's value, then print 1, then print 0's till end of loop)
(print newline)))))
I know this is insane pseudocode, but my problem is that I'm not used to scheme and there isn't too much documentation on how I could do any of this. Any help would be greatly appreciated.

You didn't mention which Scheme interpreter you're using, so first I'll show you a generic solution that uses standard procedures. For starters, we must decide how are we going to loop over the vector (say, using named lets).
Also notice that I changed the input parameter, it's easier if we pass the board's solution, besides I don't see how you can use the size n of the board if nq-bt doesn't receive it as a parameter (I hope nq-bt isn't obtaining n from a global define, that wouldn't be right):
(define (print-answer board)
(let outer-loop ((i 0))
(cond ((< i (vector-length board))
(let ((queen (vector-ref board i)))
(let inner-loop ((j 0))
(cond ((< j (vector-length board))
(display (if (= queen j) 1 0))
(display " ")
(inner-loop (+ j 1))))))
(newline)
(outer-loop (+ i 1))))))
Now, if you're lucky and use Racket we can write a simpler and more idiomatic implementation without all the kludge of the previous solution:
(define (print-answer board)
(for ([i (in-range (vector-length board))])
(let ([queen (vector-ref board i)])
(for ([j (in-range (vector-length board))])
(printf "~a " (if (= queen j) 1 0))))
(newline)))
Either way we can call print-answer with the result returned by nq-bt. For example:
(print-answer '#(0 2 4 1 3))
1 0 0 0 0
0 0 1 0 0
0 0 0 0 1
0 1 0 0 0
0 0 0 1 0

Related

Clisp error : Variable has no value (In this Binary search program high and low has no value)

Simple program for binary search.
elements contain no. of elements
then array contains those elements
then q contains no. of queries
search contains element to be searched.
Why this error is coming about high and low has no value after some iterations.
Kindly help :)
My Code :-
(setf elements (parse-integer (read-line)))
(setf array (make-array elements :fill-pointer 0))
(dotimes (i elements) (vector-push (parse-integer (read-line)) array))
(setf q (parse-integer (read-line)))
(defvar *mid*)
(dotimes (i q)
(setf search (parse-integer (read-line)))
(do ((low 0)
(high (- elements 1))
(mid (floor (+ low high) 2)
(floor (+ low high) 2)))
((>= low high) (setf *mid* nil))
(cond
((eql (elt array mid) search) (setf *mid* mid))
((< (elt array mid) search) (setf high (- mid 1)))
(t (setf low (+ mid 1)))))
(format t "~a" *mid*))
Your code is a fine example of an old adage:
the determined Real Programmer can write FORTRAN programs in any language.
Unfortunately Lisp programmers are generally quiche-eating hippies: so here is one quiche-eater's solution to this problem, using notions not present when FORTRAN IV was handed down to us from above on punched stones. These notions are therefore clearly heretical, but nonetheless useful.
Assuming this is homework, you probably will not be able to submit this answer.
Reading the data
First of all we'll write some functions which read the specification of the problem from a stream or file. I have inferred what it is from your code.
(defun stream->search-spec (stream)
;; Read a search vector from a stream: return a vector to be searched
;; and a vector of elements to search for.
;;
;; This function defines what is in files: each line contains an
;; integer, and the file contains a count followed by that many
;; lines, which specifies first the vector to be searched, and then
;; the things to search for.
;;
;; This relies on PARSE-INTEGER & READ-LINE to puke appropriately.
(flet ((read-vector ()
(let* ((elts (parse-integer (read-line stream)))
(vec (make-array elts :element-type 'integer))) ;won't help
(dotimes (i elts vec)
(setf (aref vec i) (parse-integer (read-line stream)))))))
(values (read-vector) (read-vector))))
(defun file->search-spec (file)
;; Read a search vector from a file. This is unused below but is
;; useful to have.
(with-open-file (in file)
(stream->search-spec in)))
(defun validate-sorted-vector (v)
;; check that V is a sorted vector
(dotimes (i (- (length v) 1) v)
(unless (<= (aref v i) (aref v (1+ i)))
(return-from validate-sorted-vector nil))))
The last function is used below to sanity check the data, since the search algorithm assumes the vector is sorted.
The search function
This implements binary search in the same way yours tries to do. Rather than doing it with loops and explicit assignemnt it does it using a local recursive function, which is far easier to understand. There are also various sanity checks and optionally debugging output. In any implementation which optimises tail calls this will be optimised to a loop; in implementations which don't then there will be a few extra function calls but stack overflow problems are very unlikely (think about why: how big would the vector need to be?).
(defun search-sorted-vector-for (vector for &key (debug nil))
;; search a sorted vector for some value. If DEBUG is true then
;; print what we're doing. Return the index, or NIL if FOR is not
;; present.
(when debug
(format *debug-io* "~&* ~D:~%" for))
(labels ((search (low mid high)
(when debug
(format *debug-io* "~& ~10D ~10D ~10D~%" low mid high))
(if (<= low mid high)
;; more to do
(let ((candidate (aref vector mid)))
(cond ((= candidate for)
;; found it
mid)
((< candidate for)
;; look higher
(search (1+ mid) (floor (+ high mid 1) 2) high))
((> candidate for)
;; look lower
(search low (floor (+ low mid) 2) (1- mid)))
(t
;; can't happen
(error "mutant death"))))
;; low = high: failed
nil)))
(let ((high (1- (length vector))))
(search 0 (floor high 2) high))))
Putting the previous two things together.
search-sorted-vector-with-search-vector will repeatedly search using the two vectors that the *->search-spec functions return. stream->search-results uses stream->search-spec and then calls this on its values. file->search-results does it all from a file.
(defun search-sorted-vector-with-search-vector (vector searches &key (debug nil))
;; do a bunch of searches, returning a vector of results.
(let ((results (make-array (length searches))))
(dotimes (i (length searches) results)
(setf (aref results i) (search-sorted-vector vector (aref searches i)
:debug debug)))))
(defun stream->search-results (stream &key (debug nil))
;; Read search specs from a stream, and search according to them.
;; Return the vector of results, the vector being searched and the
;; vector of search specifications.
(multiple-value-bind (to-search search-specs) (stream->search-spec stream)
(when debug
(format *debug-io* "~&searching ~S~% for ~S~&" to-search search-specs))
(assert (validate-sorted-vector to-search) (to-search) "not sorted")
(values (search-sorted-vector-with-search-vector to-search search-specs
:debug debug)
to-search search-specs)))
(defun file->search-results (file &key (debug nil))
;; sort from a file
(with-open-file (in file)
(stream->search-results in :debug debug)))
Using it
Given a file /tmp/x.dat with:
9
1
10
100
101
102
103
200
201
400
6
10
102
200
1
400
99
then:
> (file->search-results "/tmp/x.dat" :debug t)
searching #(1 10 100 101 102 103 200 201 400)
for #(10 102 200 1 400 99)
* 10:
0 4 8
0 2 3
0 1 1
* 102:
0 4 8
* 200:
0 4 8
5 6 8
* 1:
0 4 8
0 2 3
0 1 1
0 0 0
* 400:
0 4 8
5 6 8
7 7 8
8 8 8
* 99:
0 4 8
0 2 3
0 1 1
2 1 1
#(1 4 6 0 8 nil)
#(1 10 100 101 102 103 200 201 400)
#(10 102 200 1 400 99)
You can see that the last search failed (99 is not in the vector).

How do I get out of this recursive function when n = -1?

The problem I have to solve is how many oranges are in a pyramid if each level has 2^n oranges. I think I have the basis for the solution, however this is an infinite recursion. How do I get out of this function when n has reached -1 and display the solution? This is in scheme.
I've used this to help me set up what I need:
(+ (expt 2 0) (+ (expt 2 1) (+ (expt 2 2) (expt 2 3))))
3 is arbitrary and I only used it to help me write out the solution
(define oranges
(lambda (n)
(+ (expt 2 n) (oranges(- n 1)))))
Running this will not work because it is an infinite loop.
When you're writing a recursive procedure, it's mandatory to have a base case: it's the exit point of the recursion, otherwise it'll loop infinitely. Ask yourself: when should my procedure end? what should I return in that case?
In your case is simple, you literally wrote the answer in the title: how should we handle the case when n = -1? (or -2, or -3...?) Just return a meaningful value! I'd suggest 0, because we're doing an addition.
Now, in your code ask with an if expression whether we're in a value when we should return, and then return 0 - otherwise do the recursive step, which will eventually reach the base case. This is what I mean:
(define oranges
(lambda (n)
(if (< n 0)
0
(+ (expt 2 n) (oranges (- n 1))))))
It works as expected:
(oranges 3)
=> 15
When you make a recursive function, there are different parts that are compulsory. You need the general case and the basic cases. You have forgotten the basic cases also known as exit condition. Your exit condition is n = 0, so your program will be:
(define (oranges n)
(cond [(= n 0) 1]
[else (+(expt 2 n)(oranges(- n 1)))]
)
)
Tested:
(oranges 1)
=> 3
(oranges 0)
=> 1
(oranges 2)
=> 7

Pascal's Triangle Row Sequence

I'm currently working on finding the row sequences of Pascal's triangle. I wanted to input the row number and output the sequence of numbers in a list up until that row. For example, (Pascal 4) would give the result (1 1 1 1 2 1 1 3 3 1).
I am trying to use an algorithm that I found. Here is the algorithm itself:
Vc = Vc-1 * ((r - c)/c)
r and c are supposed to be row and column, and V0=1. The algorithm can be specifically found on the wikipedia page in the section titled "Calculating and Individual Row or Diagonal."
Here is the code that I have so far:
(define pascal n)
(cond((zero? n) '())
((positive? n) (* pascal (- n 1) (/ (- n c)c))))
I know that's hardly anything but I've been struggling a lot on trying to find scoping the function with a let or a lambda to incorporate column values. Additionally, I've also been struggling on the recursion. I don't really know how to establish the base case and how to get to the next step. Basically, I've been getting pretty lost everywhere. I know this isn't showing much, but any step in the right direction would be greatly appreciated.
Using as a guide the entry in Wikipedia, this is a straightforward implementation of the algorithm for calculating a value in the Pascal Triangle given its row and column, as described in the link:
#lang racket
(define (pascal row column)
(define (aux r c)
(if (zero? c)
1
(* (/ (- r c) c)
(aux r (sub1 c)))))
(aux (add1 row) column))
For example, the following will return the first four rows of values, noticing that both rows and columns start with zero:
(pascal 0 0)
(pascal 1 0)
(pascal 1 1)
(pascal 2 0)
(pascal 2 1)
(pascal 2 2)
(pascal 3 0)
(pascal 3 1)
(pascal 3 2)
(pascal 3 3)
Now we need a procedure to stick together all the values up until the desired row; this works for Racket:
(define (pascal-up-to-row n)
(for*/list ((i (in-range n))
(j (in-range (add1 i))))
(pascal i j)))
The result is as expected:
(pascal-up-to-row 4)
> '(1 1 1 1 2 1 1 3 3 1)
I discussed Pascal's Triangle at my blog.
In your question, the expression for Vc is just for one row. That translates to code like this:
(define (row r)
(let loop ((c 1) (row (list 1)))
(if (= r c)
row
(loop (+ c 1) (cons (* (car row) (- r c) (/ c)) row)))))
Then you just put together a bunch of rows to make the triangle:
(define (rows r)
(let loop ((r r) (rows (list)))
(if (zero? r)
rows
(loop (- r 1) (append (row r) rows)))))
And here's the output:
> (rows 4)
(1 1 1 1 2 1 1 3 3 1)
The base case is (= r c) in the first function and (zero? r) in the second.
If you want to write subscripts clearly, you can adopt the notation used by TeX: subscripts are introduced by an underscore and superscripts by a caret, with braces around anything bigger than one character. Thus Vc in your notation would be V_c, and Vc-1 in your notation would be V_{c-1}.

How can I return list with different values?

If I have the following list:
(define thelist '(0 1 0 0 7 7 7))
How can I write a function that returns a new list in which the value in the requested cell is replaced.
Example:
(set-cell thelist 2 4)
This would return a new list with the same values, but in cell (2) there will be the value 4 instead of 1:
(0 4 0 0 7 7 7)
HtDP provides a really concrete methodology for solving this kind of problem. For this problem, your job is going to be to write down the template for lists, then to stare at it until you can see what the arguments to the recursive call should be, and what the results will be. I'm hoping that you've solved a bunch of warm-up problems on lists--compute the length of a list, count the number of 6's in the list, etc.
Although you can implement the requested functionality with lists, the natural way to solve that problem is to use a vector, and remember that in Scheme indexes start in 0 (that's why the second argument for vector-set! is a 1 and not a 2):
(define thevector (vector 0 1 0 0 7 7 7))
; thevector is #(0 1 0 0 7 7 7)
(vector-set! thevector 1 4)
; thevector is #(0 4 0 0 7 7 7)
Now, if you definitely need to use a list, something like this would work:
(define (set-cell lst idx val)
(cond ((null? lst) '())
((zero? idx) (cons val (cdr lst)))
(else (cons (car lst)
(set-cell (cdr lst) (sub1 idx) val)))))
And you'd call it like this:
(define thelist '(0 1 0 0 7 7 7))
(set-cell thelist 1 4)
> (0 4 0 0 7 7 7)
Again, I'm using 0-based indexing, as is the convention. Also notice that thelist was not modified, instead, set-cell returns a new list with the modification.
Other people have mentioned the 0-based indexes convention. I'll assume 0-based indexes, then.
The other answers you've gotten are wrong, given how you stated your problem. I'll cite the key point in your question (my emphasis):
This would return a new list with the same values, but in cell (2) there will be the value 4 instead of 1.
The answers you've been given are modifying a list in place, not returning a newly constructed list while leaving the original intact!
Here's a correct (though suboptimal) solution:
(define (set-list index new-value list)
(if (= index 0)
(cons new-value (cdr list))
(cons (car list)
(set-list (- index 1) new-value (cdr list))))))
I didn't bother to put in error checking here (e.g., if somebody passes in the empty list, or a list with too few elements relative to index, or a negative index).
Here is an approach using an auxiliary function that starts the count from 0. On each recursion, the count is incremented, and the list is shortened.
If the desired index is hit, the recursion can stop. If it gets to the end of the list without hitting the index, the original list is returned.
(define (set-cell ls ind val)
(define (aux c ls)
(cond ((null? ls) ls)
((= c ind) (cons val (cdr ls)))
(else (cons (car ls) (aux (+ c 1) (cdr ls))))))
(aux 0 ls))
What a mess above!! Keep it simple: Scheme has list-set! for this.
Example:
(define ls (list 1 2 3 4 5))
(list-set! ls 0 "new")
(list-set! ls 3 "changed")
(list-ref ls 0)
=> "new"
ls
=> '("new" 2 3 "changed" 5)
However, you might want to limit assignments on lists. Vectors are faster for this since you don't need to traverse the previous elements. Use lists whenever you can't specify the length before construction or when the length is continously changed.

getting an interval of a vector

I want to take an interval of a vector in Scheme. I know there is a procedure named vector->values, but seems like it returns each element separately, while I want to get the result as a vector. How can I achieve this?
> (vector->values (vector 1 2 3 4 5) 0 3)
1
2
3
while I need:
#(1 2 3)
If you're using PLT, you have a few easy ways to get this:
(define (subvector v start end)
(list->vector (for/list ([i (in-vector v start end)]) i)))
(define (subvector v start end)
(build-vector (- end start) (lambda (i) (vector-ref v (+ i start)))))
(define (subvector v start end)
(define new (make-vector (- end start)))
(vector-copy! new 0 v start end)
new)
The last one is probably going to be the fastest. The reason that there is no such operation that is built-in is that people usually don't do that. When you're dealing with vectors in Scheme, you're usually doing so because you want to optimize something so returning a vector and a range instead of allocating a new one is more common.
(And if you think that this is useful, please suggest it on the PLT mailing list.)
The Scheme R6RS standard has make-vector, vector-ref, vector-set! and vector-length. With that you can write your own function subvector, which does not seem to be part of R6RS (!). Some Scheme implementation have something like subvector already.
You can also switch to Common Lisp, which provides the function SUBSEQ in the standard.
Here is a portable R6RS version using SRFI 43:
#!r6rs
(import (rnrs base)
(prefix (srfi :43) srfi/43:))
(srfi/43:vector-copy (vector 1 2 3 4 5) 0 3)
#lang scheme
(define (my-vector-value v l h c)
(if (and (>= c l) (< c h))
(cons (first v) (my-vector-value (rest v) l h (add1 c)))
empty))
(list->vector (my-vector-value (vector->list (vector 1 2 3 4 5)) 0 3 0))
Ghetto? Yes, very. But it only took two minutes to write and gets the job done.
(I find it's generally easier to play with lists in Scheme)
you want subvector:
(subvector (vector 1 2 3 4 5) 0 3)

Resources