A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^(2) + b^(2) = c^(2)
For example, 3^(2) + 4^(2) = 9 + 16 = 25 = 5^(2).
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,
a^(2) + b^(2) = c^(2)
For example, 3^(2) + 4^(2) = 9 + 16 = 25 = 5^(2).
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
[code]MAX=1000
1.upto(MAX) do |i|
a = i
a.upto(MAX) do |j|
b = j
c = Math.sqrt(aa + bb)
puts “#{a} #{b} #{c.to_i}” if (a+b+c==1000)
end
end[/code]
=> 200 375 425
Inaczej nie mam pomysłu, chętnie przeczytam bardziej “ruby way” rozwiązanie
Tomash, mała poprawka ode mnie (nie widzę potrzeby dla zmiennych a i b + szukane jest abc):
[code=ruby]MAX=1000
1.upto(MAX) do |a|
a.upto(MAX) do |b|
c = Math.sqrt(aa + bb)
puts a * b * c.to_i if (a+b+c==1000)
end[/code]
Chociaż nie podoba mi się, że porównujesz liczbę float z fixnum (a+b+c zwróci liczbę float):
irb(main):023:0> 5.00000000000000000000000000000001 == 5
=> true
Moja wersja:
code=ruby.each do |a|
(a…1000).each do |b|
next if a + b >= 1000
c = 1000 - a - b
puts a * b * c if a ** 2 + b ** 2 == c ** 2
end
end[/code]
No tak, zapis “product abc” był odrobinę dwuznaczny, więc pograłem bezpiecznie i na pałę wypisałem całą trójkę.
Podoba mi się to:
next if a + b >= 1000
tj. nie wpadłem na to i włączyłem do swojego.
Co do Twojej uwagi: wiem i zrobiłem to specjalnie: pierwiastki liczb całkowitych mają taką postać (tak mało zer po przecinku, if any), że nie ma co bać się błędu przy porównywaniu.
Benchmark obu podejść, tj. co jest szybsze: liczeniem c z pierwiastka czy liczeniem c z różnicy 1000,a,b?
user system total real
radarka 0.420000 0.050000 0.470000 ( 0.477962)
tomasha 0.500000 0.040000 0.540000 ( 0.535020)
radarka2 0.400000 0.070000 0.470000 ( 0.476215)
tomasha2 0.470000 0.070000 0.540000 ( 0.546534)
Czyli wygrałeś, lepiej liczyć c = 1000-a-b i sprawdzać kwadrat
Proponuję teraz trochę odpuścić (mam na myśli Hosiawaka, Radarka i siebie) i dać szansę innym forumowiczom
Ja tam na wydajność praktycznie nie patrzę. Jest konkretny problem a ja mam go rozwiązać (powiedzmy w “rozsądnym” czasie) :).
Btw:
irb(main):026:0> Math.sqrt(100000000000001)
=> 10000000.0000001
Lepiej jednak uważać (chociaż działając na liczbach z zadania pewnie nie ma niebezpieczeństwa).
Kluczowa jest chyba informacja, że a<b<c. Co daje nam a<b<(1000-a-b).
A to chyba prowadzi nas do wniosku, że b < 500 - (a/2) oraz (co pewnie też jest ważne), że a < (1000/3).
Te pętelki można zatem jeszcze ograniczyć, nie?
O to, że druga pętla powinna być od a+1 nie będę już się czepiał
Troche z innej strony
[codeRuby]def is_pit_tri?(a)
a.sort!
return true if a[0]**2 + a[1]**2 == a[2]**2
return false
end
def oblicz
wynik = 0
1.upto(500) do |a|
1.upto(999 - a) do |b|
c = 1000 - a - b
tab = [a , b , c]
return [abc, a, b, c] if is_pit_tri?(tab)
end
end
return wynik
end
puts oblicz[/code]
1.upto(1000) {|a| a.upto(1000) {|b| p "a=#{a}, b=#{b}, c=#{Math.sqrt(a*a + b*b).to_i}" if a + b + Math.sqrt(a*a + b*b) == 1000}}
a=200, b=375, c=425