First time here? Check out the FAQ!
x

How to calculate closest Prime?

0 votes
484 views

Over at the SignalSymbol Lab I am working on overlapping things. I would like to round to the nearest Prime number. I have written this code.

"round to nearest prime"
| i |
i := 40.
[(i ceiling) isPrime]
whileFalse: [i := i + 1].
i

which works well. But when I try to compile it with

(?NumberVoices / ?VoiceNumber) ceiling as the starting value of i , Kyma gives me an error.

Is there another way to do it?
 

 

asked Sep 8, 2015 in Capytalk & Smalltalk by cristian-vogel (Master) (8,460 points)
edited Sep 8, 2015 by cristian-vogel
by the way.... whats the markup for formatting code snippets in this Q&A forum?
We used the quote option below.

1 Answer

0 votes

Because of the order of evaluation and value substitution during parameter compiling, the algorithm you are trying to use cannot work with green variables.

Here is a variation that will work:

"round to nearest prime"
(?NumberVoices / ?VoiceNumber) of:
    { | lastPrime backwardsList |
    lastPrime := 97.
    backwardsList :=
        (100 to: 1 by: -1) collect: [ :x |
            x isPrime ifTrue: [lastPrime := x].
            lastPrime].
    backwardsList reverse}

The expression in the curly braces creates an Array containing the next prime greater than or equal to the array index (for example, at index 6 the value is 7), up to an index of 100.

Since of: truncates the index and treats zero as meaning the first index of the Array, you do not need to use ceiling.

answered Sep 8, 2015 by ssc (Savant) (128,200 points)
Thanks! Thats cool. I love SmallTalk/Capytalk combo solutions.

Could you shed some light on why the collection is compiled backwards?
Since you want the next largest prime, it is simplest to work backward: whenever you encounter a prime you save it and use that as the next largest prime until you encounter another prime.

If you were to work forward, then, for each index, you would have to scan further ahead until you encountered a prime. This would work, but it would be a more complicated algorithm and would take longer for the compiler to evaluate.
Thankyou.

Would it be possible to extend Capytalk with such a command ?
Why not just use an outside program (Mathematica or an online app) to generate a large table of primes, copy it into an array and write a simple lookup function, that would be very fast. Look for the sieve of eratosthenese on google.
By large, maybe the first 2000 or so primes would cover you for any foreseeable program you could write.
...