From a7bc930133c6cb7908cbc310d9b391bde39c78b3 Mon Sep 17 00:00:00 2001 From: nickzerjeski Date: Mon, 13 Apr 2026 10:51:59 +0200 Subject: [PATCH 1/2] feat: add free fall distance and time helpers Fixes: #194 --- maths/free_fall_distance.rb | 26 ++++++++++++++++++++++++++ maths/free_fall_distance_test.rb | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 maths/free_fall_distance.rb create mode 100644 maths/free_fall_distance_test.rb diff --git a/maths/free_fall_distance.rb b/maths/free_fall_distance.rb new file mode 100644 index 0000000..bae680b --- /dev/null +++ b/maths/free_fall_distance.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# Free-fall helpers based on constant acceleration motion. +class FreeFallDistance + class << self + STANDARD_GRAVITY = 9.80665 + + # d = 0.5 * g * t^2 + def distance(time:, gravity: STANDARD_GRAVITY) + raise DomainError, 'time must be non-negative' if time.negative? + raise DomainError, 'gravity must be positive' unless gravity.positive? + + 0.5 * gravity * time * time + end + + # t = sqrt(2d / g) + def time(distance:, gravity: STANDARD_GRAVITY) + raise DomainError, 'distance must be non-negative' if distance.negative? + raise DomainError, 'gravity must be positive' unless gravity.positive? + + Math.sqrt((2.0 * distance) / gravity) + end + end +end + +class DomainError < StandardError; end diff --git a/maths/free_fall_distance_test.rb b/maths/free_fall_distance_test.rb new file mode 100644 index 0000000..ae25015 --- /dev/null +++ b/maths/free_fall_distance_test.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative './free_fall_distance' + +class FreeFallDistanceTest < Minitest::Test + def test_distance_from_time + assert_in_delta 19.6133, FreeFallDistance.distance(time: 2.0), 1E-4 + end + + def test_time_from_distance + assert_in_delta 2.0, FreeFallDistance.time(distance: 19.6133), 1E-4 + end + + def test_negative_time_raises + assert_raises DomainError do + FreeFallDistance.distance(time: -1.0) + end + end + + def test_negative_distance_raises + assert_raises DomainError do + FreeFallDistance.time(distance: -1.0) + end + end +end From 4138f9fdb4bbf4bff8db8fd379c69ac8b0d61d91 Mon Sep 17 00:00:00 2001 From: Nick Zerjeski <57059725+nickzerjeski@users.noreply.github.com> Date: Tue, 14 Apr 2026 09:59:10 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- maths/free_fall_distance.rb | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/maths/free_fall_distance.rb b/maths/free_fall_distance.rb index bae680b..2aee86a 100644 --- a/maths/free_fall_distance.rb +++ b/maths/free_fall_distance.rb @@ -2,25 +2,23 @@ # Free-fall helpers based on constant acceleration motion. class FreeFallDistance - class << self - STANDARD_GRAVITY = 9.80665 + STANDARD_GRAVITY = 9.80665 + class << self # d = 0.5 * g * t^2 def distance(time:, gravity: STANDARD_GRAVITY) - raise DomainError, 'time must be non-negative' if time.negative? - raise DomainError, 'gravity must be positive' unless gravity.positive? + raise ArgumentError, 'time must be non-negative' if time.negative? + raise ArgumentError, 'gravity must be positive' unless gravity.positive? 0.5 * gravity * time * time end # t = sqrt(2d / g) def time(distance:, gravity: STANDARD_GRAVITY) - raise DomainError, 'distance must be non-negative' if distance.negative? - raise DomainError, 'gravity must be positive' unless gravity.positive? + raise ArgumentError, 'distance must be non-negative' if distance.negative? + raise ArgumentError, 'gravity must be positive' unless gravity.positive? Math.sqrt((2.0 * distance) / gravity) end end end - -class DomainError < StandardError; end