Racket simple sequence of int generator function - functional-programming

I have started working on my first racket function but there is a big problem.
(define (sequence low hide stride)
(letrec ([list-of-int null])
(define (f low hide stride)
(if (< low hide)
[(begin ((append (list low) list-of-int)
(f (+ low stride) hide stride)))]
[list-of-int]))
(f low hide stride)))
Can anybody help me with my racket understanding? In my mind it looks fine but doesn't work. I have found more simple solution in internet:
(define (sequence low high stride)
(if (> low high)
null
(cons low (sequence (+ low stride) high stride))))
I understand it but why my code doesn't work? Can anybody help me?
Oscars answer is really great) Thanks a lot dear friend.

First of all, this function already exists in Racket, and it's called range:
(range 1 11 1)
=> '(1 2 3 4 5 6 7 8 9 10)
Now, regarding your implementation you have to remember that list operations in Scheme do not modify lists in-place. In particular, this line is not doing what you imagine:
(append (list low) list-of-int)
Sure enough, append added a new element, but it returned a new list, and because you didn't store it as a variable or passed it as a parameter that modification was lost. Besides, it's better to use cons to build an output list, using append will result in a quadratic performance. Also, there's a mistake in here:
[(begin ((
See those double [( and (( there? they' re causing the "application: not a procedure" error being reported. In Scheme, surrounding an expression with () means function application - parentheses are not to be used for defining blocks of code, as you would use {} in other programming languages. A correct implementation from scratch follows, closer to what you had in mind and preserving the same behavior as range:
(define (sequence low high stride)
(define (f low cmp acc) ; lower bound, comparator and accumulator
(if (cmp high low) ; exit condition for base case
(reverse acc) ; reverse and return the accumulator
(f (+ low stride) ; advance lower bound
cmp ; pass the comparator
(cons low acc)))) ; build the list
(if (positive? stride) ; if the step is positive
(f low <= '()) ; initialize with <= comparator and '()
(f low >= '()))) ; else initialize with >= and '()
It works as expected:
(sequence 1 11 1)
=> '(1 2 3 4 5 6 7 8 9 10)
(sequence 1 12 2)
=> '(1 3 5 7 9 11)
(sequence 10 0 -1)
=> '(10 9 8 7 6 5 4 3 2 1)

Related

How does scramble function works? (Chapter 1 of The Seasoned Schemer)

According to the book, this is what the function definition is,
The function scramble takes a non-empty tuple in which no argument is greater than its own index and returns a tuple of same length. Each number in the argument is treated as a backward index from its own position to a point earlier in tuple. The result at each position is obtained by counting backward from the current position according to this index.
And these are some examples,
; Examples of scramble
(scramble '(1 1 1 3 4 2 1 1 9 2)) ; '(1 1 1 1 1 4 1 1 1 9)
(scramble '(1 2 3 4 5 6 7 8 9)) ; '(1 1 1 1 1 1 1 1 1)
(scramble '(1 2 3 1 2 3 4 1 8 2 10)) ; '(1 1 1 1 1 1 1 1 2 8 2)
Here is the implementation,
(define pick
(λ (i lat)
(cond
((eq? i 1) (car lat))
(else (pick (sub1 i)
(cdr lat))))))
(define scramble-b
(lambda (tup rev-pre)
(cond
((null? tup) '())
(else
(cons (pick (car tup) (cons (car tup) rev-pre))
(scramble-b (cdr tup)
(cons (car tup) rev-pre)))))))
(define scramble
(lambda (tup)
(scramble-b tup '())))
This is a case where using a very minimal version of the language means that the code is verbose enough that understanding the algorithm is not perhaps easy.
One way of dealing with this problem is to write the program in a much richer language, and then work out how the algorithm, which is now obvious, is implemented in the minimal version. Let's pick Racket as the rich language.
Racket has a function (as does Scheme) called list-ref: (list-ref l i) returns the ith element of l, zero-based.
It also has a nice notion of 'sequences' which are pretty much 'things you can iterate over' and a bunch of constructs whose names begin with for for iterating over sequences. There are two functions which make sequences we care about:
in-naturals makes an infinite sequence of the natural numbers, which by default starts from 0, but (in-naturals n) starts from n.
in-list makes a sequence from a list (a list is already a sequence in fact, but in-list makes things clearer and there are rumours also faster).
And the iteration construct we care about is for/list which iterates over some sequences and collects the result from its body into a list.
Given these, then the algorithm is almost trivial: we want to iterate along the list, keeping track of the current index and then do the appropriate subtraction to pick a value further back along the list. The only non-trivial bit is dealing with zero- vs one-based indexing.
(define (scramble l)
(for/list ([index (in-naturals)]
[element (in-list l)])
(list-ref l (+ (- index element) 1))))
And in fact if we cause in-naturals to count from 1 we can avoid the awkward adding-1:
(define (scramble l)
(for/list ([index (in-naturals 1)]
(element (in-list l)))
(list-ref l (- index element))))
Now looking at this code, even if you don't know Racket, the algorithm is very clear, and you can check it gives the answers in the book:
> (scramble '(1 1 1 3 4 2 1 1 9 2))
'(1 1 1 1 1 4 1 1 1 9)
Now it remains to work out how the code in the book implements the same algorithm. That's fiddly, but once you know what the algorithm is it should be straightforward.
If the verbal description looks vague and hard to follow, we can try following the code itself, turning it into a more visual pseudocode as we go:
pick i [x, ...ys] =
case i {
1 --> x ;
pick (i-1) ys }
==>
pick i xs = nth1 i xs
(* 1 <= i <= |xs| *)
scramble xs =
scramble2 xs []
scramble2 xs revPre =
case xs {
[] --> [] ;
[x, ...ys] -->
[ pick x [x, ...revPre],
...scramble2 ys
[x, ...revPre]] }
Thus,
scramble [x,y,z,w, ...]
=
[ nth1 x [x] (*x=1..1*)
, nth1 y [y,x] (*y=1..2*)
, nth1 z [z,y,x] (*z=1..3*)
, nth1 w [w,z,y,x] (*w=1..4*)
, ... ]
Thus each element in the input list is used as an index into the reversed prefix of that list, up to and including that element. In other words, an index into the prefix while counting backwards, i.e. from the element to the left, i.e. towards the list's start.
So we have now visualized what the code is doing, and have also discovered requirements for its input list's elements.

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).

Is (lambda (x) ... ) with parenthesis placed in a certain way used for limiting scope?

A classic enumeration using unfold:
(unfold-left (lambda (x)
(if (> x 10)
(#;no values)
(+ x 1)))
#;from 0)
===> (0 1 2 3 4 5 6 7 8 9 10))
if limiting the scope is not needed is there any way to just write x without the lambda?
unfold is implemented like this:
(define (unfold p f g seed (tail-gen (λ (_) '())))
(let recur ((seed seed))
(if (p seed)
(tail-gen seed)
(cons (f seed)
(recur (g seed))))))
As you can see p, f, g, and tail-gen are all procedures since they get surrounded by parentheses in the implementation. If they are not procedures you will get an application: not a procedure error.
You are using unfold wrong. you need a procedure that takes the current value and return wether or not you are finished. Second is a procedure that takes the seed and return what value to collect and the third is a procedure to create the next seed. The optional tail-gen takes the seed and creates the tail where the empty list will be used if not provided. Here is how you make a list from 0 to 10:
#lang racket
(require srfi/1)
(require srfi/26)
(unfold (cut > <> 10) identity add1 0)
; ==> (0 1 2 3 4 5 6 7 8 9 10)
And of course, (range 11) gives the same answer.

Knight's Tour Depth First Search Backtracking

I'm working on a knight's tour implementation using DFS.
My problem is, when I run it, it works fine up to step 20, but after that the algorithm freaks out and outputs this on a 5x5 board (there is a solution for a 5x5 board starting at (0,0)):
(1 10 5 16 24)
(4 15 2 11 20)
(9 6 17 23 22)
(14 3 8 19 12)
(7 18 13 21 25)
*Legal successors must be 0 <= row < n and 0 <= column < n and not be a previous step.
My implementation involves generating *legal successors using the genSuccessors function, throwing them onto a stack and recursively running the algorithm with the item at the top of the stack as the new current position. I only increment the step_count (in charge of tracking the order of squares the knight visits) if the next position is a step not taken before. When I cannot generate any more children, the algorithm explores other alternatives in the frontier until frontier empty (fail condition) or the step_count = # squares on the board (win).
I think the algorithm in general is sound.
edit: I think the problem is that when I can't generate more children, and I go to explore the rest of the frontier I need to scrap some of the current tour. My question is, how do I know how far back I need to go?
Graphically, in a tree I think I would need to go back up to the closest node that had a branch to an unvisited child and restart from there scrapping all the nodes visited when going down the previous (wrong) branch. Is this correct? How would I keep track of that in my code?
Thanks for reading such a long post; and thanks for any help you guys can give me.
Yikes! Your code is really scary. In particular:
1) It uses mutation everywhere.
2) It tries to model "return".
3) It doesn't have any test cases.
I'm going to be a snooty-poo, here, and simply remark that this combination of features makes for SUPER-hard-to-debug programs.
Also... for DFS, there's really no need to keep track of your own stack; you can just use recursion, right?
Sorry not to be more helpful.
Here's how I'd write it:
#lang racket
;; a position is (make-posn x y)
(struct posn (x y) #:transparent)
(define XDIM 5)
(define YDIM 5)
(define empty-board
(for*/set ([x XDIM]
[y YDIM])
(posn x y)))
(define (add-posn a b)
(posn (+ (posn-x a) (posn-x b))
(+ (posn-y a) (posn-y b))))
;; the legal moves, represented as posns:
(define moves
(list->set
(list (posn 1 2) (posn 2 1)
(posn -1 2) (posn 2 -1)
(posn -1 -2) (posn -2 -1)
(posn 1 -2) (posn -2 1))))
;; reachable knights moves from a given posn
(define (possible-moves from-posn)
(for/set ([m moves])
(add-posn from-posn m)))
;; search loop. invariant: elements of path-taken are not
;; in the remaining set. The path taken is given in reverse order.
(define (search-loop remaining path-taken)
(cond [(set-empty? remaining) path-taken]
[else (define possibilities (set-intersect (possible-moves
(first path-taken))
remaining))
(for/or ([p possibilities])
(search-loop (set-remove remaining p)
(cons p path-taken)))]))
(search-loop (set-remove empty-board (posn 0 0)) (list (posn 0 0)))
;; start at every possible posn:
#;(for/or ([p empty-board])
(search-loop (set-remove empty-board p) (list p)))

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