I was impressed when I started going through 1..1000 in under 15 
seconds, so this is much slower than others report. I'm just going to 
tell myself you all have much faster computers, and go to bed.

require 'set'

class Subsets
  def initialize(set, start)
    @set = set.to_a.uniq.sort
    @num_elements = start - 1
    @map = {}
    @set.each_with_index {|k, v| @map[k] = v+1}
  end

  # returns each subset, in turn. Returns nil when there are no more
  def succ
    if @combo == nil or @combo == @set[- / num_elements..-1]
      return nil if (@num_elements +=1) > @set.length
      @combo = @set[0,@num_elements]
    else
      index = (1..@num_elements).find {|i| @combo[-i] < @set[-i]}
      @combo[-index, index] = @set[@map[@combo[-index]], index]
    end
    @combo
  end

  def find
    while(x = succ)
      break if yield x
    end
    x
  end
end

class Integer

  def proper_divisors
    return [] if self < 2
    div = Set.new [1]
    2.upto(Math.sqrt(Float.induced_from(self)).to_i) {|i|
      quotient, modulus = self.divmod(i)
      div.merge([i,quotient]) if modulus.zero?
    }
    div.to_a.sort
  end

  def abundant?
    self > 11 and [0].concat(proper_divisors).inject {|sum,n| sum += n} 
> self
  end

  def semiperfect?
    return nil if self < 6
    subsets = Subsets.new(proper_divisors, 2)
    subsets.find {|subset| [0].concat(subset).inject {|sum,n| sum += n} 
== self }
  end

  def weird?
    self > 69 and abundant? and not semiperfect?
  end
end

n = gets.strip
exit if n =~ /\D/ or n !~ /[^0]/
p (1..n.to_i).find_all {|i| i.weird? }

-- 
Posted via http://www.ruby-forum.com/.