The sieve of Sundaram: Difference between revisions
Content added Content deleted
(Added AppleScript.) |
|||
Line 414: | Line 414: | ||
{{Out}} |
{{Out}} |
||
<pre>First 100 Sundaram primes (starting at 3): |
<pre>First 100 Sundaram primes (starting at 3): |
||
3 5 7 11 13 17 19 23 29 31 |
|||
37 41 43 47 53 59 61 67 71 73 |
|||
79 83 89 97 101 103 107 109 113 127 |
|||
131 137 139 149 151 157 163 167 173 179 |
|||
181 191 193 197 199 211 223 227 229 233 |
|||
239 241 251 257 263 269 271 277 281 283 |
|||
293 307 311 313 317 331 337 347 349 353 |
|||
359 367 373 379 383 389 397 401 409 419 |
|||
421 431 433 439 443 449 457 461 463 467 |
|||
479 487 491 499 503 509 521 523 541 547</pre> |
|||
=={{header|JavaScript}}== |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// ----------------- SUNDARAM PRIMES ----------------- |
|||
// sundaramsUpTo :: Int -> [Int] |
|||
const sundaramsUpTo = n => { |
|||
const |
|||
m = Math.floor(n - 1) / 2, |
|||
excluded = new Set( |
|||
enumFromTo(1)( |
|||
Math.floor(Math.sqrt(m / 2)) |
|||
) |
|||
.flatMap( |
|||
i => enumFromTo(i)( |
|||
Math.floor((m - i) / (1 + (2 * i))) |
|||
) |
|||
.flatMap( |
|||
j => [(2 * i * j) + i + j] |
|||
) |
|||
) |
|||
); |
|||
return enumFromTo(1)(m).flatMap( |
|||
x => excluded.has(x) ? ( |
|||
[] |
|||
) : [1 + (2 * x)] |
|||
); |
|||
}; |
|||
// nSundaramsPrimes :: Int -> [Int] |
|||
const nSundaramPrimes = n => |
|||
sundaramsUpTo( |
|||
// Probable limit |
|||
Math.floor((2.4 * n * Math.log(n)) / 2) |
|||
) |
|||
.slice(0, n); |
|||
// ---------------------- TEST ----------------------- |
|||
const main = () => ( |
|||
xs => [ |
|||
"First hundred Sundaram primes", |
|||
"(starting at 3):", |
|||
`\n${xs}` |
|||
].join("\n") |
|||
)( |
|||
table(" ")( |
|||
chunksOf(10)( |
|||
nSundaramPrimes(100) |
|||
.map(n => `${n}`) |
|||
) |
|||
) |
|||
); |
|||
// --------------------- GENERIC --------------------- |
|||
// enumFromTo :: Int -> Int -> [Int] |
|||
const enumFromTo = m => |
|||
n => Array.from({ |
|||
length: 1 + n - m |
|||
}, (_, i) => m + i); |
|||
// --------------------- DISPLAY --------------------- |
|||
// chunksOf :: Int -> [a] -> [[a]] |
|||
const chunksOf = n => { |
|||
// xs split into sublists of length n. |
|||
// The last sublist will be short if n |
|||
// does not evenly divide the length of xs . |
|||
const go = xs => { |
|||
const chunk = xs.slice(0, n); |
|||
return 0 < chunk.length ? ( |
|||
[chunk].concat( |
|||
go(xs.slice(n)) |
|||
) |
|||
) : []; |
|||
}; |
|||
return go; |
|||
}; |
|||
// table :: String -> |
|||
// (Int -> Char -> String -> String) -> |
|||
// [[String]] -> String |
|||
const table = gap => |
|||
// A tabulation of rows of string values, |
|||
// with a specified gap between columns. |
|||
rows => { |
|||
const |
|||
lastRow = rows[rows.length - 1], |
|||
w = lastRow[lastRow.length - 1].length; |
|||
return rows.map( |
|||
row => row.map( |
|||
justifyRight(w)(" ") |
|||
).join(gap) |
|||
).join("\n"); |
|||
}; |
|||
// justifyRight :: Int -> Char -> String -> String |
|||
const justifyRight = n => |
|||
// The string s, preceded by enough padding (with |
|||
// the character c) to reach the string length n. |
|||
c => s => Boolean(s) ? ( |
|||
s.padStart(n, c) |
|||
) : ""; |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>First hundred Sundaram primes |
|||
(starting at 3): |
|||
3 5 7 11 13 17 19 23 29 31 |
3 5 7 11 13 17 19 23 29 31 |