What is the Clojure equivalent of Ruby's select? - ruby

I want to return a list/collection of all numbers in a range that are a multiple of 3 or 5.
In Ruby, I would do
(1..1000).select {|e| e % 3 == 0 || e % 5 == 0}
In Clojure, I'm thinking I might do something like...
(select (mod 5 ...x?) (range 0 1000))

(filter #(or (zero? (mod % 3)) (zero? (mod % 5))) (range 1000))

A different way is to generate the solution, rather than to filter for it:
(set (concat (range 0 1000 3) (range 0 1000 5)))

(filter #(or (= (mod % 5) 0) (= (mod % 3) 0)) (range 1 100))
is the most direct translation.
(for [x (range 1 100) :when (or (= (mod x 5) 0) (= (mod x 3) 0))] x)
is another way to do it.
Instead of doing (= .. 0), you can use the zero? function instead. Here is the amended solution:
(filter #(or (zero? (mod % 5)) (zero? (mod % 3))) (range 1 100))

how about this:
http://gist.github.com/456486

Related

How to do modulo in scheme

How would I do the following in sicp/scheme/dr. racket?
(define (even? n) (= (% n 2) 0))
Currently it seems like that's not a primitive symbol: %: unbound identifier in: %.
This may be the stupidest way in the world to do it, but without a % or bitwise-&1 I am doing (without logs or anything else):
(define (even? n)
(if (< (abs n) 2)
(= n 0)
(even? (- n 2))))
mod is modulo in scheme:
(define (even? n)
(= (modulo n 2) 0))
I think it's a good practice to get comfortable writing your own procedures when it feels like they are "missing". You could implement your own mod as -
(define (mod a b)
(if (< a b)
a
(mod (- a b) b)))
(mod 0 3) ; 0
(mod 1 3) ; 1
(mod 2 3) ; 2
(mod 3 3) ; 0
(mod 4 3) ; 1
(mod 5 3) ; 2
(mod 6 3) ; 0
(mod 7 3) ; 1
(mod 8 3) ; 2
But maybe we make it more robust by supporting negative numbers and preventing caller from divi
(define (mod a b)
(if (= b 0)
(error 'mod "division by zero")
(rem (+ b (rem a b)) b)))
(define (rem a b)
(cond ((= b 0)
(error 'rem "division by zero"))
((< b 0)
(rem a (neg b)))
((< a 0)
(neg (rem (neg a) b)))
((< a b)
a)
(else
(rem (- a b) b))))

Recursive Pascal in Scheme - Unable to find the correct algorithm

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

find sum of the squares of the digits of a number in scheme

I need to write a function in scheme which calculates the sum of square digits.
ex - (sum-of-digits 130)
> 10
This is my function.
(define (sum-of-digits x)
(if (= x 0) 0
(+ (modulo x 10) (sum-of-digits (/ (- x (modulo x 10)) 10)))))
it doesn't work for some numbers. When I entered (sum-of-digits 130) , it returns 4. How can i fix this ?
Also I need to use this function to find the stop numbers which are 0,1,4,16,20,37,42,58,89,145
ex :- (stop? 42)
 #t
(stop? 31)
 #f
How can I do this using the function sum of sum-of-digits above?
You forgot to actually square each digit, and there's a simpler way to obtain the quotient:
(define (sum-of-digits x)
(if (= x 0)
0
(+ (sqr (modulo x 10))
(sum-of-digits (quotient x 10)))))
For the second part of the question:
(define (stop? x)
(let ((sum (sum-of-digits x)))
(if (member sum '(0 1 4 16 20 37 42 58 89 145)) #t #f)))

cosine function calculating scheme

Im making a scheme program that calculates
cos(x) = 1-(x^2/2!)+(x^4/4!)-(x^6/6!).......
whats the most efficient way to finish the program and how would you do the alternating addition and subtraction, thats what I used the modulo for but doesnt work for 0 and 1 (first 2 terms). x is the intial value of x and num is the number of terms
(define cosine-taylor
(lambda (x num)
(do ((i 0 (+ i 1)))
((= i num))
(if(= 0 (modulo i 2))
(+ x (/ (pow-tr2 x (* i 2)) (factorial (* 2 i))))
(- x (/ (pow-tr2 x (* i 2)) (factorial (* 2 i))))
))
x))
Your questions:
whats the most efficient way to finish the program? Assuming you want use the Taylor series expansion and simply sum up the terms n times, then your iterative approach is fine. I've refined it below; but your algorithm is fine. Others have pointed out possible loss of precision issues; see below for my approach.
how would you do the alternating addition and subtraction? Use another 'argument/local-variable' of odd?, a boolean, and have it alternate by using not. When odd? subtract when not odd? add.
(define (cosine-taylor x n)
(let computing ((result 1) (i 1) (odd? #t))
(if (> i n)
result
(computing ((if odd? - +) result (/ (expt x (* 2 i)) (factorial (* 2 i))))
(+ i 1)
(not odd?)))))
> (cos 1)
0.5403023058681398
> (cosine-taylor 1.0 100)
0.5403023058681397
Not bad?
The above is the Scheme-ish way of performing a 'do' loop. You should easily be able to see the correspondence to a do with three locals for i, result and odd?.
Regarding loss of numeric precision - if you really want to solve the precision problem, then convert x to an 'exact' number and do all computation using exact numbers. By doing that, you get a natural, Scheme-ly algorithm with 'perfect' precision.
> (cosine-taylor (exact 1.0) 100)
3982370694189213112257449588574354368421083585745317294214591570720658797345712348245607951726273112140707569917666955767676493702079041143086577901788489963764057368985531760218072253884896510810027045608931163026924711871107650567429563045077012372870953594171353825520131544591426035218450395194640007965562952702049286379961461862576998942257714483441812954797016455243/7370634274437294425723020690955000582197532501749282834530304049012705139844891055329946579551258167328758991952519989067828437291987262664130155373390933935639839787577227263900906438728247155340669759254710591512748889975965372460537609742126858908788049134631584753833888148637105832358427110829870831048811117978541096960000000000000000000000000000000000000000000000000
> (inexact (cosine-taylor (exact 1.0) 100))
0.5403023058681398
we should calculate the terms in iterative fashion to prevent the loss of precision from dividing very large numbers:
(define (cosine-taylor-term x)
(let ((t 1.0) (k 0))
(lambda (msg)
(case msg
((peek) t)
((pull)
(let ((p t))
(set! k (+ k 2))
(set! t (* (- t) (/ x (- k 1)) (/ x k)))
p))))))
Then it should be easy to build a function to produce an n-th term, or to sum the terms up until a term is smaller than a pre-set precision value:
(define t (cosine-taylor-term (atan 1)))
;Value: t
(reduce + 0 (map (lambda(x)(t 'pull)) '(1 2 3 4 5)))
;Value: .7071068056832942
(cos (atan 1))
;Value: .7071067811865476
(t 'peek)
;Value: -2.4611369504941985e-8
A few suggestions:
reduce your input modulo 2pi - most polynomial expansions converge very slowly with large numbers
Keep track of your factorials rather than computing them from scratch each time (once you have 4!, you get 5! by multiplying by 5, etc)
Similarly, all your powers are powers of x^2. Compute x^2 just once, then multiply the "x power so far" by this number (x2), rather than taking x to the n'th power
Here is some python code that implements this - it converges with very few terms (and you can control the precision with the while(abs(delta)>precision): statement)
from math import *
def myCos(x):
precision = 1e-5 # pick whatever you need
xr = (x+pi/2) % (2*pi)
if xr > pi:
sign = -1
else:
sign = 1
xr = (xr % pi) - pi/2
x2 = xr * xr
xp = 1
f = 1
c = 0
ans = 1
temp = 0
delta = 1
while(abs(delta) > precision):
c += 1
f *= c
c += 1
f *= c
xp *= x2
temp = xp / f
c += 1
f *= c
c += 1
f *= c
xp *= x2
delta = xp/f - temp
ans += delta
return sign * ans
Other than that I can't help you much as I am not familiar with scheme...
For your general enjoyment, here is a stream implementation. The stream returns an infinite sequence of taylor terms based on the provided func. The func is called with the current index.
(define (stream-taylor func)
(stream-map func (stream-from 0)))
(define (stream-cosine x)
(stream-taylor (lambda (n)
(if (zero? n)
1
(let ((odd? (= 1 (modulo n 2))))
;; Use `exact` if desired...
;; and see #WillNess above; save 'last'; use for next; avoid expt/factorial
((if odd? - +) (/ (expt x (* 2 n)) (factorial (* 2 n)))))))))
> (stream-fold + 0 (stream-take 10 (stream-cosine 1.0)))
0.5403023058681397
Here's the most streamlined function I could come up with.
It takes advantage of the fact that the every term is multiplied by (-x^2) and divided by (i+1)*(i+2) to come up with the text term.
It also takes advantage of the fact that we are computing factorials of 2, 4, 6. etc. So it increments the position counter by 2 and compares it with 2*N to stop iteration.
(define (cosine-taylor x num)
(let ((mult (* x x -1))
(twice-num (* 2 num)))
(define (helper iter prev-term prev-out)
(if (= iter twice-num)
(+ prev-term prev-out)
(helper (+ iter 2)
(/ (* prev-term mult) (+ iter 1) (+ iter 2))
(+ prev-term prev-out))))
(helper 0 1 0)))
Tested at repl.it.
Here are some answers:
(cosine-taylor 1.0 2)
=> 0.5416666666666666
(cosine-taylor 1.0 4)
=> 0.5403025793650793
(cosine-taylor 1.0 6)
=> 0.5403023058795627
(cosine-taylor 1.0 8)
=> 0.5403023058681398
(cosine-taylor 1.0 10)
=> 0.5403023058681397
(cosine-taylor 1.0 20)
=> 0.5403023058681397

Calculate Sums with accumulate

procedure accumulate is defined like this:
(define (accumulate combiner null-value term a next b)
(if (> a b) null-value
(combiner (term a)
(accumulate combiner null-value term (next a) next b))))
problem 1: x^n
;Solution: recursive without accumulate
(define (expon x n)
(if (> n 0) (* x
(expon x (- n 1))
)
1))
problem 2: x + x^2 + x^4 + x^6 + ...+ ,calculate for given n the first n elements of the sequence.
problem 3: 1 + x/1! + x^2/2! + ... + x^n/n!; calculate the sum for given x,n
possibly incorrect solution:
(define (exp1 x n)
(define (term i)
(define (term1 k) (/ x k))
(accumulate * 1 term1 1 1+ i))
(accumulate + 0 term 1 1+ n))
why the previous code is incorrect:
(exp1 0 3) -> 0 ; It should be 1
(exp1 1 1) -> 1 ; It should be 2
First off, I would say that your EXP1 procedure is operating at too low a level in being defined in terms of ACCUMULATE, and for the sake of perspicacity rewrite it instead in terms of sums and factorials:
(define (sum term a b)
(accumulate + 0 term a 1+ b))
(define (product term a b)
(accumulate * 1 term a 1+ b))
(define (identity x) x)
(define (fact n)
(if (= n 0)
1
(product identity 1 n)))
(define (exp1 x n)
(define (term i)
(/ (expon x i) (fact i)))
(sum term 1 n))
Now to your question: the reason you are getting (EXP1 0 3) → 0 is no more than that you forgot to add the 1 at the start of the series, and are just computing x/1! + x^2/2! + ... + x^n/n!
Changing EXP1 to include the missing term works as expected:
(define (exp1 x n)
(define (term i)
(/ (expon x i) (fact i)))
(+ 1 (sum term 1 n)))
=> (exp1 0 3)
1
=> (exp1 1 1)
2

Resources