-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprime.rb
More file actions
65 lines (52 loc) · 2 KB
/
prime.rb
File metadata and controls
65 lines (52 loc) · 2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/env ruby
def calculateTableOfSquares(list)
return list.map {|x| list.map {|y| x * y}}
end
# Returns the list of minimum column widths for table.
def calculatePaddingForNumericTable(table)
return table.transpose().map {|x| String(x.max).length}
end
# Prefixes each row in table with specified header.
def insertRowPrefixes(table, headers)
return headers.zip(table).map {|header, row| ([header] << row).flatten}
end
def getFormatStringForPadding(rowPadding)
return rowPadding.map {|x| "%#{x}s"}.join(" ")
end
def getTableOfSquares(list)
table = insertRowPrefixes(calculateTableOfSquares(list), list)
columnWidths = calculatePaddingForNumericTable(table)
# Add the header row, with a prefixed blank column for alignment.
table = table.unshift(list.unshift(""))
formatString = getFormatStringForPadding(columnWidths)
return table.map {|row| formatString % row }.join("\n")
end
=begin
Based on the Sieve of Eratosthenes but modified to be incremental.
Rather than searching to a fixed upper bound, we compute and discard composite numbers lazily,
using iterators that track each prime number we find. Iterators are keyed on their next
multiple in an associative array and advanced by their prime when that number is checked.
=end
def firstNPrimes(n)
result = []
# Set a default creator for when keys are not found.
iterators = Hash.new {|hash, key| hash[key] = []}
# Our first prime number.
p = 2
while result.length < n
iteratorsAtP = iterators[p]
iterators.delete(p);
if (0 == iteratorsAtP.length)
# Never touched so must be prime, add it to the iterators.
iterators[p * p] << p
result << p
else
# Cannot be prime if reached by an iterator. Advance our iterators
# to their next composites.
iteratorsAtP.each {|x| iterators[p + x] << x}
end
p = p + 1
end
return result
end
puts getTableOfSquares(firstNPrimes(10))