viernes, 25 de noviembre de 2016

Euler #23

A partir de ahora, voy a intentar resolver cada problema utilizando un lenguaje con el que no esté familiarizado. Hoy toca Ruby, que lo empecé a cacharrear hace 15 años, pero no profundicé mucho en su día. Cuando apareció Ruby On Rails yo ya estaba en otra cosa...

Vamos allá con el problema: https://projecteuler.net/problem=23

Como comentaba, no estoy familiarizado con Ruby, seguro que en este código estoy haciendo cosas sin utilizar los modismos del lenguaje, pero bueno, allá va:

#!/usr/bin/env ruby

$divisors_precalculated = []

def divisors_sum number
  if $divisors_precalculated[number] != nil
    return $divisors_precalculated[number] 
  end
  sum = 0
  i = 1
  max = number / 2
  while i <= max
    if number % i == 0
      sum += i
    end
    i += 1
  end
  $divisors_precalculated[number] = sum
  return sum
end

def is_abundant number
  return divisors_sum(number) > number
end

total = 0

for current_number in 1..28123
  is_sum_of_two_abundant_numbers = false
  fist_half = current_number - 1
  second_half = 1
  while second_half <= fist_half
    if is_abundant(fist_half) and is_abundant(second_half)
      is_sum_of_two_abundant_numbers = true
      break
    end
    fist_half -= 1
    second_half += 1
  end
  if !is_sum_of_two_abundant_numbers
    puts current_number.to_s + ' cannot be written as the sum of two abundant numbers'
    total += current_number
  end
end

puts "Result: " + total.to_s

Lo único relevante en el problema es lo costoso que es encontrar divisores, así que los vamos guardando en una variable global (la que lleva un $ por delante). Se podría hacer todo dentro de una clase y que esta global pasase a ser una variable miembro de la clase, pero para un problema de este tipo, con el estilo procedimental nos apañamos.

Después lo que hacemos es iterar por los números y para cada uno de ellos, calculamos todas sus posibles sumas y si alguna de ellas es de dos números abundantes, ya no tenemos en cuenta el número.

No hay comentarios:

Publicar un comentario