How to pretty print the contents of the 2d array b?
The code below only returns:
#<array:srfi-9-record-type-descriptor>
(require srfi/25)
(require racket/pretty)
(define (board x y)
(make-array (shape 0 x 0 y) 0))
(define b (board 7 7))
(pretty-print b)
also tried:
(array-map (lambda (n) (print n)) b) ...(i'm trying to mark this as code but it doesn't work)
but it returns:
0000000000000000000000000000000000000000000000000
is there any way for the print to insert a new line every x characters?
You can try rolling your own pretty-printing procedure, give this a try:
(define (pretty-print board)
(for ((i (in-range (array-length board 0))))
(for ((j (in-range (array-length board 1))))
(printf "~a\t" (array-ref board i j)))
(newline)))
For example:
(pretty-print (board 3 3))
0 0 0
0 0 0
0 0 0
Related
I have a list of lists and want to test if all elements are different from each other, i.e. equal should return nil for all combinations of list elements.
E.g.
(defparameter feld '((1 0 0 5 5 0)
(0 0 0 0 0 0)
(1 1 5 5 0 0)
(0 1 0 1 5 5)
(5 5 1 0 1 0)
(1 0 1 0 5 5)))
I thought of using reduce but as far as I understand it only tests the equality of neighbors, as would do a loop construct like:
(loop for i below (length feld)
for j from 1
if (equal (nth i feld) (nth j feld)) return t)
Is there a simple way using a standard construct which I do not see at the moment or do I have to create a recursive function?
The whole data structure represents a "board game" where every list is a line on the board and each element in the inside-lists is a value of this very field. The three numerical values (0, 1 and 5) are something like empty, Symbol A and Symbol B. A valid board cannot have two identical lines. This is why I want to identify those.
Basically, it is like remove-duplicates without removing. In the meantime I was thinking about something like this:
(defun duplicates-p (lst)
(cond ((null lst) '())
((member (car lst) (cdr lst)) t)
(t (duplicates-p (rest lst)))))
Something like this:
(defun unique (lsts &aux (h (make-hash-table :test 'equal)))
(loop :for lst :in lsts
:never (gethash lst h)
:do (setf (gethash lst h) t)))
This procedure takes a non-negative integer n and creates a list of all lists of n 0's or 1's in the specific order required for a truth table. I am just trying to understand how the map portion of the procedure works. I am particularly confused as to how append, map, and the recursive call to all-lists are working together in the second argument of the if. Any help would be greatly greatly appreciated!
(define all-lists
(lambda (n)
(if (= n 0)
'(())
(append (map (lambda (k) (cons 0 k)) (all-lists (- n 1)))
(map (lambda (k) (cons 1 k)) (all-lists (- n 1)))
))))
The best strategy to understand a recursive function is to try it with the case sligthly more complex than the terminal one. So, let's try it with n=1.
In this case, the function becomes:
(append (map (lambda (k) (cons 0 k)) (all-lists 0))
(map (lambda (k) (cons 1 k)) (all-lists 0))
that is:
(append (map (lambda (k) (cons 0 k)) '(()))
(map (lambda (k) (cons 1 k)) '(())))
So, the first map applies the function (lambda (k) (cons 0 k)) to all the elements of the list '(())), which has only an element, '(), producing '((0)) (the list containing an element obtained by the cons of 0 and the empty list), and in the same way the second map produces '((1)).
These lists are appended together yielding the list '((0) (1)), in other words, the list of all the lists of length 1 with all the possible combinations of 0 and 1.
In the case of n=2, the recursive case is applied to '((0) (1)): so the first map puts a 0 before all the elements, obtaining '((0 0) (0 1)), while the second map produces '((1 0) (1 1)). If you append together these two lists, you obtain '((0 0) (0 1) (1 0) (1 1)), which is the list of all the possible combinations, of length 2, of 0 and 1.
And so on, and so on...
Actually, the function is not well defined, since it calculates unnecessarily the value of (all-lists (- n 1)) two times at each recursion, so doubling its work, which is already exponential. So it could be made much more efficient by computing that value only once, for instance in the following way:
(define all-lists
(lambda (n)
(if (= n 0)
'(())
(let ((a (all-lists (- n 1))))
(append (map (lambda (k) (cons 0 k)) a)
(map (lambda (k) (cons 1 k)) a))))))
Separating statements along with 'println' can help understand what is happening:
(define (all-lists n)
(if (= n 0)
'(())
(let* ((a (all-lists (- n 1)))
(ol1 (map (λ (k) (cons 0 k)) a))
(ol2 (map (λ (k) (cons 1 k)) a))
(ol (append ol1 ol2)))
(println "---------")
(println ol1)
(println ol2)
(println ol)
ol)))
(all-lists 3)
Output:
"---------"
'((0))
'((1))
'((0) (1))
"---------"
'((0 0) (0 1))
'((1 0) (1 1))
'((0 0) (0 1) (1 0) (1 1))
"---------"
'((0 0 0) (0 0 1) (0 1 0) (0 1 1))
'((1 0 0) (1 0 1) (1 1 0) (1 1 1))
'((0 0 0) (0 0 1) (0 1 0) (0 1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1))
'((0 0 0) (0 0 1) (0 1 0) (0 1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1))
One can clearly see how outlists (ol1, ol2 and combined ol) are changing at each step.
Why following function (match-redefine) is not working?
(define vlist (list 10 20 30))
(match-define (list aa bb cc) (list 1 2 3))
(define alist (list aa bb cc))
alist
vlist
(define (match-redefine dst_list src_list)
(for ((d dst_list)(s src_list)) (set! d s)) )
(rnmatch-redefine alist vlist)
alist
vlist
The output is:
'(1 2 3)
'(10 20 30)
'(1 2 3)
'(10 20 30)
The destination list (alist) remains unchanged. Can this function be made to work?
Edit: I tried vector as suggested by #OscarLopez in the answers, but it does not work:
(match-define (list a b c) (list 0 0 0 ) )
(define variable_vect (vector a b c))
a
b
c
(define valuelist (list 1 2 3) )
(for ((i variable_vect)(j valuelist)) ; does not work
(set! i j))
variable_vect
a
b
c
(set! variable_vect valuelist)
(println "------- after ----------")
variable_vect
a
b
c
Output is:
0
0
0
'#(0 0 0)
0
0
0
"------- after ----------"
'(1 2 3)
0
0
0
Edit: It seems I will have to use special class to apply this:
(define myob%
(class object%
(super-new)
(init-field val)
(define/public (getval) val)
(define/public (setval v) (set! val v)) ))
(define (copyvalues objlist valuelist)
(for ((a alist)(v valuelist)) (send a setval v)) )
(define (show_objlist alist)
(for ((a alist)) (println (send a getval))) )
; USED AS FOLLOWS:
(define ob1 (make-object myob% 5))
(define ob2 (make-object myob% 5))
(define ob3 (make-object myob% 5))
(define alist (list ob1 ob2 ob3))
(println "---------- first assignment -----------")
(define vlist (list 1 2 3))
(copyvalues alist vlist)
(show_objlist alist)
(println "---------- second assignment -----------")
(define ylist (list 10 20 30))
(copyvalues alist ylist)
(show_objlist alist)
(println "---------- individual access -----------")
(send ob1 getval)
(send ob3 getval)
Output is:
"---------- first assignment -----------"
1
2
3
"---------- second assignment -----------"
10
20
30
"---------- individual access -----------"
10
30
You ask why the function is not working.
The reason is that (set! d s) is doing something
you do not expect.
Observe:
#lang racket
(define vlist (list 10 20 30))
(match-define (list aa bb cc) (list 1 2 3))
(define alist (list aa bb cc))
alist
vlist
(define (match-redefine dst_list src_list)
(for ((d dst_list)(s src_list))
(set! d s)
(displayln (~a "d is now: " s))))
(match-redefine alist vlist)
The output is:
'(1 2 3)
'(10 20 30)
d is now: 10
d is now: 20
d is now: 30
This means that you change the value of d (not the value of the variable which corresponds to the symbols that d runs through.
See your previous question on the same topic.
Again, this is not the way we do things in Scheme. Besides, your code is simply reassigning a local variable that was pointing to an element in the list, the destination list remains unmodified.
You could use vectors instead of lists - those can be modified, exactly as you would modify an array in the most common programming languages, something like this:
(define value_list (list 1 2 3))
(define value_vect (vector 0 0 0))
value_vect
=> '#(0 0 0)
(for [(i (in-range (vector-length value_vect)))
(value value_list)]
(vector-set! value_vect i value))
value_vect
=> '#(1 2 3)
Anyway you should not modify a list of variables, just return a list with the new values. And don't think about mutating the list - although it is possible to do so using mutable pairs, that's not the correct way to deal with this situation, please stop thinking about mutating everything you encounter!
I'm attempting to create a function that creates copies of whatever list the user puts in by the desired number of copies.
User: (copy '(A) '(7))
Output: (A A A A A A A)
(defun copy (x y)
(cond ((-1 counter)
nil)
(T
(list (cons (car x) (cdr x)))
copy
(cdr x)))
I'm attempting to set up a counter and just create a new list into the current list by decrementing the counter. So far the counter is pseudo-code.
This is the counter I'm trying to figure out.
(defun count (y)
(let ((a y))
(- a 1)))
The error I get is that whatever I put into y isn't a number.
While I can understand why the first parameter is a list, the second must be a number. A very simple implementation might look like:
(defun copy (lst count)
(when (> count 0)
(append (copy-list lst) (copy lst (1- count)))))
Testing:
CL-USER> (copy '(A) 7)
(A A A A A A A)
CL-USER> (copy '(A B C) 7)
(A B C A B C A B C A B C A B C A B C A B C)
The usual caveats concerning the use of append and object copying apply.
I'd suggest passing your list as a &rest argument instead and use loop:
(defun repeat (n &rest items)
(loop repeat n append items))
Test
CL-USER> (repeat 10 0 1 2)
(0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2)
I have written the following program to calculate the sum of all multiples of 3 & 5 below 1000 in scheme. However, it gives me an incorrect output.
Any help would be much appreciated.
(define (multiples)
(define (calc a sum ctr cir)
(cond (> a 1000) (sum)
(= ctr 7) (calc (+ a (list-ref cir 0)) (+ sum a) 0 (list 3 2 1 3 1 2 3))
(else (calc (+ a (list-ref cir ctr)) (+ sum a) (+ 1 ctr) (list 3 2 1 3 1 2 3)))))
(calc 0 0 0 (list 3 2 1 3 1 2 3)))
You can simply port imperative style solution to functional Scheme by using an accumulator(sum parameter) and a target parameter to test when to stop summing:
(define (multiples)
(define (multiples-iter num sum target)
(if (> num target)
sum
(multiples-iter (+ 1 num)
(if (or (zero? (mod num 3)) (zero? (mod num 5)))
(+ sum num)
sum)
target)))
(multiples-iter 0 0 1000))
Here's my (Racket-specific) solution, which doesn't involve lots of (or, for that matter, any) modulo calls, and is completely general (so that you don't need to construct the (3 2 1 3 1 2 3) list that the OP has):
(define (sum-of-multiples a b limit)
(define (sum-of-multiple x)
(for/fold ((sum 0))
((i (in-range 0 limit x)))
(+ sum i)))
(- (+ (sum-of-multiple a) (sum-of-multiple b))
(sum-of-multiple (lcm a b))))
Test run:
> (sum-of-multiples 3 5 1000)
233168
If you're using Racket, there's a very compact way to do what you ask, using looping constructs:
(for/fold ([sum 0])
([i (in-range 1 1000)]
#:when (or (zero? (modulo i 3)) (zero? (modulo i 5))))
(+ sum i))
=> 233168
One problem is that your code is missing a pair of parentheses around the cond clauses.
In the line (cond (> a 1000) (sum) the condition is just> while a and 1000 are interpreted as forms to be evaluated if > is true (which it is), and thus 1000 will be returned as the result.
Two other problem (masked by the first one) is that you are initializing ctr to 0 when it reaches 7, while it should be set to the next value, i.e. 1, and that you are including 1000 in the result.
The corrected version of your function is
(define (multiples)
(define (calc a sum ctr cir)
(cond ((>= a 1000) sum)
((= ctr 7) (calc (+ a (list-ref cir 0)) (+ sum a) 1 (list 3 2 1 3 1 2 3)))
(else (calc (+ a (list-ref cir ctr)) (+ sum a) (+ 1 ctr) (list 3 2 1 3 1 2 3)))))
(calc 0 0 0 (list 3 2 1 3 1 2 3)))
The same algorithm can also be defined as a non-recursive function like this:
(define (multiples)
(do ((cir (list 3 2 1 3 1 2 3))
(ctr 0 (+ ctr 1))
(a 0 (+ a (list-ref cir (modulo ctr 7))))
(sum 0 (+ sum a)))
((>= a 1000) sum)))
(require-extension (srfi 1))
(define (sum-mod-3-5 upto)
(define (%sum-mod-3-5 so-far generator-position steps)
(let ((next (car generator-position)))
(if (> (+ steps next) upto)
so-far
(%sum-mod-3-5 (+ so-far steps)
(cdr generator-position)
(+ steps next)))))
(%sum-mod-3-5 0 (circular-list 3 2 1 3 1 2 3) 0)) ; 233168
For this particular task, it will do on average half the operations then you would do if incrementing the counter by one, also, one less if condition to check.
Also, modulo (as being division in disguise, probably) is more expensive then summation.
EDIT: I'm not a pro on modular system in different dialects of Scheme. The SRFI-1 extension here is only required to make it easier to create a circular list. I couldn't find an analogue to Common Lisp (#0=(3 2 1 3 1 2 3) . #0#), but perhaps, someone more knowledgeable will correct this.
If you absolutely want to use the "repeating pattern" method, you could go about it something like this.
This uses recursion on the list of intervals rather than relying on list-ref and explicit indexing.
(define (mults limit)
(define steps '(3 2 1 3 1 2 3))
(define (mults-help a sum ls)
(cond ((>= a limit) sum)
((null? ls) (mults-help a sum steps))
(else (mults-help (+ a (car ls))
(+ a sum)
(cdr ls)))))
(mults-help 0 0 steps))