Racket: sliding window over a vector - scheme

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

Related

Creating an evaluate function in racket

Example of what function should do:
(list 3 4 6 9 7) ←→ 3x^4 + 4x^3 + 6x^2 + 9x + 7
What I have so far:
(define (poly-eval x numlist)
(compute-poly-tail x numlist 0 0))
(define (compute-poly-tail xn list n acc)
(cond
[(null? list) acc]
[else (compute-poly-tail (first list) (rest list)
(+ acc (* (first list) (expt xn n))) (+ n 1))]))
(check-expect(poly-eval 5 (list 1 0 -1)) 24)
(check-expect(poly-eval 0 (list 3 4 6 9 7)) 7)
(check-expect(poly-eval 2 (list 1 1 0 1 1 0)) 54)
Expected results:
(check-expect(poly-eval 5(list 1 0 -1)) 24)
(check-expect(poly-eval 0 (list 3 4 6 9 7))7)
(check-expect(poly-eval 2 (list 1 1 0 1 1 0)) 54)
I am getting a run-time error. Can someone spot what I am doing wrong. I don't know why I am getting these results.
There are a couple of errors in the code:
You need to process the coefficient's list in the correct order, corresponding to their position in the polynomial! you can either:
reverse the list from the beginning and process the coefficients from right to left (simpler).
Or start n in (sub1 (length numlist)) and decrease it at each iteration (that's what I did).
The order and value of the arguments when calling the recursion in compute-poly-tail is incorrect, check the procedure definition, make sure that you pass along the values in the same order as you defined them, also the first call to (first list) doesn't make any sense.
You should not name list a parameter, this will clash with the built-in procedure of the same name. I renamed it to lst.
This should fix the issues:
(define (poly-eval x numlist)
(compute-poly-tail x numlist (sub1 (length numlist)) 0))
(define (compute-poly-tail xn lst n acc)
(cond
[(null? lst) acc]
[else (compute-poly-tail xn
(rest lst)
(- n 1)
(+ acc (* (first lst) (expt xn n))))]))
It works as expected:
(poly-eval 5 (list 1 0 -1))
=> 24
(poly-eval 0 (list 3 4 6 9 7))
=> 7
(poly-eval 2 (list 1 1 0 1 1 0))
=> 54
Build power coefficient and unknown list than use map function.
; 2*3^1+4*3^0
; input is 3 and '(2 4)
; we need '(3 3) '(2 4) '(1 0)
; use map expt build '(3^1 3^0)
; use map * build '(2*3^1 4*3^0)
; use foldr + 0 sum up
(define (poly-eval x coefficient-ls)
(local ((define power-ls (reverse (build-list (length coefficient-ls) values)))
(define unknown-ls (build-list (length coefficient-ls) (λ (i) x))))
(foldr + 0 (map * coefficient-ls (map expt unknown-ls power-ls)))))

DrRacket - why is this number negative?

So I can not figure out why my numbers are negative in this function. Also, the input for calculate is supposed to be a list of the same 3 if someone could give me a hand with that as well, it would be much appreciated. Thank you.
calculate takes the first number in the list, then multiplies it by the second number in the list and subtracts the third number from the input list.
((calculate '(8 3 7)) '(4 8 2 9)) should return '(29 41 23 44)
(define (calculateHelper n m o L)
(if (null? L) empty
(cons ((calculate n m o) (car L))
(calculateHelper n m o (cdr L)))))
;((calculate 8 3 7) '(4 8 2 9))
(define (calculate n m o)
(lambda (L)
(if (list? L) (calculate n m o L)
(- o (* m (+ n L))))))
Among other things, your subtraction was inverted. This should help:
(define (calculate n m o)
(lambda (L)
(map (lambda (e)
(- (* m (+ n e)) o))
L)))
then
> ((calculate 8 3 7) '(4 8 2 9))
'(29 41 23 44)
EDIT: to call calculate with a list, you could for example use apply to destructure:
(define (calculate nums)
(apply (lambda (n m o)
(lambda (L)
(map (lambda (e)
(- (* m (+ n e)) o))
L)))
nums))
then
> ((calculate '(8 3 7)) '(4 8 2 9))
'(29 41 23 44)

Splitting list into lists of a maximal length

For instance
I want to make a list which has 20 numbers showed below. separate
(list 1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20)
into list of list which contains 10 numbers in each list. just like below
(list (list 1 2 3 4 5 6 7 8 9 10)
(list 11 12 13 14 15 16 17 18 19 20))
what is the best way to do this?
//Sorry for my poor English.
(define (take n xs)
(if (or (= n 0)
(null? xs) )
'()
(cons (car xs)
(take (- n 1)
(cdr xs) ))))
(define (drop n xs)
(if (or (= n 0)
(null? xs) )
xs
(drop (- n 1)
(cdr xs) )))
(define (split n xs)
(if (null? xs) '()
(cons (take n xs)
(split n (drop n xs)) )))
(display
(split 3 (list 1 2 3 4 5)) ) ; `((1 2 3) (4 5))`
Alternative split definition, elimination of wrapper recursion using named let:
(define (split n xs)
(let spl ((xs' xs)) ; Named let
(if (null? xs') '()
(cons (take n xs')
(spl (drop n xs')) ))))

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

translate a matrix in scheme

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

Resources