Skip to content

Instantly share code, notes, and snippets.

@amirrajan
Last active March 13, 2024 05:28
Show Gist options
  • Save amirrajan/eccda89bc6884e03cf63e88b559b6e5d to your computer and use it in GitHub Desktop.
Save amirrajan/eccda89bc6884e03cf63e88b559b6e5d to your computer and use it in GitHub Desktop.
Ruby - Pythagorean Triples
# all unique pythagorean triples
# sorted by area
# range of numbers we are checking
one_to_hundred = (1..100).to_a
# ==================================================
# OPTION 1: vanilla/intertwined logic -> bleh
# ==================================================
triples = Set.new
for a in one_to_hundred
for b in one_to_hundred
# calc c
c = Math.sqrt(a ** 2 + b ** 2)
# calc area
area = a * c / 2
# only add it if it's a triple
triples << { a:, b:, c:, area: } if c.to_i == c
end
end
triples = triples.sort_by { |triangle| triangle[:area] }
puts triples
# ==================================================
# end vanilla
# ==================================================
# ==================================================
# OPTION 2: lambda chains
# ==================================================
triples = one_to_hundred.product(one_to_hundred).map do |a, b|
# given permutations of side a, and side b (product)
# calculate the hypotenuse
{ a:, b:, c: Math.sqrt(a ** 2 + b ** 2) }
end.find_all do |triangle|
# where area is a whole number (pythagaroean triple)
triangle[:c].to_i == triangle[:c]
end.uniq do |triangle|
# unique based on sorted sides
triangle.values.map(&:to_i).sort
end.map do |triangle|
# calculate the area
triangle.merge(area: (triangle[:a] * triangle[:c]) / 2)
end.sort_by do |triangle|
# sort by area
triangle[:area]
end
puts triples
# ==================================================
# end lambda chanins
# ==================================================
# ==================================================
# OPTION 3: OO based (kind of overkill for the problem)
# ==================================================
class Triangle
attr_accessor :a, :b, :c
def initialize(a, b)
@a = a
@b = b
@c = Math.sqrt(a ** 2 + b ** 2)
end
def triple?
@c.to_i == @c
end
def area
@a * @c / 2
end
def eql? other
[@a, @b, @c].sort == [other.a, other.b, other.c].sort
end
def to_s
"Triangle(#{@a}, #{@b}, #{@c})"
end
end
triples = one_to_hundred.product(one_to_hundred)
.map { |a, b| Triangle.new(a, b) }
.find_all { |triangle| triangle.triple? }
.uniq
.sort_by { |triangle| triangle.area }
puts triples
# same as above, but condensed using pointers to lambdas/methods
triples = one_to_hundred.product(one_to_hundred)
.map { |a, b| Triangle.new(a, b) }
.find_all(&:triple?)
.uniq
.sort_by(&:area)
puts triples
# ==================================================
# end OO based
# ==================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment