-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.rb
More file actions
127 lines (106 loc) · 2.35 KB
/
util.rb
File metadata and controls
127 lines (106 loc) · 2.35 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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class Array
def sum
inject( nil ) { |sum,x| sum ? sum+x : x }
end
def diff
self[0] - self[1]
end
def mult
inject( nil ) { |sum,x| sum ? sum*x : x }
end
def prod(b = self)
(0...self.length).map{|i| self[i] * b[i]}
end
def appendprod(c = self)
r = []
self.each{|a| c.each{|b| r.push(a + [b])}}
r
end
def cumsum
sum = 0
self.map{|n| sum = sum + n}
end
def mv_find_all
# Multivariable find_all
@vs = []
def iter(l, r)
if r.length > 1
r[0].each{|n| iter(l + [n], r[1..-1]){|n| yield n}}
else
r[0].each{|n| v = l + [n]; @vs.push(v) if yield v}
end
end
iter([], self){|n| yield n}
@vs
end
def explode
r = self[0].map{|n| [n]}
s = self[1..-1]
while s.length > 0
r = r.appendprod(s[0])
s = s[1..-1]
end
r
end
def counts
# Count occurrence of each element and return as a dict
d = {}
self.each{|n| d[n] = ((d.member?n) ? d[n] : 0) + 1}
d
end
end
class Integer
def factors
n = self
div = 2
factors = []
while n > 1
while n % div == 0
n /= div
factors.push(div)
end
div += 1
end
factors
end
def divisors
maxcheck = (self ** 0.5).floor
divs = (1..maxcheck).find_all{|d| self % d == 0}
invdivs = divs.map{|d| self / d}
invdivs.pop if invdivs.last == maxcheck # Avoid double-counting the square root
divs.concat(invdivs.reverse)
end
def proper_divisors
self.divisors[0...-1]
end
@@was_prime = {}
def is_prime
return false if self <= 1
return @@was_prime[self] if @@was_prime.key?self
maxcheck = (self ** 0.5).floor
@@was_prime[self] = false # This is worse than not being thread-safe
(2..maxcheck).each{|n| return false if self % n == 0}
@@was_prime[self] = true
end
def is_even
self & 1 == 0
end
def is_odd
self & 1 == 1
end
def digits
self.to_s.split('').map{|c| c.to_i}
end
def factorial
return 1 if self <= 1
self * (self - 1).factorial
end
def is_square
# This is probably not a perfect implementation, but seems to work somewhat - depends greatly on how (** 0.5) is implemented in terms of rounding and accuracy.
(self ** 0.5).floor ** 2 == self
end
def palindrome?
s = self.to_s
s == s.reverse
end
end