-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstd++.rb
66 lines (59 loc) · 1.77 KB
/
std++.rb
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
# frozen_string_literal: true
module Enumerable
# Checks if the given enumerable is a non-strict monotonic sequence.
#
# @return [Boolean] `true` if the enumerable is monotonic, `false` otherwise.
#
# @example
# [1, 2, 3].monotonic? # => true
# [3, 2, 1].monotonic? # => true
# [1, 1, 1].monotonic? # => true
# [1, 3, 2].monotonic? # => false
def monotonic?
dir = 0
each_cons(2) do |a, b|
d = b <=> a
dir = d if dir.zero?
return false if !d.zero? && dir != d
end
true
end
# Divides the enumerable into three parts: elements before, current element, and elements after.
# Yields each partition to the block.
#
# @example
# [1,2,3].partitions.to_a #=> [[[], 1, [2, 3]], [[1], 2, [3]], [[1, 2], 3, []]]
#
# @yieldparam left [Array] The elements before the current element.
# @yieldparam current [Object] The current element.
# @yieldparam right [Array] The elements after the current element.
# @return [Enumerator] if no block is given.
def partitions
return enum_for(:partitions) unless block_given?
each_with_index do |current, index|
left = lazy.take(index)
right = lazy.drop(index + 1)
yield [left, current, right]
end
end
end
class Integer
def length
Math.log10(self).floor + 1
end
def end_with?(other)
return (self - other) % 10 ** other.length == 0
end
end
class Array
# Returns the middle element(s) of the array.
# If the array has an odd size, returns an array with one element.
# If the array has an even size, returns an array with two elements.
# If the array is empty, returns itself.
#
# @return [Array] the middle element(s).
def middle
return self if empty?
size.odd? ? self[size / 2, 1] : self[(size / 2) - 1, 2]
end
end