require 'set'
class Array
def delete_fi
x = select { |v| v if yield(v) }
delete_if { |v| v if yield(v) }
x.empty? ? nil : x
end
def next!(n=1)
n.times do
push(shift)
end
if block_given?
y = yield(first)
y
else
self
end
end
def expand
x = (first..last).to_a
if block_given?
x.collect { |x| yield(x) }
else
x
end
end
def shuffle!
each_index do |i|
j = rand(length-i) + i
self[j], self[i] = self[i], self[j]
end
end
def pick(n=1)
y = Set.new
until y.size == n
t = self[rand(size)]
y.add(t)
end
y.to_a
y.to_a.first if n == 1
end
def to_matrix
row = first
col = last
if block_given?
x = Array.new(row) { Array.new(col) { yield } }
else
x = Array.new(row) { Array.new(col,0) }
end
x
end
def each_coordinate
each_with_index do |row,x|
row.each_with_index do |col,y|
yield(x,y)
end
end
end
def mx_lookup(row,col)
if row < 0 || col < 0
nil
else
self[row][col]
end
end
def mx_assign(row,col,val)
self[row][col] = val
end
def mx_update(row,col,new_val)
self[row][col] = new_val
end
end
class Hash
def delete_fi
x = select { |k,v| yield(k,v) }
delete_if { |k,v| yield(k,v) }
x.empty? ? nil : x
end
def collect
x = select { |k,v| yield(k,v) }
h = x.inject({}) { |h,v| h.update x.first => x.last }
h
end
end
class Range
def pick(n=1)
y = []
x = [first,last].expand
n.times { y << x[rand(x.size)] }
y
y.first if n == 1
end
end