-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b66ca34
commit 878c462
Showing
8 changed files
with
10,298 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# Challenge name | ||
|
||
Challenge URL: | ||
|
||
Challenge description goes here | ||
|
||
**Example** | ||
|
||
| input | expected result | | ||
| ----- | --------------- | | ||
| 'abc' | 5 | | ||
| 'def' | 3 | | ||
| 'ghi' | 5 | | ||
|
||
**Constraints** | ||
|
||
- $1 \leq n \leq 100 $ | ||
- $1 \leq m \leq 100 $ | ||
|
||
## Test suite 🧪 | ||
|
||
The test suite for this challenge covers the constraints described above and a happy path using the example's data. The tests are: | ||
|
||
- `test_raises_ex` | ||
- `test_happy_path` | ||
|
||
For the full test suite, see [algorithm.spec.rb](./algorithm.spec.rb). | ||
|
||
## Algorithm resolution description 📄 | ||
|
||
Algorithm resolution description | ||
|
||
```ruby | ||
# some ruby code here | ||
``` | ||
|
||
The final code, including constraint validations, is available [here](./algorithm.rb). | ||
|
||
## Samples 🥯 | ||
|
||
The samples used to run a quick sanity check on the implementation are: | ||
|
||
```ruby | ||
samples = [ | ||
# add samples here | ||
] | ||
``` | ||
|
||
Which, after feeding it into our runner: | ||
|
||
```ruby | ||
HackerRank::Runner.new(samples).run do |n| | ||
HackerRank::Challenges.challenge_fn(n) | ||
end | ||
``` | ||
|
||
Gives the following output: | ||
|
||
``` | ||
➜ ruby ./challenge/index.rb | ||
challenge output | ||
``` | ||
|
||
A good indicative that the solution looks reasonable. | ||
|
||
## Implementation benchmarking & time complexity analysis 📈 | ||
|
||
Let's now take a look at this implementation and see how it stands from a performance point of view. Below, we have a code analysis and a benchmarking of the solution. | ||
|
||
### Code analysis 🕵🏽♂️ | ||
|
||
Code analysis considerations | ||
|
||
```ruby | ||
# some code here | ||
``` | ||
|
||
Which translates to the following expression: | ||
|
||
[expression breakdown] | ||
|
||
Which means **CONSTANT|LINEAR|QUADRATIC** time complexity. | ||
|
||
### Benchmarking 📊 | ||
|
||
To get a visual feeling of how the function behaves as $n$ increases, a benchmark was run from **BENCHMARK_N_ZERO** up to **BENCHMARK_N_MAX**, resulting in the following chart: | ||
|
||
```console | ||
➜ cat ./circular-array-rotation/results.csv | uplot line -d, -w 50 -h 15 -t Results --canvas ascii --xlabel n --ylabel "T(n)" | ||
Results | ||
┌──────────────────────────────────────────────────┐ | ||
0.003 │ │ | ||
│ .│ | ||
│ ._r@@│ | ||
│ ._@@@@@TT│ | ||
│ . _@@@@@T" │ | ||
│ @@@@@@@TT` │ | ||
│ ._r@@@@T" │ | ||
T(n) │ .\r@@@@T/ │ | ||
│ ._r@@@T/` │ | ||
│ .._@@@@T"` │ | ||
│ .__@@@T/` │ | ||
│ ._r@@T"` │ | ||
│ ..r@@TT" │ | ||
│ __r@T/` │ | ||
0 │@@T"` │ | ||
└──────────────────────────────────────────────────┘ | ||
0 10000 | ||
n | ||
``` | ||
|
||
Which, ignoring eventual CPU fluctuations, matches the given time complexity pattern theoretically demonstrated by the code analysis above. | ||
|
||
For the full benchmarking code, see [benchmarking.rb](./benchmarking.rb). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
require "benchmark" | ||
require_relative './circularly_rotate_array.rb' | ||
require_relative '../_utils/benchmark.rb' | ||
require_relative '../_utils/array/array.rb' | ||
|
||
include ArrayUtils | ||
|
||
MAX_N_SIZE = 10000 | ||
|
||
ENV["CONSTRAINT_ENFORCEMENT_ENABLED"] = "disabled" | ||
|
||
def invoke_algorithm_n_times(n) | ||
HackerRank::Algorithms.circularly_rotate_array( | ||
input: create_array_of_random_integers(size: n), | ||
rotations: 2 | ||
) | ||
end | ||
|
||
HackerRank::Benchmarking.create_time_complexity_analysis( | ||
method_name: :invoke_algorithm_n_times, | ||
n0: 1, | ||
n_max: MAX_N_SIZE, | ||
n_incrementation_step: 1, | ||
file_name: "#{File.expand_path File.dirname(__FILE__)}/results.csv" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
require_relative './circularly_rotate_array.rb' | ||
require_relative "../_utils/validation/index.rb" | ||
|
||
module HackerRank | ||
module Challenges | ||
include HackerRank::Validation | ||
|
||
def self.circular_array_rotation(input:, number_of_rotations:, queries:) | ||
validate_inputs(input, number_of_rotations, queries) | ||
|
||
rotated = Algorithms.circularly_rotate_array(input: input, rotations: number_of_rotations) | ||
queries.map { |query| rotated[query] } | ||
end | ||
|
||
def self.validate_inputs(arr, number_of_rotations, queries) | ||
Validation.ensure_is_array(arr: arr, input_name: "input") | ||
Validation.ensure_array_constraints(input_name: 'input', value: arr, constraints: [1, 10**5]) | ||
|
||
Validation.ensure_constraint_is_within_range( | ||
constraint_name: "number_of_rotations", | ||
constraint_value: number_of_rotations, | ||
range: [1, 10**5], | ||
) | ||
|
||
Validation.ensure_is_array(arr: queries, input_name: "queries") | ||
Validation.ensure_array_constraints( | ||
input_name: 'queries', | ||
value: queries, | ||
constraints: [1, 500] | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
require "test/unit" | ||
require_relative "./challenge.rb" | ||
require_relative "../_utils/algorithm-test/index.rb" | ||
require_relative "../_utils/exceptions/exceptions.rb" | ||
|
||
module HackerRank | ||
module Challenges | ||
class CircularlyRotateArrayTests < Algorithms::AlgorithmTest | ||
def test_raises_exception_if_input_is_not_an_array | ||
assert_raises_invalid_type &-> { | ||
Challenges.circular_array_rotation(input: 3, number_of_rotations: 2, queries: [1, 2]) | ||
} | ||
end | ||
|
||
def test_raises_exception_if_input_array_size_is_smaller_than_the_lower_end_constraint | ||
assert_raises_arr_out_of_min_size &-> { | ||
Challenges.circular_array_rotation(input: [], number_of_rotations: 2, queries: [1, 2]) | ||
} | ||
end | ||
|
||
def test_raises_exception_if_input_array_size_is_greater_than_the_higher_end_constraint | ||
assert_raises_arr_out_of_max_size &-> { | ||
Challenges.circular_array_rotation( | ||
input: create_array_of_random_integers(size: 10**5 + 1), | ||
number_of_rotations: 2, | ||
queries: [1, 2] | ||
) | ||
} | ||
end | ||
|
||
def test_raises_exception_if_number_of_rotations_is_smaller_than_the_lower_end_constraint | ||
assert_raises_out_of_constraints &-> { | ||
Challenges.circular_array_rotation( | ||
input: [3, 4, 5], number_of_rotations: 0, queries: [1, 2] | ||
) | ||
} | ||
end | ||
|
||
def test_raises_exception_if_number_of_rotations_is_greater_than_the_higher_end_constraint | ||
assert_raises_out_of_constraints &-> { | ||
Challenges.circular_array_rotation( | ||
input: [3, 4, 5], number_of_rotations: 10 ** 5 + 1, queries: [1, 2] | ||
) | ||
} | ||
end | ||
|
||
def test_raises_an_exception_if_queries_input_is_not_an_array | ||
assert_raises_invalid_type &-> { | ||
Challenges.circular_array_rotation(input: [3, 4, 5], number_of_rotations: 2, queries: 3) | ||
} | ||
end | ||
|
||
def test_raises_exception_if_queries_array_size_is_smaller_than_the_lower_end_constraint | ||
assert_raises_arr_out_of_min_size &-> { | ||
Challenges.circular_array_rotation(input: [3, 4, 5], number_of_rotations: 2, queries: []) | ||
} | ||
end | ||
|
||
def test_raises_exception_if_queries_array_size_is_greater_than_the_higher_end_constraint | ||
assert_raises_arr_out_of_max_size &-> { | ||
Challenges.circular_array_rotation( | ||
input: [3, 4, 5], | ||
number_of_rotations: 2, | ||
queries: create_array_of_random_integers(size: 501) | ||
) | ||
} | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
require_relative "../_utils/exceptions/exceptions.rb" | ||
|
||
module HackerRank | ||
module Algorithms | ||
include HackerRank::Exceptions | ||
|
||
def self.circularly_rotate_array(input:, rotations: 1) | ||
clone = input.clone | ||
rotations.times { clone = clone.unshift(clone.pop) } | ||
clone | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
require "test/unit" | ||
require_relative "./circularly_rotate_array.rb" | ||
require_relative "../_utils/algorithm-test/index.rb" | ||
require_relative "../_utils/exceptions/exceptions.rb" | ||
|
||
module HackerRank | ||
module Algorithms | ||
class CircularlyRotateArrayTests < AlgorithmTest | ||
def test_return_a_clone_of_the_original_input | ||
original_input = [5, 3, 4] | ||
Algorithms.circularly_rotate_array(input: [3, 4, 5]) | ||
assert_equal [5, 3, 4], original_input | ||
end | ||
|
||
def test_moves_the_last_element_to_the_first_position | ||
assert_equal [5, 3, 4], Algorithms.circularly_rotate_array(input: [3, 4, 5]) | ||
end | ||
|
||
def test_moves_the_last_element_to_the_first_position_multiple_times | ||
assert_equal [4, 5, 3], Algorithms.circularly_rotate_array(input: [3, 4, 5], rotations: 2) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
require_relative './challenge.rb' | ||
require_relative '../_utils/hacker-rank/hacker-rank.rb' | ||
|
||
samples = [ | ||
HackerRank.create_sample(expected_result: [5, 3], params: [[3, 4, 5], 2, [1, 2]]), | ||
HackerRank.create_sample(expected_result: [10, 20, 30], params: [[10, 20, 30], 3, [0, 1, 2]]) | ||
] | ||
|
||
HackerRank::Runner.new(samples).run do |*params| | ||
array, number_of_rotations, queries = params | ||
HackerRank::Challenges.circular_array_rotation( | ||
input: array, | ||
number_of_rotations: number_of_rotations, | ||
queries: queries | ||
) | ||
end |
Oops, something went wrong.