5 февраля 2011 г.

Задача «Треугольник Пифагора»

Ну или оригинальное название (http://habrahabr.ru/blogs/python/111898/) - «Double Squares»
Эта задача из Hacker Cup Qualification Round, очень нравится :
Matraska хочет участвовать в Facebook Hacker Cup 2011 (хоть и заочно) и заодно представить решение этой задачи на ruby ибо python-ом автор опуса не орудует, в отличие от авторов оригинальной статьи (ссылка была в начале абзаца).
Автор (Matraska пр. ред.) позволил себе назвать эту задачу, казалось бы таким уже «истертым» названием, потому что увидел в ней скрытый смысл, о котором будет написано далее. А все скрытое неприменно привлекает внимание и побуждает к действию.
И так текст задачи:
«Найти число представлений целого числа в виде суммы двух полных квадратов целых. Диапазон входящих чисел от нуля до 2147483647.»
Рассмотрим задачу на двух пальцах. Пусть  имеется коллекция целых  неотрицательных чисел m; 0, 2, 67 и т. д. и необходимо определить  для каждого числа количество возможных комбинаций вида
c^2=b^2+a^2,
где с, b и а целые положительные числа.
Почему Пифагора — потому что если обозначить c,  a и b как стороны прямоугольного треугольника, то  c будет гипотенузой, a и b — катетами.
Представляю код:
class Pifagor
  # Метод, который возращает корень входного числа если оно имеет целый корень и nil если иначе
  def simple?(input_number)
    # Dy=number -round(sqrt(number))^2
    dy=input_number- Math.sqrt(input_number).floor**2
    dy==0?Math.sqrt(input_number):nil
  end
  def work(number) #number - то число которое раскладываем
    a_limit=self.simple?(number)
    b_limit=0 # a_limit, b_limit определяют диапазон значений a и b для перебора
    i=0 #кол-во комбинаций
    if !a_limit.nil?
      (0..a_limit).each do|a|
        (0..b_limit).each do |b|
          if(a**2+b**2)==number
            puts("a: #{a}, b: #{b}")
            i+=1
          end
        end
        b_limit+=1# Делаем нижне треугольная матрицу [a_limit x b_limit]
      end
    end
    puts("Number: #{i}")
  end
endSyhi-подсветка кода
Здесь задачу решаем перебором, перебираем в двух циклах от 0 до round(sqrt(c^2) )
Пример вызова:
Pifagor.new.work(25)

1 комментарий:

  1. Пример реализации на Haskell:

    > let m =sqrt 100
    > [(a,b,c)|c<-[0..m], a<- [0..m], b<- [0..m], c*c==a*a+b*b]
    [(0.0,0.0,0.0),(0.0,1.0,1.0),(1.0,0.0,1.0),(0.0,2.0,2.0),(2.0,0.0,2.0),(0.0,3.0,3.0),(3.0,0.0,3.0),(0.0,4.0,4.0),(4.0,0.0,4.0),(0.0,5.0,5.0),(3.0,4.0,5.0),(4.0,3.0,5.0),(5.0,0.0,5.0),(0.0,6.0,6.0),(6.0,0.0,6.0),(0.0,7.0,7.0),(7.0,0.0,7.0),(0.0,8.0,8.0),(8.0,0.0,8.0),(0.0,9.0,9.0),(9.0,0.0,9.0),(0.0,10.0,10.0),(6.0,8.0,10.0),(8.0,6.0,10.0),(10.0,0.0,10.0)]

    ОтветитьУдалить