for, positive?, negative?, divisible?

Q&A's, tips, howto's
Locked
Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

for, positive?, negative?, divisible?

Post by Kazimir Majorinc »

Few proposals:

* traditional for, so (for(i 2 1) ... body ... ) doesn't evaluate body. For example, I just tried to write program that test prime numbers, and typically it should have the following code:

Code: Select all

(for (i 2 (- n 1)) 
  (if (= (mod n i) 0) ...
but it doesn't work for n=2, it must be treated as a special case. It is not good. Maybe traditional for can be named for*.

* Also, few simple predicates: positive?, negative?, (divisible? i j) All three replace simple phrases, nevertheless, it is easier to think in terms (divisible? i j) than (= (% i j) 0), especially (clean positive? L) instead of (clean (lambda(x)(> x 0)) L)

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: for, positive?, negative?, divisible?

Post by Lutz »

You can use < and > with one parameter for negative? and positive?:

Code: Select all

> (> 1)
true
> (< 1)
nil
> (< -1)
true
> 
 
> (filter > '(1 2 -3 -5 9))
(1 2 9)
> (filter < '(1 2 -3 -5 9))
(-3 -5)
> 
or you could define

Code: Select all

> (constant (global 'negative?) <)

> (filter negative? '(-1 2 -3 4))
(-1 -3)

> (constant (global 'positive?) >)

> (filter positive? '(-1 2 -3 4))
(2 4)
> 

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: for, positive?, negative?, divisible?

Post by cormullion »

Can you use the break condition option for for?

Code: Select all

(for (i 2 1 1 (> i 1)) 
    (println i))
simpler and more attractive than for* ...

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: for, positive?, negative?, divisible?

Post by Lutz »

yes, but I think, he wants it the other way around:

Code: Select all

> (for (i 2 (- 1 1) 1 (< i 2)) (println i))
2
true
> (for (i 2 (- 5 1) 1 (< i 2)) (println i))
2
3
4
so its forced to go upwards only, for his purpose.

Kazimir Majorinc
Posts: 388
Joined: Thu May 08, 2008 1:24 am
Location: Croatia
Contact:

Re: for, positive?, negative?, divisible?

Post by Kazimir Majorinc »

I've seen discussion on prime numbers, so I tried to make the most elegant imperative and functional style program that prints all primes from 2 to 100. For a functional part, I'm quite satisfied:

Code: Select all

(println (clean (lambda(x)
                  (exists zero? (map (curry mod x) 
                                     (chop (sequence 2 x)))))
                (sequence 2 100)))
But for imperative, I'm not. I want something like:

Code: Select all

for n:=2 to 100
  prime:=true
  for j:=2 to n-1
     if (j divides n) then prime:=false
  next j
  println n ": " prime
next n
There shouldn't be special cases.

positive? and negative? are mostly solved with > <. Nice trick.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Re: for, positive?, negative?, divisible?

Post by cormullion »

You could do:

Code: Select all

(dotimes (r 10)
   (dotimes (c 10)
      (if (= 1 (length (factor (set 'n (+ (* r 10) c)))))
          (println n " is prime"))))

kosh
Posts: 72
Joined: Sun Sep 13, 2009 5:38 am
Location: Japan
Contact:

Re: for, positive?, negative?, divisible?

Post by kosh »

Current for macro does same behavior

Code: Select all

(for (i 3 0 +1) (println i))            ; print 3,2,1,0
(for (i 3 0 -1) (println i))            ; print 3,2,1,0
I think it will be work more better like this,

Code: Select all

;; If `for' argument [num-step] no given, variable will increase by default.
(for (i 3 0) (println i))           ; <no output>
(for (i 3 0 +1) (println i))        ; print 3,4,5,... (not reached 0)
(for (i 3 0 -1) (println i))        ; print 3,2,1,0
---
kosh (not good at english...)

Locked