Skip to content

Commit 697a4e9

Browse files
authored
Merge pull request #197 from aparibocci/feature/counting_sort
Adding `counting sort` implementation
2 parents fc19420 + 7ca6ac7 commit 697a4e9

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

sorting/counting_sort.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
##
2+
# Given a non-negative integer value_upper_bound and an array of integers arr with values between 0 and value_upper_bound,
3+
# returns a sorted copy of the input array.
4+
# When value_upper_bound = O(arr.length), sorting runs in O(arr.length).
5+
6+
def counting_sort(arr, value_upper_bound)
7+
if !value_upper_bound.integer? || value_upper_bound < 0
8+
raise ArgumentError.new("counting_sort must be invoked with integer value_upper_bound >= 0")
9+
end
10+
if !arr.all? { |elem| elem.integer? && elem.between?(0, value_upper_bound) }
11+
raise ArgumentError.new("counting_sort must be invoked with integer array elements in (0..value_upper_bound)")
12+
end
13+
sorted_arr = Array.new(arr.length) { 0 }
14+
tmp_arr = Array.new(value_upper_bound+1) { 0 }
15+
for elem in arr
16+
tmp_arr[elem] += 1
17+
end
18+
for i in 1..value_upper_bound
19+
tmp_arr[i] += tmp_arr[i-1]
20+
end
21+
arr.reverse_each do |elem|
22+
sorted_arr[tmp_arr[elem]-1] = elem
23+
tmp_arr[elem] -= 1
24+
end
25+
sorted_arr
26+
end

sorting/counting_sort_test.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require 'minitest/autorun'
2+
require_relative 'counting_sort'
3+
4+
class TestCountingSort < Minitest::Test
5+
def test_empty_array_given_empty_array
6+
assert counting_sort([], 1).empty?
7+
end
8+
9+
def test_array_sorted_correctly
10+
assert counting_sort([1, 5, 3, 0, 4, 2, 4], 5) == [0, 1, 2, 3, 4, 4, 5]
11+
end
12+
13+
def test_exception_given_non_integer_upper_bound
14+
assert_raises ArgumentError do
15+
counting_sort([1, 3, 2], 5.5)
16+
end
17+
end
18+
19+
def test_exception_given_negative_upper_bound
20+
assert_raises ArgumentError do
21+
counting_sort([1, 3, 2], -1)
22+
end
23+
end
24+
25+
def test_exception_given_non_integer_elements
26+
assert_raises ArgumentError do
27+
counting_sort([1, 3, 2.5], 5)
28+
end
29+
end
30+
31+
def test_exception_given_negative_elements
32+
assert_raises ArgumentError do
33+
counting_sort([1, 3, -2], 5)
34+
end
35+
end
36+
37+
def test_exception_given_elements_above_upper_bound
38+
assert_raises ArgumentError do
39+
counting_sort([1, 3, 6], 5)
40+
end
41+
end
42+
end

0 commit comments

Comments
 (0)