class Object
  def in?(arr)
    arr.include? self
  end
end

class Array
  def any_in?(container)
    container.has_any? self
  end

  def all_in?(container)
    container.has_all? self
  end

  def has?(obj)
    self.include? obj
  end

  def has_any?(*arr)
    arr.flatten.any?{ |i| i.in? self }
  end

  def has_all?(*arr)
    arr.flatten.all?{ |i| i.in? self }
  end

  def cut(start=nil, stop=nil, step=1)
    step = 1 if step==0
    if step > 0
      start = 0 if start==nil
      if step == 1
        stop==nil ? self.slice(start..-1) : self.slice(start...stop)
      else
        arr = stop==nil ? self.slice(start..-1) : self.slice(start...stop)
        arr.select{ |x| arr.index(x)%step==0 }
      end
    else
      start = -1 if start==nil
      if step == -1
        stop==nil ? self.reverse.slice(-start-1..-1) : self.reverse.slice(-start-1...-stop-1)
      else
        arr = stop==nil ? self.reverse.slice(-start-1..-1) : self.reverse.slice(-start-1...-stop-1)
        arr.select{ |x| arr.index(x)%step==0 }
      end
    end
  end
end

class String
  def has?(obj)
    self.include? obj
  end

  def has_any?(*arr)
    self.chars.to_a.has_any? *arr
  end

  def has_all?(*arr)
    self.chars.to_a.has_all? *arr
  end

  def cut(start, stop, step)
    self.chars.to_a.cut(start, stop, step).join
  end

  def first(n=1)
    n==1 ? self[0] : self[0...n]
  end

  def last(n=1)
    n==1 ? self[-1] : self[-n..-1]
  end

  def startswith?(obj)
    if obj.is_a?(String)
      self.index(obj) == 0
    elsif obj.is_a?(Array)
      obj.any?{ |i| self.index(i)==0 }
    end
  end

  def endswith?(obj)
    if obj.is_a?(String)
      self.reverse.index(obj.reverse) == 0
    elsif obj.is_a?(Array)
      obj.any?{ |i| self.reverse.index(i.reverse)==0 }
    end
  end
end