
# Me encanta redefinir clases. MWAHAHAHAHAHAHAHAHAHA, HEY! MOSKAU[1]
#[1] Quien no conozca la canción de Dschinghis Khan no merece la vida.
class String
  
  # Dice si el número es reversible. Aunque no comprueba que es un número.
  def reversible?
    res = true
    CONFUSIONS[:reverse].each_key do |key| # Comprueba que no tiene ningún caracter cuyo array de confusiones al revés sea vacío.
      res = res && (!(self[key.to_s])) if CONFUSIONS[:reverse][key].empty?
    end
    res
  end
  
  # Calcula la cadena menos el primer caracter.
  def little
    self[1..-1]
  end
end

# Posibles confusiones.
CONFUSIONS =  {
                :straight =>  {
                                :"0" => [0,8],
                                :"1" => [1,7],
                                :"2" => [2],
                                :"3" => [3,8],
                                :"4" => [4],
                                :"5" => [5],
                                :"6" => [6],
                                :"7" => [7,1],
                                :"8" => [8,0,3],
                                :"9" => [9]
                              },
                              
                :reverse =>   {
                                :"0" => [0,8],
                                :"1" => [1,7],
                                :"2" => [7],
                                :"3" => [8],
                                :"4" => [],
                                :"5" => [],
                                :"6" => [9],
                                :"7" => [1,2],
                                :"8" => [8,0,3],
                                :"9" => [6],
                              }
              }

# Función auxiliar.
# Es recursiva. Si el número dado tiene un sólo dígito, devuelve sus posibles confusiones.
# Si es de más, calcula las confusiones de number.little y las combina con sus propias confusiones.
def confused_with_aux(number, con = CONFUSIONS[:straight])
  if number.size == 1
    con[number.to_sym]
  else
    res = []
    aux = confused_with_aux(number.little,con) # Mi odiada recursión!!!
    
    # Se combinan los resultados de la recursión con las confusiones posibles del primer caracter.
    con[number[0..0].to_sym].each do |x|
      aux.each do |y|
        res << x.to_s + y.to_s
      end
    end
    res
  end
end

# Función principal. Calcula las confusines al derecho y, de ser necesario, al revés.
def confused_with(number)
  res = confused_with_aux(number)
  res = res + confused_with_aux(number.reverse,CONFUSIONS[:reverse]) if number.reversible?
  res.sort.uniq # Se ordena y se eliminan duplicados.
end

# Se comprueban los parámetros.
if ARGV.size == 0 || ARGV.size > 1 || (ARGV[0].to_i.to_s != ARGV[0])
  puts "Usage:"
  puts "${0} number"
  exit -1
end
res = confused_with(ARGV[0])

puts "Posibles números (#{res.size}): "+res.join(", ")
