Skip to content

Instantly share code, notes, and snippets.

@kachick
Created January 24, 2012 17:57
Show Gist options
  • Save kachick/1671529 to your computer and use it in GitHub Desktop.
Save kachick/1671529 to your computer and use it in GitHub Desktop.
"Hit and Blow" an approach to http://vipprog.net/wiki/exercise.html#ffeaab60
# an approach to
# * http://vipprog.net/wiki/exercise.html#ffeaab60
# tested Ruby 1.9.3
$VERBOSE = true
class Array
def uniq?
dup.uniq!.nil?
end
end
Answer = Struct.new :hit, :bolow do
def initialize(*args)
@rights = args.pop
super(*args)
end
def to_s
each_pair.select{|k, v|v > 0}.map{|k, v|[v, k].join}.join(' ')
end
def correct?
hit == @rights.length
end
end
LENGTH = 4
until (rights = LENGTH.times.map{rand(9) + 1}; rights.uniq?)
end
puts "Can you guess the number that I'm thinking of?"
loop do
result = Answer.new 0, 0, rights
begin
puts "Input #{LENGTH} unique numbers"
numbers = gets.chomp.chars.map{|s|Integer s}
raise ArgumentError unless numbers.length == rights.length
raise ArgumentError unless numbers.uniq?
rescue
retry
else
numbers.each_with_index do |number, index|
case rights.index(number)
when index
result.hit += 1
when Fixnum
result.bolow += 1
end
end
puts result
break if result.correct?
end
end
puts 'Great!'
#!/usr/bin/ruby -w
class Array
def uniq?
dup.uniq!.nil?
end
end
class Answer
def self.generate(length)
raise ArgumentError unless length >= 2
until (numbers = length.times.map{rand(9) + 1}; numbers.uniq?)
end
numbers
end
def initialize(yours, length)
@yours, @rights, @counts = yours, self.class.generate(length), nil
raise ArgumentError unless @yours.length == @rights.length
raise ArgumentError unless @yours.uniq?
end
def to_s
[].tap {|r|
r << "#{hit}hit" if hit > 0
r << "#{blow}blow" if blow > 0
}.join(' ')
end
def correct?
@yours == @rights
end
def hit
counts[:hit]
end
def blow
counts[:blow]
end
private
def counts
@counts ||= Hash.new(0).tap {|r|
@yours.each_with_index do |number, index|
case @rights.index(number)
when index
r[:hit] += 1
when Fixnum
r[:blow] += 1
end
end
}
end
end
begin
puts "Input length"
length = Integer gets
rescue
retry
else
end
loop do
begin
puts "Input #{length} unique numbers"
numbers = gets.chomp.chars.map{|s|Integer s}
answer = Answer.new numbers, length
rescue
retry
else
puts answer
break if answer.correct?
end
end
puts 'You Great'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment