array-sort 0.1.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +73 -0
- data/README.md +228 -29
- data/lib/array/sort.rb +5 -8
- data/lib/array_sort/algorithms/binary_insertion_sort.rb +41 -0
- data/lib/array_sort/algorithms/bubble_sort.rb +31 -0
- data/lib/array_sort/algorithms/bucket_sort.rb +67 -0
- data/lib/array_sort/algorithms/cocktail_shaker_sort.rb +42 -0
- data/lib/array_sort/algorithms/comb_sort.rb +33 -0
- data/lib/array_sort/algorithms/counting_sort.rb +50 -0
- data/lib/array_sort/algorithms/cycle_sort.rb +46 -0
- data/lib/array_sort/algorithms/gnome_sort.rb +28 -0
- data/lib/array_sort/algorithms/heap_sort.rb +43 -0
- data/lib/array_sort/algorithms/insertion_sort.rb +35 -0
- data/lib/array_sort/algorithms/intro_sort.rb +80 -0
- data/lib/array_sort/algorithms/merge_sort.rb +57 -0
- data/lib/array_sort/algorithms/odd_even_sort.rb +34 -0
- data/lib/array_sort/algorithms/pancake_sort.rb +39 -0
- data/lib/array_sort/algorithms/quick_sort.rb +68 -0
- data/lib/array_sort/algorithms/radix_sort.rb +58 -0
- data/lib/array_sort/algorithms/selection_sort.rb +25 -0
- data/lib/array_sort/algorithms/shell_sort.rb +41 -0
- data/lib/array_sort/algorithms/smooth_sort.rb +106 -0
- data/lib/array_sort/algorithms/tim_sort.rb +335 -0
- data/lib/array_sort/algorithms/tournament_sort.rb +53 -0
- data/lib/array_sort/algorithms/tree_sort.rb +96 -0
- data/lib/array_sort/array_methods.rb +67 -0
- data/lib/array_sort/core.rb +124 -0
- data/lib/array_sort/functions.rb +23 -0
- data/lib/array_sort/refinements.rb +16 -0
- data/lib/array_sort/registry.rb +68 -0
- data/lib/array_sort/trace.rb +111 -0
- data/lib/{array/sort → array_sort}/version.rb +1 -1
- data/lib/array_sort.rb +43 -0
- data/sig/array_sort.rbs +368 -0
- metadata +47 -71
- data/.gitignore +0 -9
- data/.rubocop.yml +0 -11
- data/.travis.yml +0 -6
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -22
- data/Rakefile +0 -10
- data/array-sort.gemspec +0 -37
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/lib/array/sort/bubble_sort.rb +0 -91
- data/lib/array/sort/heap_sort.rb +0 -111
- data/lib/array/sort/helper.rb +0 -34
- data/lib/array/sort/insertion_sort.rb +0 -78
- data/lib/array/sort/merge_sort.rb +0 -94
- data/lib/array/sort/quick_sort.rb +0 -73
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ArraySort
|
|
4
|
+
# Adds the {ArrayMethods} to Array only in files that opt in, instead of everywhere.
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# require 'array_sort'
|
|
8
|
+
# using ArraySort::Refinements
|
|
9
|
+
#
|
|
10
|
+
# [3, 1, 2].merge_sort # => [1, 2, 3]
|
|
11
|
+
module Refinements
|
|
12
|
+
refine Array do
|
|
13
|
+
import_methods ArraySort::ArrayMethods
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ArraySort
|
|
4
|
+
# Describes one sorting algorithm: what it is called, whether it is stable, and its complexity.
|
|
5
|
+
#
|
|
6
|
+
# Complexities are written without the O(...), e.g. +"n log n"+. In the distribution sorts, +k+ is the range of the
|
|
7
|
+
# keys (largest minus smallest) and +w+ is the number of bytes in the largest key.
|
|
8
|
+
#
|
|
9
|
+
# @!attribute [r] name
|
|
10
|
+
# @return [Symbol] the method prefix, e.g. +:merge+ for +merge_sort+
|
|
11
|
+
# @!attribute [r] title
|
|
12
|
+
# @return [String] the human-readable name, e.g. +"Merge sort"+
|
|
13
|
+
# @!attribute [r] kind
|
|
14
|
+
# @return [Symbol] +:comparison+ for sorts that compare elements (and accept a comparison block), or
|
|
15
|
+
# +:distribution+ for sorts that place elements by numeric key (Integer, or any real number for bucket sort)
|
|
16
|
+
# @!attribute [r] best
|
|
17
|
+
# @return [String] best-case time complexity
|
|
18
|
+
# @!attribute [r] average
|
|
19
|
+
# @return [String] average-case time complexity
|
|
20
|
+
# @!attribute [r] worst
|
|
21
|
+
# @return [String] worst-case time complexity
|
|
22
|
+
# @!attribute [r] space
|
|
23
|
+
# @return [String] extra space used, beyond the copy made by the non-bang methods
|
|
24
|
+
Algorithm = Data.define(:name, :title, :implementation, :stable, :kind, :best, :average, :worst, :space) do
|
|
25
|
+
# @return [Boolean] whether elements that compare equal keep their original relative order
|
|
26
|
+
def stable? = stable
|
|
27
|
+
|
|
28
|
+
# @return [Boolean] whether the algorithm sorts by comparing elements
|
|
29
|
+
def comparison? = kind == :comparison
|
|
30
|
+
|
|
31
|
+
# @return [Boolean] whether the algorithm sorts by distributing numeric keys, without comparing elements
|
|
32
|
+
def distribution? = kind == :distribution
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
@algorithms = {}
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
# Returns the names of every available algorithm, in alphabetical order. Each name +x+ provides +x_sort+,
|
|
39
|
+
# +x_sort!+, +x_sort_by+ and +x_sort_by!+.
|
|
40
|
+
#
|
|
41
|
+
# @example
|
|
42
|
+
# ArraySort.algorithms # => [:binary_insertion, :bubble, :bucket, ...]
|
|
43
|
+
# @return [Array<Symbol>]
|
|
44
|
+
def algorithms
|
|
45
|
+
@algorithms.keys.sort
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Returns the description of an algorithm.
|
|
49
|
+
#
|
|
50
|
+
# @example
|
|
51
|
+
# ArraySort.algorithm(:merge).stable? # => true
|
|
52
|
+
# @param name [Symbol, String]
|
|
53
|
+
# @return [Algorithm]
|
|
54
|
+
# @raise [ArgumentError] if there is no algorithm with that name
|
|
55
|
+
def algorithm(name)
|
|
56
|
+
@algorithms.fetch(name.to_sym) { raise ArgumentError, "unknown sorting algorithm: #{name.inspect}" }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
# Called by each algorithm file to add itself.
|
|
62
|
+
def register(name, implementation, title:, stable:, best:, average:, worst:, space:, kind: :comparison)
|
|
63
|
+
raise "algorithm #{name.inspect} is already registered" if @algorithms.key?(name)
|
|
64
|
+
|
|
65
|
+
@algorithms[name] = Algorithm.new(name:, title:, implementation:, stable:, kind:, best:, average:, worst:, space:)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ArraySort
|
|
4
|
+
# A record of everything a sorting algorithm did: every comparison it made and every write to the array, in order.
|
|
5
|
+
# Build one with {ArraySort.trace}.
|
|
6
|
+
#
|
|
7
|
+
# Replaying the writes onto a copy of {#input} reproduces {#result} step by step, which makes traces handy for
|
|
8
|
+
# visualizing or teaching how the algorithms differ.
|
|
9
|
+
class Trace
|
|
10
|
+
# One comparison between two elements. +result+ is -1, 0 or 1.
|
|
11
|
+
Comparison = Data.define(:left, :right, :result)
|
|
12
|
+
|
|
13
|
+
# One assignment +array[index] = value+. A swap shows up as two writes.
|
|
14
|
+
Write = Data.define(:index, :value)
|
|
15
|
+
|
|
16
|
+
# @return [Algorithm] the algorithm that ran
|
|
17
|
+
attr_reader :algorithm
|
|
18
|
+
# @return [Array] a copy of the array before sorting
|
|
19
|
+
attr_reader :input
|
|
20
|
+
# @return [Array] the sorted array
|
|
21
|
+
attr_reader :result
|
|
22
|
+
# @return [Array<Comparison, Write>] everything the algorithm did, in order
|
|
23
|
+
attr_reader :events
|
|
24
|
+
|
|
25
|
+
# @api private
|
|
26
|
+
def initialize(algorithm, input, result, events)
|
|
27
|
+
@algorithm = algorithm
|
|
28
|
+
@input = input
|
|
29
|
+
@result = result
|
|
30
|
+
@events = events
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Integer] how many comparisons were made
|
|
34
|
+
def comparisons
|
|
35
|
+
events.count { |event| event.is_a?(Comparison) }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Integer] how many elements were written
|
|
39
|
+
def writes
|
|
40
|
+
events.count { |event| event.is_a?(Write) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The array handed to the algorithm while tracing. It reports every element assignment.
|
|
44
|
+
#
|
|
45
|
+
# @api private
|
|
46
|
+
class Buffer < Array
|
|
47
|
+
def initialize(array, on_write)
|
|
48
|
+
super(array, &nil)
|
|
49
|
+
@on_write = on_write
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Only single-element assignment is supported; algorithms must not use the range or length forms.
|
|
53
|
+
def []=(index, value)
|
|
54
|
+
@on_write.call(index, value)
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
private_constant :Buffer
|
|
59
|
+
|
|
60
|
+
# @api private
|
|
61
|
+
def self.run(name, array, &on_event)
|
|
62
|
+
algorithm = ArraySort.algorithm(name)
|
|
63
|
+
input = Array.new(array).freeze
|
|
64
|
+
events = []
|
|
65
|
+
record = lambda do |event|
|
|
66
|
+
events << event
|
|
67
|
+
on_event&.call(event)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
buffer = Buffer.new(input, ->(index, value) { record.call(Write.new(index:, value:)) })
|
|
71
|
+
algorithm.implementation.call(buffer, algorithm.comparison? ? recording_comparator(record) : lambda { |element|
|
|
72
|
+
element
|
|
73
|
+
})
|
|
74
|
+
new(algorithm, input, Array.new(buffer), events.freeze)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Compares with <=> like an untraced sort, and records each comparison.
|
|
78
|
+
def self.recording_comparator(record)
|
|
79
|
+
compare = Core.comparator(nil)
|
|
80
|
+
lambda do |a, b|
|
|
81
|
+
compare.call(a, b).tap { |result| record.call(Comparison.new(left: a, right: b, result: result <=> 0)) }
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
private_class_method :recording_comparator
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class << self
|
|
88
|
+
# Sorts a copy of +array+ with the named algorithm, recording each comparison and write.
|
|
89
|
+
#
|
|
90
|
+
# Elements are compared with +<=>+ (distribution sorts never compare; they need Integer elements, or real numbers
|
|
91
|
+
# for bucket sort).
|
|
92
|
+
#
|
|
93
|
+
# @example
|
|
94
|
+
# trace = ArraySort.trace(:insertion, [3, 1, 2])
|
|
95
|
+
# trace.result # => [1, 2, 3]
|
|
96
|
+
# trace.comparisons # => 3
|
|
97
|
+
# trace.events.first
|
|
98
|
+
# # => #<data ArraySort::Trace::Comparison left=3, right=1, result=1>
|
|
99
|
+
#
|
|
100
|
+
# @example Streaming events as they happen
|
|
101
|
+
# ArraySort.trace(:heap, [3, 1, 2]) { |event| puts event.inspect }
|
|
102
|
+
#
|
|
103
|
+
# @param name [Symbol, String] one of {ArraySort.algorithms}
|
|
104
|
+
# @param array [Array] the array to sort; it is not modified
|
|
105
|
+
# @yieldparam event [Trace::Comparison, Trace::Write] each event, as it happens
|
|
106
|
+
# @return [Trace]
|
|
107
|
+
def trace(name, array, &)
|
|
108
|
+
Trace.run(name, array, &)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
data/lib/array_sort.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Popular sorting algorithms for Ruby arrays.
|
|
4
|
+
#
|
|
5
|
+
# Requiring +array_sort+ loads everything without changing Array. From there, sort with the module functions
|
|
6
|
+
# (+ArraySort.merge_sort(array)+), or opt in per file with +using ArraySort::Refinements+. Requiring +array/sort+
|
|
7
|
+
# instead also adds the sort methods to every Array.
|
|
8
|
+
module ArraySort
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require_relative 'array_sort/version'
|
|
12
|
+
require_relative 'array_sort/registry'
|
|
13
|
+
require_relative 'array_sort/core'
|
|
14
|
+
|
|
15
|
+
# Algorithms some others build on come first.
|
|
16
|
+
require_relative 'array_sort/algorithms/bubble_sort'
|
|
17
|
+
require_relative 'array_sort/algorithms/heap_sort'
|
|
18
|
+
require_relative 'array_sort/algorithms/insertion_sort'
|
|
19
|
+
require_relative 'array_sort/algorithms/quick_sort'
|
|
20
|
+
|
|
21
|
+
require_relative 'array_sort/algorithms/binary_insertion_sort'
|
|
22
|
+
require_relative 'array_sort/algorithms/bucket_sort'
|
|
23
|
+
require_relative 'array_sort/algorithms/cocktail_shaker_sort'
|
|
24
|
+
require_relative 'array_sort/algorithms/comb_sort'
|
|
25
|
+
require_relative 'array_sort/algorithms/counting_sort'
|
|
26
|
+
require_relative 'array_sort/algorithms/cycle_sort'
|
|
27
|
+
require_relative 'array_sort/algorithms/gnome_sort'
|
|
28
|
+
require_relative 'array_sort/algorithms/intro_sort'
|
|
29
|
+
require_relative 'array_sort/algorithms/merge_sort'
|
|
30
|
+
require_relative 'array_sort/algorithms/odd_even_sort'
|
|
31
|
+
require_relative 'array_sort/algorithms/pancake_sort'
|
|
32
|
+
require_relative 'array_sort/algorithms/radix_sort'
|
|
33
|
+
require_relative 'array_sort/algorithms/selection_sort'
|
|
34
|
+
require_relative 'array_sort/algorithms/shell_sort'
|
|
35
|
+
require_relative 'array_sort/algorithms/smooth_sort'
|
|
36
|
+
require_relative 'array_sort/algorithms/tim_sort'
|
|
37
|
+
require_relative 'array_sort/algorithms/tournament_sort'
|
|
38
|
+
require_relative 'array_sort/algorithms/tree_sort'
|
|
39
|
+
|
|
40
|
+
require_relative 'array_sort/array_methods'
|
|
41
|
+
require_relative 'array_sort/functions'
|
|
42
|
+
require_relative 'array_sort/refinements'
|
|
43
|
+
require_relative 'array_sort/trace'
|
data/sig/array_sort.rbs
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# Generated by script/generate_sig.rb from the algorithm registry; run `bundle exec rake sig` to update.
|
|
2
|
+
|
|
3
|
+
module ArraySort
|
|
4
|
+
VERSION: String
|
|
5
|
+
|
|
6
|
+
type real = Integer | Float | Rational
|
|
7
|
+
|
|
8
|
+
def self.algorithms: () -> Array[Symbol]
|
|
9
|
+
def self.algorithm: (Symbol | String name) -> Algorithm
|
|
10
|
+
def self.trace: (Symbol | String name, Array[untyped] array) ?{ (Trace::event event) -> void } -> Trace
|
|
11
|
+
|
|
12
|
+
def self.binary_insertion_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
13
|
+
def self.binary_insertion_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
14
|
+
def self.binary_insertion_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
15
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
16
|
+
def self.binary_insertion_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
17
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
18
|
+
|
|
19
|
+
def self.bubble_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
20
|
+
def self.bubble_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
21
|
+
def self.bubble_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
22
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
23
|
+
def self.bubble_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
24
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
25
|
+
|
|
26
|
+
def self.bucket_sort: [T] (Array[real] array) -> Array[real]
|
|
27
|
+
def self.bucket_sort!: [T] (Array[real] array) -> Array[real]
|
|
28
|
+
def self.bucket_sort_by: [T] (Array[T] array) { (T) -> real } -> Array[T]
|
|
29
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
30
|
+
def self.bucket_sort_by!: [T] (Array[T] array) { (T) -> real } -> Array[T]
|
|
31
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
32
|
+
|
|
33
|
+
def self.cocktail_shaker_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
34
|
+
def self.cocktail_shaker_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
35
|
+
def self.cocktail_shaker_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
36
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
37
|
+
def self.cocktail_shaker_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
38
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
39
|
+
|
|
40
|
+
def self.comb_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
41
|
+
def self.comb_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
42
|
+
def self.comb_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
43
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
44
|
+
def self.comb_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
45
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
46
|
+
|
|
47
|
+
def self.counting_sort: [T] (Array[Integer] array) -> Array[Integer]
|
|
48
|
+
def self.counting_sort!: [T] (Array[Integer] array) -> Array[Integer]
|
|
49
|
+
def self.counting_sort_by: [T] (Array[T] array) { (T) -> Integer } -> Array[T]
|
|
50
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
51
|
+
def self.counting_sort_by!: [T] (Array[T] array) { (T) -> Integer } -> Array[T]
|
|
52
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
53
|
+
|
|
54
|
+
def self.cycle_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
55
|
+
def self.cycle_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
56
|
+
def self.cycle_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
57
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
58
|
+
def self.cycle_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
59
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
60
|
+
|
|
61
|
+
def self.gnome_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
62
|
+
def self.gnome_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
63
|
+
def self.gnome_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
64
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
65
|
+
def self.gnome_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
66
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
67
|
+
|
|
68
|
+
def self.heap_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
69
|
+
def self.heap_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
70
|
+
def self.heap_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
71
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
72
|
+
def self.heap_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
73
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
74
|
+
|
|
75
|
+
def self.insertion_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
76
|
+
def self.insertion_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
77
|
+
def self.insertion_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
78
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
79
|
+
def self.insertion_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
80
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
81
|
+
|
|
82
|
+
def self.intro_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
83
|
+
def self.intro_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
84
|
+
def self.intro_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
85
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
86
|
+
def self.intro_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
87
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
88
|
+
|
|
89
|
+
def self.merge_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
90
|
+
def self.merge_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
91
|
+
def self.merge_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
92
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
93
|
+
def self.merge_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
94
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
95
|
+
|
|
96
|
+
def self.odd_even_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
97
|
+
def self.odd_even_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
98
|
+
def self.odd_even_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
99
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
100
|
+
def self.odd_even_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
101
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
102
|
+
|
|
103
|
+
def self.pancake_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
104
|
+
def self.pancake_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
105
|
+
def self.pancake_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
106
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
107
|
+
def self.pancake_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
108
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
109
|
+
|
|
110
|
+
def self.quick_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
111
|
+
def self.quick_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
112
|
+
def self.quick_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
113
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
114
|
+
def self.quick_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
115
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
116
|
+
|
|
117
|
+
def self.radix_sort: [T] (Array[Integer] array) -> Array[Integer]
|
|
118
|
+
def self.radix_sort!: [T] (Array[Integer] array) -> Array[Integer]
|
|
119
|
+
def self.radix_sort_by: [T] (Array[T] array) { (T) -> Integer } -> Array[T]
|
|
120
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
121
|
+
def self.radix_sort_by!: [T] (Array[T] array) { (T) -> Integer } -> Array[T]
|
|
122
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
123
|
+
|
|
124
|
+
def self.selection_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
125
|
+
def self.selection_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
126
|
+
def self.selection_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
127
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
128
|
+
def self.selection_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
129
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
130
|
+
|
|
131
|
+
def self.shell_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
132
|
+
def self.shell_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
133
|
+
def self.shell_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
134
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
135
|
+
def self.shell_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
136
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
137
|
+
|
|
138
|
+
def self.smooth_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
139
|
+
def self.smooth_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
140
|
+
def self.smooth_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
141
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
142
|
+
def self.smooth_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
143
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
144
|
+
|
|
145
|
+
def self.tim_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
146
|
+
def self.tim_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
147
|
+
def self.tim_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
148
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
149
|
+
def self.tim_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
150
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
151
|
+
|
|
152
|
+
def self.tournament_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
153
|
+
def self.tournament_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
154
|
+
def self.tournament_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
155
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
156
|
+
def self.tournament_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
157
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
158
|
+
|
|
159
|
+
def self.tree_sort: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
160
|
+
def self.tree_sort!: [T] (Array[T] array) ?{ (T a, T b) -> Numeric? } -> Array[T]
|
|
161
|
+
def self.tree_sort_by: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
162
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
163
|
+
def self.tree_sort_by!: [T] (Array[T] array) { (T) -> untyped } -> Array[T]
|
|
164
|
+
| [T] (Array[T] array) -> Enumerator[T, Array[T]]
|
|
165
|
+
|
|
166
|
+
class Algorithm < Data
|
|
167
|
+
attr_reader name: Symbol
|
|
168
|
+
attr_reader title: String
|
|
169
|
+
attr_reader implementation: untyped
|
|
170
|
+
attr_reader stable: bool
|
|
171
|
+
attr_reader kind: :comparison | :distribution
|
|
172
|
+
attr_reader best: String
|
|
173
|
+
attr_reader average: String
|
|
174
|
+
attr_reader worst: String
|
|
175
|
+
attr_reader space: String
|
|
176
|
+
def stable?: () -> bool
|
|
177
|
+
def comparison?: () -> bool
|
|
178
|
+
def distribution?: () -> bool
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class Trace
|
|
182
|
+
type event = Comparison | Write
|
|
183
|
+
|
|
184
|
+
class Comparison < Data
|
|
185
|
+
attr_reader left: untyped
|
|
186
|
+
attr_reader right: untyped
|
|
187
|
+
attr_reader result: Integer
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
class Write < Data
|
|
191
|
+
attr_reader index: Integer
|
|
192
|
+
attr_reader value: untyped
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
attr_reader algorithm: Algorithm
|
|
196
|
+
attr_reader input: Array[untyped]
|
|
197
|
+
attr_reader result: Array[untyped]
|
|
198
|
+
attr_reader events: Array[event]
|
|
199
|
+
def comparisons: () -> Integer
|
|
200
|
+
def writes: () -> Integer
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
module ArrayMethods[Elem]
|
|
204
|
+
def swap: (Integer index1, Integer index2) -> self
|
|
205
|
+
|
|
206
|
+
def binary_insertion_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
207
|
+
def binary_insertion_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
208
|
+
def binary_insertion_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
209
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
210
|
+
def binary_insertion_sort_by!: () { (Elem) -> untyped } -> self
|
|
211
|
+
| () -> Enumerator[Elem, self]
|
|
212
|
+
|
|
213
|
+
def bubble_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
214
|
+
def bubble_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
215
|
+
def bubble_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
216
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
217
|
+
def bubble_sort_by!: () { (Elem) -> untyped } -> self
|
|
218
|
+
| () -> Enumerator[Elem, self]
|
|
219
|
+
|
|
220
|
+
def bucket_sort: () -> Array[Elem]
|
|
221
|
+
def bucket_sort!: () -> self
|
|
222
|
+
def bucket_sort_by: () { (Elem) -> real } -> Array[Elem]
|
|
223
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
224
|
+
def bucket_sort_by!: () { (Elem) -> real } -> self
|
|
225
|
+
| () -> Enumerator[Elem, self]
|
|
226
|
+
|
|
227
|
+
def cocktail_shaker_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
228
|
+
def cocktail_shaker_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
229
|
+
def cocktail_shaker_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
230
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
231
|
+
def cocktail_shaker_sort_by!: () { (Elem) -> untyped } -> self
|
|
232
|
+
| () -> Enumerator[Elem, self]
|
|
233
|
+
|
|
234
|
+
def comb_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
235
|
+
def comb_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
236
|
+
def comb_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
237
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
238
|
+
def comb_sort_by!: () { (Elem) -> untyped } -> self
|
|
239
|
+
| () -> Enumerator[Elem, self]
|
|
240
|
+
|
|
241
|
+
def counting_sort: () -> Array[Elem]
|
|
242
|
+
def counting_sort!: () -> self
|
|
243
|
+
def counting_sort_by: () { (Elem) -> Integer } -> Array[Elem]
|
|
244
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
245
|
+
def counting_sort_by!: () { (Elem) -> Integer } -> self
|
|
246
|
+
| () -> Enumerator[Elem, self]
|
|
247
|
+
|
|
248
|
+
def cycle_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
249
|
+
def cycle_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
250
|
+
def cycle_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
251
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
252
|
+
def cycle_sort_by!: () { (Elem) -> untyped } -> self
|
|
253
|
+
| () -> Enumerator[Elem, self]
|
|
254
|
+
|
|
255
|
+
def gnome_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
256
|
+
def gnome_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
257
|
+
def gnome_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
258
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
259
|
+
def gnome_sort_by!: () { (Elem) -> untyped } -> self
|
|
260
|
+
| () -> Enumerator[Elem, self]
|
|
261
|
+
|
|
262
|
+
def heap_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
263
|
+
def heap_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
264
|
+
def heap_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
265
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
266
|
+
def heap_sort_by!: () { (Elem) -> untyped } -> self
|
|
267
|
+
| () -> Enumerator[Elem, self]
|
|
268
|
+
|
|
269
|
+
def insertion_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
270
|
+
def insertion_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
271
|
+
def insertion_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
272
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
273
|
+
def insertion_sort_by!: () { (Elem) -> untyped } -> self
|
|
274
|
+
| () -> Enumerator[Elem, self]
|
|
275
|
+
|
|
276
|
+
def intro_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
277
|
+
def intro_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
278
|
+
def intro_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
279
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
280
|
+
def intro_sort_by!: () { (Elem) -> untyped } -> self
|
|
281
|
+
| () -> Enumerator[Elem, self]
|
|
282
|
+
|
|
283
|
+
def merge_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
284
|
+
def merge_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
285
|
+
def merge_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
286
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
287
|
+
def merge_sort_by!: () { (Elem) -> untyped } -> self
|
|
288
|
+
| () -> Enumerator[Elem, self]
|
|
289
|
+
|
|
290
|
+
def odd_even_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
291
|
+
def odd_even_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
292
|
+
def odd_even_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
293
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
294
|
+
def odd_even_sort_by!: () { (Elem) -> untyped } -> self
|
|
295
|
+
| () -> Enumerator[Elem, self]
|
|
296
|
+
|
|
297
|
+
def pancake_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
298
|
+
def pancake_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
299
|
+
def pancake_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
300
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
301
|
+
def pancake_sort_by!: () { (Elem) -> untyped } -> self
|
|
302
|
+
| () -> Enumerator[Elem, self]
|
|
303
|
+
|
|
304
|
+
def quick_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
305
|
+
def quick_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
306
|
+
def quick_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
307
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
308
|
+
def quick_sort_by!: () { (Elem) -> untyped } -> self
|
|
309
|
+
| () -> Enumerator[Elem, self]
|
|
310
|
+
|
|
311
|
+
def radix_sort: () -> Array[Elem]
|
|
312
|
+
def radix_sort!: () -> self
|
|
313
|
+
def radix_sort_by: () { (Elem) -> Integer } -> Array[Elem]
|
|
314
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
315
|
+
def radix_sort_by!: () { (Elem) -> Integer } -> self
|
|
316
|
+
| () -> Enumerator[Elem, self]
|
|
317
|
+
|
|
318
|
+
def selection_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
319
|
+
def selection_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
320
|
+
def selection_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
321
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
322
|
+
def selection_sort_by!: () { (Elem) -> untyped } -> self
|
|
323
|
+
| () -> Enumerator[Elem, self]
|
|
324
|
+
|
|
325
|
+
def shell_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
326
|
+
def shell_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
327
|
+
def shell_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
328
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
329
|
+
def shell_sort_by!: () { (Elem) -> untyped } -> self
|
|
330
|
+
| () -> Enumerator[Elem, self]
|
|
331
|
+
|
|
332
|
+
def smooth_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
333
|
+
def smooth_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
334
|
+
def smooth_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
335
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
336
|
+
def smooth_sort_by!: () { (Elem) -> untyped } -> self
|
|
337
|
+
| () -> Enumerator[Elem, self]
|
|
338
|
+
|
|
339
|
+
def tim_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
340
|
+
def tim_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
341
|
+
def tim_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
342
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
343
|
+
def tim_sort_by!: () { (Elem) -> untyped } -> self
|
|
344
|
+
| () -> Enumerator[Elem, self]
|
|
345
|
+
|
|
346
|
+
def tournament_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
347
|
+
def tournament_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
348
|
+
def tournament_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
349
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
350
|
+
def tournament_sort_by!: () { (Elem) -> untyped } -> self
|
|
351
|
+
| () -> Enumerator[Elem, self]
|
|
352
|
+
|
|
353
|
+
def tree_sort: () ?{ (Elem a, Elem b) -> Numeric? } -> Array[Elem]
|
|
354
|
+
def tree_sort!: () ?{ (Elem a, Elem b) -> Numeric? } -> self
|
|
355
|
+
def tree_sort_by: () { (Elem) -> untyped } -> Array[Elem]
|
|
356
|
+
| () -> Enumerator[Elem, Array[Elem]]
|
|
357
|
+
def tree_sort_by!: () { (Elem) -> untyped } -> self
|
|
358
|
+
| () -> Enumerator[Elem, self]
|
|
359
|
+
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
module Refinements
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
class Array[unchecked out Elem]
|
|
367
|
+
include ArraySort::ArrayMethods[Elem]
|
|
368
|
+
end
|