translate a matrix in scheme - matrix

Having trouble translating a matrix where the input would be two lists and the output would be the addition of the second list to every first such as:
(translate '((1 2 3)(4 5 6)(7 8 9)) '(10 20 30))
; -> ((11 22 33) (14 25 36) (17 28 39))
I currently have:
(define (translate matrix1 matrix2)
(if (list? (car matrix1))
(append '() (map + (car matrix1) matrix2))
(translate (cdr matrix1) matrix2)))
I think this will keep appending each car of matrix1 everytime I recursively call to an empty list but I'm only getting my first 'row' to output.
Any input would be greatly appreciated!

That would be as easy as
(define (translate matrix1 matrix2)
(map (lambda (lst) (map + lst matrix2)) matrix1))
Testing
> (translate '((1 2 3)(4 5 6)(7 8 9)) '(10 20 30))
'((11 22 33) (14 25 36) (17 28 39))

Related

count number of element in multiple sublists scheme

i would like to ask you for help with my task i am trying to solve. Function should work like this. Input is sublist ((1 10 250) (1 10 250) (250 10 250) (1 10 255))) and output should be ((1 . 3) (10 . 4) (250 . 4) (255 . 1)) so it output is actually histogram in text format.
I am using this code with implementation of flatten function which is making from sublists one list. But it is counting number of sublists and not every element in sublist.
(define (run-length-encode lst )
(define (rle val-lst cur-val cur-cnt acc)
(if (pair? val-lst)
(let ((new-val (car val-lst)))
(if (eq? new-val cur-val)
(rle (cdr val-lst) cur-val (+ cur-cnt 1) acc)
(rle (cdr val-lst) new-val 1 (cons (cons cur-cnt cur-val) acc))))
(cons (cons cur-cnt cur-val) acc)))
(if (pair? lst)
(reverse (rle (cdr lst) (car lst) 1 '()))
'()))
Flatten function:
(define (flatten lst)
(if (not (list? lst))
(list lst)
(apply append (map flatten lst))))
Output:
> (run-length-encode '((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
(250 10 1 1 250 10 1 1 250 10 250 1 255 10 1 1)
Thanks for help on this.
Jan
In Racket there's a built-in flatten procedure, there's no need to rewrite it. Coupled with good old bagify, we can solve the problem using simple procedure composition - you should avoid trying to do everything in a single procedure, it'll be confusing:
#lang racket
(define (bagify lst)
(foldl (lambda (key ht)
(hash-update ht key add1 0))
#hash() lst))
(define (run-length-encode lst)
(hash->list
(bagify (flatten lst))))
It works as expected:
(run-length-encode '((1 10 250) (1 10 250) (250 10 250) (1 10 255)))
=> '((1 . 3) (250 . 4) (10 . 4) (255 . 1))

Racket: sliding window over a vector

What are some good ways to perform a sliding window over a finite sequence in Racket, such as finding the highest sum of any sub-sequence of 4 numbers?
(define example #(3 1 4 5 10 23 1 50 0 12 40 12 43 20))
First find prefix sums:
#lang racket
(define example #(3 1 4 5 10 23 1 50 0 12 40 12 43 20))
(define-values (sums sum)
(for/fold ([sums '()] [sum 0]) ([x example])
(values (cons sum sums) (+ sum x))))
(list->vector (cons sum sums))
Result:
'#(224 204 161 149 109 97 97 47 46 23 13 8 4 3 0)
Then ... profit.
Where profit could be this:
#lang racket
(define example #(3 1 4 5 10 23 1 50 0 12 40 12 43 20))
(define (prefix-sums xs)
(define-values (sums sum)
(for/fold ([sums '()] [sum 0]) ([x xs])
(values (cons sum sums) (+ sum x))))
(list->vector (reverse (cons sum sums))))
(define (sum4 xs i)
(- (vector-ref xs (+ i 4))
(vector-ref xs i)))
(define (sum4s xs)
(for/list ([i (- (vector-length xs) 4)])
(sum4 (prefix-sums xs) i)))
(apply max (sum4s example))
For a more generic approach, here's a sequence constructor that returns a sliding window of len elements from a vector, len values at a time, which can then be used with for comprehensions:
(define (in-vector-window v len)
(make-do-sequence
(lambda ()
(values
(lambda (i) (vector->values v i (+ i len)))
add1
0
(lambda (i) (<= (+ i len) (vector-length v)))
#f
#f))))
And some example usages:
> (for/list ([(a b c d) (in-vector-window example 4)]) (list a b c d))
'((3 1 4 5) (1 4 5 10) (4 5 10 23) (5 10 23 1) (10 23 1 50) (23 1 50 0) (1 50 0 12) (50 0 12 40) (0 12 40 12) (12 40 12 43) (40 12 43 20))
> (define sums (for/list ([(a b c d) (in-vector-window example 4)]) (+ a b c d)))
> (foldl max (car sums) (cdr sums))
115

scheme display the perfect squares

I'm trying to make a function that takes one argument and uses a combination of map, apply and/or filter to return only the numbers that are perfect squares. For example.
> (perfect-squares `(1 2 3 4 5 6 7 8 9))
(1 4 9)
> (perfect-squares '(15 16 17 24 25 26 25))
(16 25 25)
> (perfect-squares '(2 3 5 6))
()
I manage to do this something similar, but instead of displaying the numbers that are perfect squares, displays the one that are not. Also, I can't get my head around on the implementation of map, apply and filter. This is what have so far.
(define (perfect-squares li)
(cond
((null? li) '())
((integer? (sqrt (car li)))
(perfect-squares (cdr li)))
(else
(cons (car li) (perfect-squares (cdr li)))
)
)
)
It's easiest to separate the task into sub-tasks. Here is a function that recognizes squares, based on the logic you gave:
(define (square? n) (integer? (sqrt n)))
Then you can use filter to identify the squares:
> (filter square? '(1 2 3 4 5 6 7 8 9))
(1 4 9)
Your program is backwards. You should recur when the number is not a square, and cons it to the accumulating output when it is:
(define (perfect-squares li)
(define (perfect-squares-helper li result)
(cond ((null? li) result)
((integer? (sqrt (car li)))
(perfect-squares-helper (cdr li) (cons (car li) result)))
(else (perfect-squares-helper (cdr li) result))))
(perfect-squares-helper li '()))
Note that this returns the result in reverse order, which is characteristic of this method of accumulating the result in a list:
> (perfect-squares '(1 2 3 4 5 6 7 8 9))
(9 4 1)
By the way, your method of placing closing parentheses on separate lines is universally shunned by experienced Scheme programmers. Just stack them up at the end of the last line of code.
EDIT: In a comment, Renato asks how to use map, filter and apply inside the function. We don't need map or apply, but here is the function using filter:
(define (perfect-squares xs)
(define (square? x)
(integer? (sqrt x)))
(filter square? xs))
> (perfect-squares '(1 2 3 4 5 6 7 8 9))
(1 4 9)

Creating a list of lists in Racket

I am new to Racket programming, and I am working on a problem where I am given a list of numbers, and I have to make a list of list, of different combinations of numbers.
Something like :
(combine (list 3 1 2)) => (list
(list 31 32 33)
(list 21 22 3)
(list 11 12 13))
How do I achieve this in Racket?
Thank You
Just play with iterators and comprehension to implement a cartesian product that returns lists of lists, and a bit of arithmetic to obtain the right results. Try this:
(for/list ((i '(3 2 1)))
(for/list ((j '(1 2 3)))
(+ (* 10 i) j)))
Or alternatively, using more standard constructs (available in student languages):
(map (lambda (i)
(map (lambda (j)
(+ (* 10 i) j))
'(1 2 3)))
'(3 2 1))
Either way, it works as expected:
=> '((31 32 33) (21 22 23) (11 12 13))

Expanded form of fold in Racket

Example from http://www.cse.unsw.edu.au/~en1000/haskell/hof.html :
(foldr / 7 (list 34 56 12 4 23))
(foldl / 7 (list 34 56 12 4 23))
Output in Racket:
5 193/196
5 193/196
What would be the full (expanded) form of foldl and foldr in this case? It is not the following:
> (/ (/ (/ (/ (/ 7 34) 56) 12) 4) 23)
1/300288
Edit: I have modified above question since implementation of fold in Racket vs Haskell has been explained in another question Why is foldl defined in a strange way in Racket?.
Edit: If I understand the answers clearly, the expanded form can be shown very clearly using "threading" module, where statements appear in order of execution (_ indicates output of previous statement):
foldl:
(require threading)
; expanded form of (foldl / 7 (list 34 56 12 4 23))
; FROM LEFT TO RIGHT:
(~> 7
(/ 34 _)
(/ 56 _)
(/ 12 _)
(/ 4 _)
(/ 23 _) )
foldr:
; expanded form of (foldr / 7 (list 34 56 12 4 23))
; FROM RIGHT TO LEFT:
(~> 7
(/ 23 _)
(/ 4 _)
(/ 12 _)
(/ 56 _)
(/ 34 _) )
The output in both cases is same:
5 193/196
5 193/196
It gives correct answers (which are different for foldl and foldr) in following example also:
; FROM LEFT TO RIGHT:
(foldl - 0 '(1 2 3 4))
(~> 0
(- 1 _) ; 1-0=1
(- 2 _) ; 2-1=1
(- 3 _) ; 3-1=2
(- 4 _)) ; 4-2=2
; FROM RIGHT TO LEFT:
(foldr - 0 '(1 2 3 4))
(~> 0
(- 4 _) ; 4-0=4
(- 3 _) ; 3-4=-1
(- 2 _) ; 2-(-1)=3
(- 1 _)) ; 1-3=-2
Output:
2
2
-2
-2
In common language, it seems:
The sent function takes 2 arguments,
the first argument is from the list, one after the other
(left to right or right to left depending on foldl and foldr),
the second argument is init first and
then the output of previous calculation.
In DrRacket, press the right mouse button on foldl and choose "Open defining file" In the provide list right click again and choose "Jump to the next bound occurance". You'll see this:
(define foldl
(case-lambda
[(f init l)
(check-fold 'foldl f init l null)
(let loop ([init init] [l l])
(if (null? l) init (loop (f (car l) init) (cdr l))))]
[(f init l . ls)
(check-fold 'foldl f init l ls)
(let loop ([init init] [ls (cons l ls)])
(if (pair? (car ls)) ; `check-fold' ensures all lists have equal length
(loop (apply f (mapadd car ls init)) (map cdr ls))
init))]))
However since you only have one list it's the first term in case lambda that is the current and the fist line checks arguments and throw exceptions. You can simplify it to:
(define (foldl f init l)
(let loop ([init init] [l l])
(if (null? l)
init
(loop (f (car l) init) (cdr l))))
Using substitution rules:
(foldl / 7 '(34 56 12 4 23)) ;==>
(loop 7 '(34 56 12 4 23)) ;==>
(loop (/ (car '(34 56 12 4 23)) 7) (cdr '(34 56 12 4 23))) ;==>
(loop (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)) (cdr '(56 12 4 23))) ;==>
(loop (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))) (cdr '(12 4 23))) ;==>
(loop (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)))) (cdr '(4 23))) ;==>
(loop (/ (car '(23)) (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))))) (cdr '(23))) ;==>
(/ (car '(23)) (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))))) ;==>
(/ 23 (/ 4 (/ 12 (/ 56 (/ 34 7))))) ;==>
5 193/196
I'll leave the foldr one as an exercise.
About folds and standards
The folds in #!racket are racket specific. In Scheme, more precisely #!r6rs you have fold-left and fold-right and unlike #!racket the argument order from a left to a right changes making it more similar to the *new Haskell version.
SRFI-1 list library uses the names fold and foldr and expect the same argument order for both, just like #!racket. SRFI-1 also supports different length lists and stops at the shortest one so it is the one with most features. SRFI-1 can be included in both #!racket with (require srfi/1)and with #!r6rs. (import (rnrs :1))
Haskell's foldr and foldl are not exactly equivalent to Racket's. Also, div is integer division, so you should use quotient in Racket. But even then,
(foldr quotient 7 (list 34 56 12 4 23)) => 8
(foldl quotient 7 (list 34 56 12 4 23)) => quotient: undefined for 0
You could read the documentation carefully on how foldl and foldr work, but I like to refer to the docs for the teaching languages:
(foldr f base (list x-1 ... x-n)) = (f x-1 ... (f x-n base))
(foldl f base (list x-1 ... x-n)) = (f x-n ... (f x-1 base))
So it becomes
(quotient 34 (quotient 56 (quotient 12 (quotient 4 (quotient 23 7)))))
(quotient 23 (quotient 4 (quotient 12 (quotient 56 (quotient 34 7)))))

Resources