1( import ( chezscheme ) )
2
3
4 ( define ( bigger a b )
5 ( if ( > a b )
6 a
7 b
8 )
9 )
10
11 ( define ( smaller a b )
12 ( if ( < a b )
13 a
14 b
15 )
16 )
17
18
19 ( define ( square x ) ( * x x ) )
20
21
22
23
24 ( define ( sum-of-squares a b )
25 ( + ( square a ) ( square b ) )
26 )
27
28
29
30
31 ( define ( bigger-sum-of-squares a b c )
32 ( sum-of-squares ( bigger a b ) ( bigger( smaller( a b
) ) c ) )
33 )
34
35
36 bigger-sum-of-squares( 1 3 7 )
37
/* I install Chez Scheme Version 9.5.6
When I use this command to compile : chez bigger.ss,
it will happen: "Exception: attempt to apply non-procedure
1"
I try many times ,but still not solve it , who can tell me
where's bug ?
*/
Here is the code conventionally formatted, with corrected (probably) parentheses:
(define (bigger a b)
(if (> a b)
a
b))
(define (smaller a b)
(if (< a b)
a
b))
(define (square x)
(* x x))
(define (sum-of-squares a b)
(+ (square a) (square b)))
(define (bigger-sum-of-squares a b c)
(sum-of-squares (bigger a b) (bigger (smaller a b) c)))
(bigger-sum-of-squares 1 3 7)
The error "Exception: attempt to apply non-procedure 1" results from
bigger-sum-of-squares( 1 3 7 ) -- the Scheme processor interprets
(1 3 7) as a procedure application (like (+ 3 7)), but 1 is
not a procedure.
For testing, the code can be copied from an editor and pasted into a terminal:
% scheme
Chez Scheme Version 9.5.7.6
Copyright 1984-2021 Cisco Systems, Inc.
> (define (bigger a b)
(if (> a b) a b ))
> (define (smaller a b)
(if (< a b) a b ))
> (define (square x)
(* x x))
> (define (sum-of-squares a b)
(+ (square a) (square b)))
> (define (bigger-sum-of-squares a b c)
(sum-of-squares (bigger a b) (bigger (smaller a b) c)))
> (bigger-sum-of-squares 1 3 7)
58
>
...or the definitions in a file can be loaded into Chez Scheme's
interaction environment:
% scheme
Chez Scheme Version 9.5.7.6
Copyright 1984-2021 Cisco Systems, Inc.
> (load "bigger.ss")
> (bigger-sum-of-squares 1 3 7)
58
>
I found it's can running ,when use chez bigger.ss , then running function :(bigger-sum-of-squares 1 2 3 ), it will appear the result.
Related
I've been trying to solve the seventh Euler Project problem. My program looks like this:
(define (add-prime c)
(define (smallest-divisor n) (find-divisor n 2))
(define (find-divisor n test-divisor)
(cond
((> (* test-divisor test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else
(find-divisor n (+ test-divisor 1)))))
(define (divides? a b) (= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
(if (prime? (+ c 1))
(+ c 1)
(add-prime (+ c 1))))
(define (pv v c)
(if (= c (vector-length v))
v
(begin
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
(pv v (+ c 1)))))
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display v))
The output looks like this:
In procedure add-prime:
In procedure +: Wrong type argument in position 1: #<unspecified>
I'm very confused. By itself, the add-prime procedure works correctly, it's just that when I combine it to create a vector containing 10,002 prime numbers, it returns this error.
You initialize your vector only at the address 0
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
but then you go on filling it starting from the address 3
(pv prime-vec 3)
=
(let ((v prime-vec) (c 3))
....
(vector-set! v c
(add-prime (vector-ref v (- c 1))))
....
=
....
(vector-set! prime-vec 3
(add-prime (vector-ref prime-vec 2)))
....
but you haven't initialized the contents of the vector at the address 2, yet.
Racket uses the value 0 for the uninitialized addresses evidently, but your implementation apparently isn't and instead has #<unspecified> there, causing the error.
Start filling the vector from address 1, instead of 3, and it should fix the error.
As a side note, add-prime is really next-prime. Naming is important, good naming can reduce the cognitive load.
I think there is a typo in your code:
(let ((prime-vec (make-vector 10002)))
(vector-set! prime-vec 0 2)
(pv prime-vec 3)
(display prime-vec)) ;; here you want to print the vector
If I run this program in DrScheme, it gives the following result, which seems kinda fantastic:
#(2 0 0 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 ...)
(defun replace (L z y)
(let ((f (lambda (x)
(if (equal x z)
y x) z y)))
(mapcar f L)))
(replace '(3 1 5 6 3 2 3) 3 9)
(9 9 9 9 9 9 9)
Your lambda always returns y, since you have a z and a y after your if. Change it to drop those and then it works:
(defun replace (L z y)
(let ((f (lambda (x)
(if (equal x z)
y
x))))
(mapcar f L)))
(replace '(3 1 5 6 3 2 3) 3 9)
(9 1 5 6 9 2 9)
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
(define (pascal x y)
(cond ((or (<= x 0) (<= y 0) (< x y )) 0)
((or (= 1 y) (= x y) ) 1)
(else (+ (pascal (- x 1) y) (pascal (- x 1) (- y 1))))))
This is the function I have for a recursive pascal call that should return the number given the x and y of the triangle.
1
11
121
1331
14641
If I enter pascal 0 0, it should return 1, however it returns 0;
If I enter pascal 4 2, it should return 6, but it returns 3;
Seems like my base is off but I'm not sure how I can change it without ruining the calculation for pascals algorithm. Could someone point me to the right direction
You are very close, but your conditions aren't quite doing what you think they are. You have something like an off-by-1 error, and you haven't properly split apart your cond cases.
#lang racket/base
(for ((x (in-range 1 6)))
(for ((y (in-range (add1 x))))
(printf "~a " (pascal x y)))
(newline))
0 1
0 1 1
0 1 2 1
0 1 3 3 1
0 1 4 6 4 1
I make some small changes to your conditions and get this output:
(for ((x (in-range 6)))
(for ((y (in-range (add1 x))))
(printf "~a " (pascal x y)))
(newline))
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
If this doesn't help I can edit later and put the solution in, but this smells like homework and I don't want to just post a solution.
The result of the following expression is 39,how the numbers 7 and 4 are mapped to a and b,because I understand that b is 7 and and a is 4 and I get 27 as a result but the result is 39
(((lambda [a] (lambda [b] (+ (* 5 a) b))) 7) 4)
Here is how it reduces
(((lambda [a] (lambda [b] (+ (* 5 a) b))) 7) 4)
((lambda [b] (+ (* 5 7) b)) 4)
(+ (* 5 7) 4)
39
the first redex is ((lambda [a] ...) 7) so a is bound to 7
the second redex to be reduced is ((lambda [b] ...) 4) so b is bound to 4