hamster 0.4.3 → 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 +7 -0
- data/lib/hamster.rb +11 -9
- data/lib/hamster/core_ext.rb +2 -3
- data/lib/hamster/core_ext/enumerable.rb +18 -27
- data/lib/hamster/core_ext/io.rb +16 -25
- data/lib/hamster/deque.rb +252 -0
- data/lib/hamster/enumerable.rb +123 -112
- data/lib/hamster/experimental/mutable_queue.rb +5 -14
- data/lib/hamster/experimental/mutable_set.rb +7 -14
- data/lib/hamster/hash.rb +732 -102
- data/lib/hamster/immutable.rb +4 -10
- data/lib/hamster/list.rb +1155 -215
- data/lib/hamster/{experimental/mutable_hash.rb → mutable_hash.rb} +11 -14
- data/lib/hamster/nested.rb +36 -0
- data/lib/hamster/{experimental/read_copy_update.rb → read_copy_update.rb} +10 -8
- data/lib/hamster/set.rb +488 -90
- data/lib/hamster/sorted_set.rb +1397 -0
- data/lib/hamster/trie.rb +210 -65
- data/lib/hamster/undefined.rb +1 -7
- data/lib/hamster/vector.rb +1329 -83
- data/lib/hamster/version.rb +1 -3
- data/spec/{hamster/core_ext → fixtures}/io_spec.txt +0 -0
- data/spec/lib/hamster/core_ext/array_spec.rb +14 -0
- data/spec/lib/hamster/core_ext/enumerable_spec.rb +30 -0
- data/spec/lib/hamster/core_ext/io_spec.rb +29 -0
- data/spec/lib/hamster/deque/clear_spec.rb +34 -0
- data/spec/lib/hamster/deque/construction_spec.rb +30 -0
- data/spec/lib/hamster/deque/copying_spec.rb +20 -0
- data/spec/lib/hamster/deque/dequeue_spec.rb +35 -0
- data/spec/lib/hamster/deque/empty_spec.rb +40 -0
- data/spec/lib/hamster/deque/enqueue_spec.rb +28 -0
- data/spec/lib/hamster/deque/first_spec.rb +18 -0
- data/spec/lib/hamster/deque/inspect_spec.rb +24 -0
- data/spec/lib/hamster/deque/last_spec.rb +18 -0
- data/spec/lib/hamster/deque/marshal_spec.rb +34 -0
- data/spec/lib/hamster/deque/new_spec.rb +44 -0
- data/spec/lib/hamster/deque/pop_spec.rb +33 -0
- data/spec/lib/hamster/deque/pretty_print_spec.rb +24 -0
- data/spec/lib/hamster/deque/random_modification_spec.rb +34 -0
- data/spec/lib/hamster/deque/size_spec.rb +20 -0
- data/spec/lib/hamster/deque/to_a_spec.rb +27 -0
- data/spec/lib/hamster/deque/to_ary_spec.rb +36 -0
- data/spec/lib/hamster/deque/to_list_spec.rb +26 -0
- data/spec/lib/hamster/deque/unshift_spec.rb +26 -0
- data/spec/lib/hamster/experimental/mutable_set/add_qm_spec.rb +39 -0
- data/spec/lib/hamster/experimental/mutable_set/add_spec.rb +37 -0
- data/spec/lib/hamster/experimental/mutable_set/delete_qm_spec.rb +38 -0
- data/spec/lib/hamster/experimental/mutable_set/delete_spec.rb +37 -0
- data/spec/lib/hamster/hash/all_spec.rb +54 -0
- data/spec/lib/hamster/hash/any_spec.rb +54 -0
- data/spec/lib/hamster/hash/assoc_spec.rb +52 -0
- data/spec/lib/hamster/hash/clear_spec.rb +43 -0
- data/spec/lib/hamster/hash/construction_spec.rb +39 -0
- data/spec/lib/hamster/hash/copying_spec.rb +14 -0
- data/spec/lib/hamster/hash/default_proc_spec.rb +73 -0
- data/spec/lib/hamster/hash/delete_spec.rb +40 -0
- data/spec/lib/hamster/hash/each_spec.rb +78 -0
- data/spec/lib/hamster/hash/each_with_index_spec.rb +30 -0
- data/spec/lib/hamster/hash/empty_spec.rb +44 -0
- data/spec/lib/hamster/hash/eql_spec.rb +70 -0
- data/spec/lib/hamster/hash/except_spec.rb +43 -0
- data/spec/lib/hamster/hash/fetch_spec.rb +58 -0
- data/spec/lib/hamster/hash/find_spec.rb +44 -0
- data/spec/lib/hamster/hash/flat_map_spec.rb +36 -0
- data/spec/lib/hamster/hash/flatten_spec.rb +99 -0
- data/spec/lib/hamster/hash/get_spec.rb +80 -0
- data/spec/lib/hamster/hash/has_key_spec.rb +32 -0
- data/spec/lib/hamster/hash/has_value_spec.rb +28 -0
- data/spec/lib/hamster/hash/hash_spec.rb +30 -0
- data/spec/{hamster → lib/hamster}/hash/immutable_spec.rb +3 -6
- data/spec/lib/hamster/hash/inspect_spec.rb +31 -0
- data/spec/lib/hamster/hash/invert_spec.rb +31 -0
- data/spec/lib/hamster/hash/key_spec.rb +28 -0
- data/spec/lib/hamster/hash/keys_spec.rb +17 -0
- data/spec/lib/hamster/hash/map_spec.rb +46 -0
- data/spec/lib/hamster/hash/marshal_spec.rb +29 -0
- data/spec/lib/hamster/hash/merge_spec.rb +83 -0
- data/spec/lib/hamster/hash/min_max_spec.rb +46 -0
- data/spec/lib/hamster/hash/new_spec.rb +71 -0
- data/spec/lib/hamster/hash/none_spec.rb +49 -0
- data/spec/lib/hamster/hash/partition_spec.rb +36 -0
- data/spec/lib/hamster/hash/pretty_print_spec.rb +35 -0
- data/spec/lib/hamster/hash/put_spec.rb +103 -0
- data/spec/lib/hamster/hash/reduce_spec.rb +36 -0
- data/spec/lib/hamster/hash/reject_spec.rb +62 -0
- data/spec/lib/hamster/hash/reverse_each_spec.rb +28 -0
- data/spec/lib/hamster/hash/sample_spec.rb +14 -0
- data/spec/lib/hamster/hash/select_spec.rb +58 -0
- data/spec/{hamster → lib/hamster}/hash/size_spec.rb +9 -18
- data/spec/lib/hamster/hash/slice_spec.rb +45 -0
- data/spec/lib/hamster/hash/sort_spec.rb +27 -0
- data/spec/lib/hamster/hash/store_spec.rb +76 -0
- data/spec/lib/hamster/hash/take_spec.rb +36 -0
- data/spec/lib/hamster/hash/to_a_spec.rb +14 -0
- data/spec/lib/hamster/hash/to_hash_spec.rb +22 -0
- data/spec/lib/hamster/hash/update_in_spec.rb +80 -0
- data/spec/lib/hamster/hash/values_at_spec.rb +14 -0
- data/spec/lib/hamster/hash/values_spec.rb +25 -0
- data/spec/{hamster → lib/hamster}/immutable/copying_spec.rb +3 -10
- data/spec/{hamster → lib/hamster}/immutable/immutable_spec.rb +3 -16
- data/spec/lib/hamster/immutable/memoize_spec.rb +56 -0
- data/spec/lib/hamster/immutable/new_spec.rb +14 -0
- data/spec/lib/hamster/immutable/transform_spec.rb +26 -0
- data/spec/lib/hamster/immutable/transform_unless_spec.rb +44 -0
- data/spec/lib/hamster/list/add_spec.rb +26 -0
- data/spec/lib/hamster/list/all_spec.rb +58 -0
- data/spec/lib/hamster/list/any_spec.rb +50 -0
- data/spec/lib/hamster/list/append_spec.rb +39 -0
- data/spec/lib/hamster/list/at_spec.rb +30 -0
- data/spec/lib/hamster/list/break_spec.rb +70 -0
- data/spec/lib/hamster/list/cadr_spec.rb +39 -0
- data/spec/lib/hamster/list/chunk_spec.rb +29 -0
- data/spec/lib/hamster/list/clear_spec.rb +25 -0
- data/spec/lib/hamster/list/combination_spec.rb +34 -0
- data/spec/lib/hamster/list/compact_spec.rb +35 -0
- data/spec/lib/hamster/list/compare_spec.rb +31 -0
- data/spec/lib/hamster/list/cons_spec.rb +26 -0
- data/spec/lib/hamster/list/construction_spec.rb +111 -0
- data/spec/lib/hamster/list/copying_spec.rb +20 -0
- data/spec/lib/hamster/list/count_spec.rb +37 -0
- data/spec/lib/hamster/list/cycle_spec.rb +29 -0
- data/spec/lib/hamster/list/delete_at_spec.rb +19 -0
- data/spec/lib/hamster/list/delete_spec.rb +17 -0
- data/spec/lib/hamster/list/drop_spec.rb +31 -0
- data/spec/lib/hamster/list/drop_while_spec.rb +39 -0
- data/spec/lib/hamster/list/each_slice_spec.rb +52 -0
- data/spec/lib/hamster/list/each_spec.rb +41 -0
- data/spec/lib/hamster/list/each_with_index_spec.rb +29 -0
- data/spec/lib/hamster/list/empty_spec.rb +24 -0
- data/spec/lib/hamster/list/eql_spec.rb +62 -0
- data/spec/lib/hamster/list/fill_spec.rb +50 -0
- data/spec/lib/hamster/list/find_all_spec.rb +71 -0
- data/spec/{hamster → lib/hamster}/list/find_index_spec.rb +7 -29
- data/spec/{hamster → lib/hamster}/list/find_spec.rb +13 -35
- data/spec/lib/hamster/list/flat_map_spec.rb +52 -0
- data/spec/lib/hamster/list/flatten_spec.rb +31 -0
- data/spec/lib/hamster/list/grep_spec.rb +47 -0
- data/spec/lib/hamster/list/group_by_spec.rb +42 -0
- data/spec/lib/hamster/list/hash_spec.rb +22 -0
- data/spec/{hamster → lib/hamster}/list/head_spec.rb +6 -21
- data/spec/{hamster → lib/hamster}/list/include_spec.rb +8 -29
- data/spec/lib/hamster/list/index_spec.rb +34 -0
- data/spec/lib/hamster/list/indices_spec.rb +62 -0
- data/spec/lib/hamster/list/init_spec.rb +29 -0
- data/spec/lib/hamster/list/inits_spec.rb +29 -0
- data/spec/lib/hamster/list/insert_spec.rb +47 -0
- data/spec/lib/hamster/list/inspect_spec.rb +30 -0
- data/spec/lib/hamster/list/intersperse_spec.rb +29 -0
- data/spec/lib/hamster/list/join_spec.rb +64 -0
- data/spec/lib/hamster/list/last_spec.rb +24 -0
- data/spec/lib/hamster/list/ltlt_spec.rb +20 -0
- data/spec/lib/hamster/list/map_spec.rb +46 -0
- data/spec/lib/hamster/list/maximum_spec.rb +40 -0
- data/spec/{hamster → lib/hamster}/list/merge_by_spec.rb +9 -36
- data/spec/{hamster → lib/hamster}/list/merge_spec.rb +5 -24
- data/spec/lib/hamster/list/minimum_spec.rb +40 -0
- data/spec/lib/hamster/list/multithreading_spec.rb +48 -0
- data/spec/{hamster → lib/hamster}/list/none_spec.rb +14 -41
- data/spec/{hamster → lib/hamster}/list/one_spec.rb +15 -40
- data/spec/lib/hamster/list/partition_spec.rb +116 -0
- data/spec/lib/hamster/list/permutation_spec.rb +56 -0
- data/spec/lib/hamster/list/pop_spec.rb +26 -0
- data/spec/lib/hamster/list/product_spec.rb +24 -0
- data/spec/lib/hamster/list/reduce_spec.rb +54 -0
- data/spec/lib/hamster/list/reject_spec.rb +46 -0
- data/spec/lib/hamster/list/reverse_spec.rb +35 -0
- data/spec/lib/hamster/list/rotate_spec.rb +37 -0
- data/spec/lib/hamster/list/sample_spec.rb +14 -0
- data/spec/lib/hamster/list/select_spec.rb +71 -0
- data/spec/lib/hamster/list/size_spec.rb +26 -0
- data/spec/lib/hamster/list/slice_spec.rb +230 -0
- data/spec/lib/hamster/list/sorting_spec.rb +47 -0
- data/spec/lib/hamster/list/span_spec.rb +77 -0
- data/spec/lib/hamster/list/split_at_spec.rb +44 -0
- data/spec/lib/hamster/list/subsequences_spec.rb +24 -0
- data/spec/lib/hamster/list/sum_spec.rb +24 -0
- data/spec/lib/hamster/list/tail_spec.rb +31 -0
- data/spec/lib/hamster/list/tails_spec.rb +29 -0
- data/spec/lib/hamster/list/take_spec.rb +31 -0
- data/spec/lib/hamster/list/take_while_spec.rb +47 -0
- data/spec/lib/hamster/list/to_a_spec.rb +40 -0
- data/spec/lib/hamster/list/to_ary_spec.rb +42 -0
- data/spec/lib/hamster/list/to_list_spec.rb +20 -0
- data/spec/lib/hamster/list/to_set_spec.rb +19 -0
- data/spec/lib/hamster/list/transpose_spec.rb +20 -0
- data/spec/lib/hamster/list/union_spec.rb +32 -0
- data/spec/lib/hamster/list/uniq_spec.rb +30 -0
- data/spec/lib/hamster/list/zip_spec.rb +24 -0
- data/spec/lib/hamster/nested/construction_spec.rb +44 -0
- data/spec/lib/hamster/set/add_spec.rb +76 -0
- data/spec/lib/hamster/set/all_spec.rb +52 -0
- data/spec/lib/hamster/set/any_spec.rb +52 -0
- data/spec/lib/hamster/set/clear_spec.rb +34 -0
- data/spec/{hamster → lib/hamster}/set/compact_spec.rb +9 -20
- data/spec/lib/hamster/set/construction_spec.rb +19 -0
- data/spec/lib/hamster/set/copying_spec.rb +14 -0
- data/spec/lib/hamster/set/count_spec.rb +37 -0
- data/spec/lib/hamster/set/delete_spec.rb +72 -0
- data/spec/lib/hamster/set/difference_spec.rb +50 -0
- data/spec/lib/hamster/set/disjoint_spec.rb +26 -0
- data/spec/lib/hamster/set/each_spec.rb +46 -0
- data/spec/lib/hamster/set/empty_spec.rb +45 -0
- data/spec/lib/hamster/set/eqeq_spec.rb +104 -0
- data/spec/lib/hamster/set/eql_spec.rb +110 -0
- data/spec/lib/hamster/set/exclusion_spec.rb +48 -0
- data/spec/{hamster → lib/hamster}/set/find_spec.rb +10 -27
- data/spec/lib/hamster/set/first_spec.rb +29 -0
- data/spec/lib/hamster/set/flatten_spec.rb +47 -0
- data/spec/lib/hamster/set/grep_spec.rb +58 -0
- data/spec/lib/hamster/set/group_by_spec.rb +60 -0
- data/spec/lib/hamster/set/hash_spec.rb +23 -0
- data/spec/{hamster → lib/hamster}/set/immutable_spec.rb +4 -7
- data/spec/lib/hamster/set/include_spec.rb +61 -0
- data/spec/lib/hamster/set/inspect_spec.rb +48 -0
- data/spec/lib/hamster/set/intersect_spec.rb +26 -0
- data/spec/lib/hamster/set/intersection_spec.rb +53 -0
- data/spec/lib/hamster/set/join_spec.rb +65 -0
- data/spec/lib/hamster/set/map_spec.rb +60 -0
- data/spec/lib/hamster/set/marshal_spec.rb +29 -0
- data/spec/lib/hamster/set/maximum_spec.rb +37 -0
- data/spec/lib/hamster/set/minimum_spec.rb +37 -0
- data/spec/lib/hamster/set/new_spec.rb +54 -0
- data/spec/{hamster → lib/hamster}/set/none_spec.rb +17 -32
- data/spec/{hamster → lib/hamster}/set/one_spec.rb +16 -31
- data/spec/lib/hamster/set/partition_spec.rb +53 -0
- data/spec/lib/hamster/set/product_spec.rb +24 -0
- data/spec/lib/hamster/set/reduce_spec.rb +56 -0
- data/spec/lib/hamster/set/reject_spec.rb +51 -0
- data/spec/lib/hamster/set/reverse_each_spec.rb +39 -0
- data/spec/lib/hamster/set/sample_spec.rb +14 -0
- data/spec/lib/hamster/set/select_spec.rb +74 -0
- data/spec/{hamster → lib/hamster}/set/size_spec.rb +4 -13
- data/spec/lib/hamster/set/sorting_spec.rb +49 -0
- data/spec/lib/hamster/set/subset_spec.rb +52 -0
- data/spec/lib/hamster/set/sum_spec.rb +24 -0
- data/spec/lib/hamster/set/superset_spec.rb +52 -0
- data/spec/lib/hamster/set/to_a_spec.rb +31 -0
- data/spec/lib/hamster/set/to_list_spec.rb +37 -0
- data/spec/lib/hamster/set/to_set_spec.rb +20 -0
- data/spec/lib/hamster/set/union_spec.rb +64 -0
- data/spec/lib/hamster/sorted_set/above_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/add_spec.rb +63 -0
- data/spec/lib/hamster/sorted_set/at_spec.rb +25 -0
- data/spec/lib/hamster/sorted_set/below_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/between_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/clear_spec.rb +44 -0
- data/spec/lib/hamster/sorted_set/construction_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/delete_at_spec.rb +19 -0
- data/spec/lib/hamster/sorted_set/delete_spec.rb +90 -0
- data/spec/lib/hamster/sorted_set/difference_spec.rb +23 -0
- data/spec/lib/hamster/sorted_set/disjoint_spec.rb +26 -0
- data/spec/lib/hamster/sorted_set/drop_spec.rb +56 -0
- data/spec/lib/hamster/sorted_set/drop_while_spec.rb +35 -0
- data/spec/lib/hamster/sorted_set/each_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/empty_spec.rb +35 -0
- data/spec/lib/hamster/sorted_set/eql_spec.rb +121 -0
- data/spec/lib/hamster/sorted_set/exclusion_spec.rb +23 -0
- data/spec/lib/hamster/sorted_set/fetch_spec.rb +65 -0
- data/spec/lib/hamster/sorted_set/find_index_spec.rb +41 -0
- data/spec/lib/hamster/sorted_set/first_spec.rb +19 -0
- data/spec/lib/hamster/sorted_set/from_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/group_by_spec.rb +58 -0
- data/spec/lib/hamster/sorted_set/include_spec.rb +24 -0
- data/spec/lib/hamster/sorted_set/inspect_spec.rb +38 -0
- data/spec/lib/hamster/sorted_set/intersect_spec.rb +26 -0
- data/spec/lib/hamster/sorted_set/intersection_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/last_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/map_spec.rb +36 -0
- data/spec/lib/hamster/sorted_set/marshal_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/maximum_spec.rb +37 -0
- data/spec/lib/hamster/sorted_set/minimum_spec.rb +20 -0
- data/spec/lib/hamster/sorted_set/new_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/reverse_each_spec.rb +29 -0
- data/spec/lib/hamster/sorted_set/sample_spec.rb +14 -0
- data/spec/lib/hamster/sorted_set/select_spec.rb +62 -0
- data/spec/{hamster/vector → lib/hamster/sorted_set}/size_spec.rb +6 -15
- data/spec/lib/hamster/sorted_set/slice_spec.rb +257 -0
- data/spec/lib/hamster/sorted_set/sorting_spec.rb +45 -0
- data/spec/lib/hamster/sorted_set/subset_spec.rb +48 -0
- data/spec/lib/hamster/sorted_set/superset_spec.rb +48 -0
- data/spec/lib/hamster/sorted_set/take_spec.rb +55 -0
- data/spec/lib/hamster/sorted_set/take_while_spec.rb +34 -0
- data/spec/lib/hamster/sorted_set/to_set_spec.rb +19 -0
- data/spec/lib/hamster/sorted_set/union_spec.rb +28 -0
- data/spec/lib/hamster/sorted_set/up_to_spec.rb +52 -0
- data/spec/lib/hamster/sorted_set/values_at_spec.rb +34 -0
- data/spec/lib/hamster/vector/add_spec.rb +68 -0
- data/spec/lib/hamster/vector/any_spec.rb +70 -0
- data/spec/lib/hamster/vector/assoc_spec.rb +36 -0
- data/spec/lib/hamster/vector/bsearch_spec.rb +58 -0
- data/spec/lib/hamster/vector/clear_spec.rb +34 -0
- data/spec/lib/hamster/vector/combination_spec.rb +82 -0
- data/spec/lib/hamster/vector/compact_spec.rb +30 -0
- data/spec/lib/hamster/vector/compare_spec.rb +32 -0
- data/spec/lib/hamster/vector/concat_spec.rb +35 -0
- data/spec/lib/hamster/vector/copying_spec.rb +21 -0
- data/spec/lib/hamster/vector/count_spec.rb +18 -0
- data/spec/lib/hamster/vector/delete_at_spec.rb +54 -0
- data/spec/lib/hamster/vector/delete_spec.rb +31 -0
- data/spec/lib/hamster/vector/drop_spec.rb +42 -0
- data/spec/lib/hamster/vector/drop_while_spec.rb +55 -0
- data/spec/lib/hamster/vector/each_index_spec.rb +41 -0
- data/spec/lib/hamster/vector/each_spec.rb +45 -0
- data/spec/lib/hamster/vector/each_with_index_spec.rb +40 -0
- data/spec/lib/hamster/vector/empty_spec.rb +42 -0
- data/spec/lib/hamster/vector/eql_spec.rb +77 -0
- data/spec/lib/hamster/vector/fetch_spec.rb +65 -0
- data/spec/lib/hamster/vector/fill_spec.rb +89 -0
- data/spec/lib/hamster/vector/first_spec.rb +19 -0
- data/spec/lib/hamster/vector/flat_map_spec.rb +51 -0
- data/spec/lib/hamster/vector/flatten_spec.rb +44 -0
- data/spec/lib/hamster/vector/get_spec.rb +75 -0
- data/spec/lib/hamster/vector/group_by_spec.rb +58 -0
- data/spec/{hamster → lib/hamster}/vector/include_spec.rb +6 -20
- data/spec/lib/hamster/vector/insert_spec.rb +69 -0
- data/spec/lib/hamster/vector/inspect_spec.rb +50 -0
- data/spec/{hamster/set → lib/hamster/vector}/join_spec.rb +24 -34
- data/spec/lib/hamster/vector/last_spec.rb +46 -0
- data/spec/lib/hamster/vector/length_spec.rb +46 -0
- data/spec/lib/hamster/vector/ltlt_spec.rb +66 -0
- data/spec/lib/hamster/vector/map_spec.rb +52 -0
- data/spec/lib/hamster/vector/marshal_spec.rb +32 -0
- data/spec/lib/hamster/vector/maximum_spec.rb +34 -0
- data/spec/lib/hamster/vector/minimum_spec.rb +34 -0
- data/spec/lib/hamster/vector/multiply_spec.rb +48 -0
- data/spec/lib/hamster/vector/new_spec.rb +51 -0
- data/spec/lib/hamster/vector/partition_spec.rb +53 -0
- data/spec/lib/hamster/vector/permutation_spec.rb +92 -0
- data/spec/lib/hamster/vector/pop_spec.rb +27 -0
- data/spec/lib/hamster/vector/product_spec.rb +71 -0
- data/spec/{hamster → lib/hamster}/vector/reduce_spec.rb +18 -49
- data/spec/lib/hamster/vector/reject_spec.rb +44 -0
- data/spec/lib/hamster/vector/repeated_combination_spec.rb +78 -0
- data/spec/lib/hamster/vector/repeated_permutation_spec.rb +94 -0
- data/spec/lib/hamster/vector/reverse_each_spec.rb +32 -0
- data/spec/lib/hamster/vector/reverse_spec.rb +22 -0
- data/spec/lib/hamster/vector/rindex_spec.rb +37 -0
- data/spec/lib/hamster/vector/rotate_spec.rb +74 -0
- data/spec/lib/hamster/vector/sample_spec.rb +14 -0
- data/spec/lib/hamster/vector/select_spec.rb +64 -0
- data/spec/lib/hamster/vector/set_spec.rb +175 -0
- data/spec/lib/hamster/vector/shift_spec.rb +28 -0
- data/spec/lib/hamster/vector/shuffle_spec.rb +44 -0
- data/spec/lib/hamster/vector/slice_spec.rb +241 -0
- data/spec/lib/hamster/vector/sorting_spec.rb +57 -0
- data/spec/{hamster/set → lib/hamster/vector}/sum_spec.rb +5 -19
- data/spec/lib/hamster/vector/take_spec.rb +43 -0
- data/spec/lib/hamster/vector/take_while_spec.rb +35 -0
- data/spec/lib/hamster/vector/to_a_spec.rb +42 -0
- data/spec/lib/hamster/vector/to_ary_spec.rb +35 -0
- data/spec/lib/hamster/vector/to_list_spec.rb +32 -0
- data/spec/lib/hamster/vector/to_set_spec.rb +23 -0
- data/spec/lib/hamster/vector/transpose_spec.rb +49 -0
- data/spec/lib/hamster/vector/uniq_spec.rb +56 -0
- data/spec/lib/hamster/vector/unshift_spec.rb +29 -0
- data/spec/lib/hamster/vector/update_in_spec.rb +83 -0
- data/spec/lib/hamster/vector/values_at_spec.rb +34 -0
- data/spec/lib/hamster/vector/zip_spec.rb +58 -0
- data/spec/spec_helper.rb +45 -13
- metadata +807 -458
- data/History.rdoc +0 -419
- data/LICENSE +0 -20
- data/README.rdoc +0 -236
- data/Rakefile +0 -5
- data/lib/hamster/core_ext/enumerator.rb +0 -30
- data/lib/hamster/experimental/mutable_stack.rb +0 -35
- data/lib/hamster/queue.rb +0 -93
- data/lib/hamster/sorter.rb +0 -32
- data/lib/hamster/stack.rb +0 -82
- data/lib/hamster/tuple.rb +0 -45
- data/spec/hamster/core_ext/array_spec.rb +0 -20
- data/spec/hamster/core_ext/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/core_ext/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/core_ext/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/core_ext/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/core_ext/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/core_ext/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/core_ext/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/core_ext/coverage/covered_percent +0 -1
- data/spec/hamster/core_ext/coverage/index.html +0 -71
- data/spec/hamster/core_ext/coverage/resultset.yml +0 -10
- data/spec/hamster/core_ext/enumerable_spec.rb +0 -34
- data/spec/hamster/core_ext/enumerator_spec.rb +0 -25
- data/spec/hamster/core_ext/io_spec.rb +0 -29
- data/spec/hamster/experimental/mutable_set/add?_spec.rb +0 -47
- data/spec/hamster/experimental/mutable_set/add_spec.rb +0 -51
- data/spec/hamster/experimental/mutable_set/delete?_spec.rb +0 -47
- data/spec/hamster/experimental/mutable_set/delete_spec.rb +0 -47
- data/spec/hamster/experimental/mutable_stack/pop_spec.rb +0 -41
- data/spec/hamster/experimental/mutable_stack/push_spec.rb +0 -41
- data/spec/hamster/hash/all_spec.rb +0 -59
- data/spec/hamster/hash/any_spec.rb +0 -68
- data/spec/hamster/hash/clear_spec.rb +0 -36
- data/spec/hamster/hash/construction_spec.rb +0 -35
- data/spec/hamster/hash/copying_spec.rb +0 -23
- data/spec/hamster/hash/delete_spec.rb +0 -47
- data/spec/hamster/hash/each_spec.rb +0 -41
- data/spec/hamster/hash/empty_spec.rb +0 -27
- data/spec/hamster/hash/eql_spec.rb +0 -62
- data/spec/hamster/hash/except_spec.rb +0 -31
- data/spec/hamster/hash/fetch_spec.rb +0 -95
- data/spec/hamster/hash/filter_spec.rb +0 -63
- data/spec/hamster/hash/find_spec.rb +0 -58
- data/spec/hamster/hash/get_spec.rb +0 -68
- data/spec/hamster/hash/has_key_spec.rb +0 -35
- data/spec/hamster/hash/hash_spec.rb +0 -54
- data/spec/hamster/hash/inspect_spec.rb +0 -32
- data/spec/hamster/hash/keys_spec.rb +0 -21
- data/spec/hamster/hash/map_spec.rb +0 -64
- data/spec/hamster/hash/merge_spec.rb +0 -36
- data/spec/hamster/hash/none_spec.rb +0 -64
- data/spec/hamster/hash/put_spec.rb +0 -65
- data/spec/hamster/hash/reduce_spec.rb +0 -60
- data/spec/hamster/hash/remove_spec.rb +0 -63
- data/spec/hamster/hash/slice_spec.rb +0 -31
- data/spec/hamster/hash/uniq_spec.rb +0 -23
- data/spec/hamster/hash/values_spec.rb +0 -34
- data/spec/hamster/immutable/memoize_spec.rb +0 -64
- data/spec/hamster/immutable/new_spec.rb +0 -28
- data/spec/hamster/immutable/transform_spec.rb +0 -31
- data/spec/hamster/immutable/transform_unless_spec.rb +0 -55
- data/spec/hamster/list/all_spec.rb +0 -111
- data/spec/hamster/list/any_spec.rb +0 -79
- data/spec/hamster/list/append_spec.rb +0 -50
- data/spec/hamster/list/at_spec.rb +0 -49
- data/spec/hamster/list/break_spec.rb +0 -85
- data/spec/hamster/list/cadr_spec.rb +0 -50
- data/spec/hamster/list/chunk_spec.rb +0 -40
- data/spec/hamster/list/clear_spec.rb +0 -36
- data/spec/hamster/list/combinations_spec.rb +0 -51
- data/spec/hamster/list/compact_spec.rb +0 -46
- data/spec/hamster/list/cons_spec.rb +0 -41
- data/spec/hamster/list/construction_spec.rb +0 -140
- data/spec/hamster/list/copying_spec.rb +0 -32
- data/spec/hamster/list/count_spec.rb +0 -66
- data/spec/hamster/list/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/list/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/list/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/list/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/list/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/list/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/list/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/list/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/list/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/list/coverage/covered_percent +0 -1
- data/spec/hamster/list/coverage/index.html +0 -71
- data/spec/hamster/list/coverage/resultset.yml +0 -225
- data/spec/hamster/list/cycle_spec.rb +0 -45
- data/spec/hamster/list/drop_spec.rb +0 -42
- data/spec/hamster/list/drop_while_spec.rb +0 -59
- data/spec/hamster/list/each_slice_spec.rb +0 -80
- data/spec/hamster/list/each_spec.rb +0 -72
- data/spec/hamster/list/each_with_index_spec.rb +0 -42
- data/spec/hamster/list/elem_index_spec.rb +0 -58
- data/spec/hamster/list/elem_indices_spec.rb +0 -45
- data/spec/hamster/list/empty_spec.rb +0 -47
- data/spec/hamster/list/eql_spec.rb +0 -78
- data/spec/hamster/list/filter_spec.rb +0 -61
- data/spec/hamster/list/find_indices_spec.rb +0 -45
- data/spec/hamster/list/flatten_spec.rb +0 -42
- data/spec/hamster/list/grep_spec.rb +0 -70
- data/spec/hamster/list/group_by_spec.rb +0 -77
- data/spec/hamster/list/hash_spec.rb +0 -43
- data/spec/hamster/list/init_spec.rb +0 -40
- data/spec/hamster/list/inits_spec.rb +0 -42
- data/spec/hamster/list/inspect_spec.rb +0 -43
- data/spec/hamster/list/intersperse_spec.rb +0 -40
- data/spec/hamster/list/join_spec.rb +0 -81
- data/spec/hamster/list/last_spec.rb +0 -44
- data/spec/hamster/list/map_spec.rb +0 -69
- data/spec/hamster/list/maximum_spec.rb +0 -77
- data/spec/hamster/list/minimum_spec.rb +0 -77
- data/spec/hamster/list/partition_spec.rb +0 -75
- data/spec/hamster/list/product_spec.rb +0 -44
- data/spec/hamster/list/reduce_spec.rb +0 -99
- data/spec/hamster/list/remove_spec.rb +0 -67
- data/spec/hamster/list/reverse_spec.rb +0 -52
- data/spec/hamster/list/size_spec.rb +0 -47
- data/spec/hamster/list/slice_spec.rb +0 -50
- data/spec/hamster/list/sorting_spec.rb +0 -70
- data/spec/hamster/list/span_spec.rb +0 -86
- data/spec/hamster/list/split_at_spec.rb +0 -53
- data/spec/hamster/list/sum_spec.rb +0 -44
- data/spec/hamster/list/tail_spec.rb +0 -48
- data/spec/hamster/list/tails_spec.rb +0 -42
- data/spec/hamster/list/take_spec.rb +0 -42
- data/spec/hamster/list/take_while_spec.rb +0 -62
- data/spec/hamster/list/to_a_spec.rb +0 -54
- data/spec/hamster/list/to_ary_spec.rb +0 -56
- data/spec/hamster/list/to_list_spec.rb +0 -32
- data/spec/hamster/list/to_set_spec.rb +0 -33
- data/spec/hamster/list/union_spec.rb +0 -49
- data/spec/hamster/list/uniq_spec.rb +0 -45
- data/spec/hamster/list/zip_spec.rb +0 -39
- data/spec/hamster/queue/clear_spec.rb +0 -36
- data/spec/hamster/queue/construction_spec.rb +0 -43
- data/spec/hamster/queue/dequeue_spec.rb +0 -40
- data/spec/hamster/queue/empty_spec.rb +0 -47
- data/spec/hamster/queue/enqueue_spec.rb +0 -41
- data/spec/hamster/queue/head_spec.rb +0 -35
- data/spec/hamster/queue/inspect_spec.rb +0 -31
- data/spec/hamster/queue/size_spec.rb +0 -35
- data/spec/hamster/queue/to_a_spec.rb +0 -42
- data/spec/hamster/queue/to_ary_spec.rb +0 -44
- data/spec/hamster/queue/to_list_spec.rb +0 -44
- data/spec/hamster/set/add_spec.rb +0 -51
- data/spec/hamster/set/all_spec.rb +0 -67
- data/spec/hamster/set/any_spec.rb +0 -67
- data/spec/hamster/set/clear_spec.rb +0 -36
- data/spec/hamster/set/construction_spec.rb +0 -31
- data/spec/hamster/set/copying_spec.rb +0 -23
- data/spec/hamster/set/count_spec.rb +0 -54
- data/spec/hamster/set/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/set/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/set/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/set/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/set/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/set/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/set/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/set/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/set/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/set/coverage/covered_percent +0 -1
- data/spec/hamster/set/coverage/index.html +0 -71
- data/spec/hamster/set/coverage/resultset.yml +0 -13
- data/spec/hamster/set/delete_spec.rb +0 -47
- data/spec/hamster/set/difference_spec.rb +0 -37
- data/spec/hamster/set/each_spec.rb +0 -42
- data/spec/hamster/set/empty_spec.rb +0 -35
- data/spec/hamster/set/eql_spec.rb +0 -62
- data/spec/hamster/set/exclusion_spec.rb +0 -38
- data/spec/hamster/set/filter_spec.rb +0 -79
- data/spec/hamster/set/flatten_spec.rb +0 -49
- data/spec/hamster/set/grep_spec.rb +0 -62
- data/spec/hamster/set/group_by_spec.rb +0 -65
- data/spec/hamster/set/hash_spec.rb +0 -31
- data/spec/hamster/set/head_spec.rb +0 -39
- data/spec/hamster/set/include_spec.rb +0 -35
- data/spec/hamster/set/inspect_spec.rb +0 -32
- data/spec/hamster/set/intersection_spec.rb +0 -46
- data/spec/hamster/set/map_spec.rb +0 -64
- data/spec/hamster/set/maximum_spec.rb +0 -65
- data/spec/hamster/set/minimum_spec.rb +0 -65
- data/spec/hamster/set/partition_spec.rb +0 -71
- data/spec/hamster/set/product_spec.rb +0 -32
- data/spec/hamster/set/reduce_spec.rb +0 -87
- data/spec/hamster/set/remove_spec.rb +0 -63
- data/spec/hamster/set/sorting_spec.rb +0 -58
- data/spec/hamster/set/subset_spec.rb +0 -39
- data/spec/hamster/set/superset_spec.rb +0 -39
- data/spec/hamster/set/to_a_spec.rb +0 -42
- data/spec/hamster/set/to_list_spec.rb +0 -47
- data/spec/hamster/set/to_set_spec.rb +0 -32
- data/spec/hamster/set/union_spec.rb +0 -45
- data/spec/hamster/set/uniq_spec.rb +0 -23
- data/spec/hamster/sorter/coverage/assets/0.4.4/app.js +0 -66
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/blank.gif +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_close.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_loading.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_nav_left.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_nav_right.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_e.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_n.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_ne.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_nw.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_s.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_se.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_sw.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_shadow_w.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_left.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_main.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_over.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancy_title_right.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox-x.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox-y.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/fancybox.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.css +0 -363
- data/spec/hamster/sorter/coverage/assets/0.4.4/fancybox/jquery.fancybox-1.3.1.pack.js +0 -44
- data/spec/hamster/sorter/coverage/assets/0.4.4/favicon.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery-1.4.2.min.js +0 -155
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.dataTables.min.js +0 -152
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.timeago.js +0 -141
- data/spec/hamster/sorter/coverage/assets/0.4.4/jquery.url.js +0 -174
- data/spec/hamster/sorter/coverage/assets/0.4.4/loading.gif +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/magnify.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/spec/hamster/sorter/coverage/assets/0.4.4/smoothness/jquery-ui-1.8.4.custom.css +0 -295
- data/spec/hamster/sorter/coverage/assets/0.4.4/stylesheet.css +0 -341
- data/spec/hamster/sorter/coverage/covered_percent +0 -1
- data/spec/hamster/sorter/coverage/index.html +0 -71
- data/spec/hamster/sorter/coverage/resultset.yml +0 -22
- data/spec/hamster/sorter/immutable_spec.rb +0 -12
- data/spec/hamster/stack/clear_spec.rb +0 -36
- data/spec/hamster/stack/construction_spec.rb +0 -43
- data/spec/hamster/stack/copying_spec.rb +0 -31
- data/spec/hamster/stack/empty_spec.rb +0 -31
- data/spec/hamster/stack/eql_spec.rb +0 -60
- data/spec/hamster/stack/immutable_spec.rb +0 -12
- data/spec/hamster/stack/inspect_spec.rb +0 -31
- data/spec/hamster/stack/peek_spec.rb +0 -40
- data/spec/hamster/stack/pop_spec.rb +0 -41
- data/spec/hamster/stack/push_spec.rb +0 -41
- data/spec/hamster/stack/size_spec.rb +0 -35
- data/spec/hamster/stack/to_a_spec.rb +0 -42
- data/spec/hamster/stack/to_ary.rb +0 -44
- data/spec/hamster/stack/to_list_spec.rb +0 -33
- data/spec/hamster/trie/remove_spec.rb +0 -117
- data/spec/hamster/tuple/copying_spec.rb +0 -24
- data/spec/hamster/tuple/eql_spec.rb +0 -61
- data/spec/hamster/tuple/first_spec.rb +0 -19
- data/spec/hamster/tuple/immutable_spec.rb +0 -12
- data/spec/hamster/tuple/inspect_spec.rb +0 -19
- data/spec/hamster/tuple/last_spec.rb +0 -19
- data/spec/hamster/tuple/to_a_spec.rb +0 -38
- data/spec/hamster/tuple/to_ary_spec.rb +0 -44
- data/spec/hamster/undefined/erase_spec.rb +0 -47
- data/spec/hamster/vector/add_spec.rb +0 -41
- data/spec/hamster/vector/any_spec.rb +0 -67
- data/spec/hamster/vector/clear_spec.rb +0 -36
- data/spec/hamster/vector/copying_spec.rb +0 -32
- data/spec/hamster/vector/each_spec.rb +0 -46
- data/spec/hamster/vector/each_with_index_spec.rb +0 -42
- data/spec/hamster/vector/empty_spec.rb +0 -35
- data/spec/hamster/vector/eql_spec.rb +0 -65
- data/spec/hamster/vector/filter_spec.rb +0 -63
- data/spec/hamster/vector/first_spec.rb +0 -35
- data/spec/hamster/vector/get_spec.rb +0 -81
- data/spec/hamster/vector/inspect_spec.rb +0 -31
- data/spec/hamster/vector/last_spec.rb +0 -32
- data/spec/hamster/vector/map_spec.rb +0 -64
- data/spec/hamster/vector/set_spec.rb +0 -153
- data/spec/hamster/vector/to_a_spec.rb +0 -42
- data/spec/hamster/vector/to_ary_spec.rb +0 -44
- data/tasks/bundler.rb +0 -2
- data/tasks/publish.rb +0 -12
- data/tasks/spec.rb +0 -13
data/lib/hamster/trie.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
1
|
module Hamster
|
4
|
-
|
2
|
+
# @private
|
5
3
|
class Trie
|
4
|
+
def self.[](pairs)
|
5
|
+
result = self.new(0)
|
6
|
+
pairs.each { |key, val| result.put!(key, val) }
|
7
|
+
result
|
8
|
+
end
|
6
9
|
|
7
|
-
|
10
|
+
# Returns the number of key-value pairs in the trie.
|
11
|
+
attr_reader :size
|
8
12
|
|
9
13
|
def initialize(significant_bits, size = 0, entries = [], children = [])
|
10
14
|
@significant_bits = significant_bits
|
@@ -13,27 +17,30 @@ module Hamster
|
|
13
17
|
@size = size
|
14
18
|
end
|
15
19
|
|
16
|
-
# Returns the number of key-value pairs in the trie.
|
17
|
-
def size
|
18
|
-
@size
|
19
|
-
end
|
20
|
-
|
21
20
|
# Returns <tt>true</tt> if the trie contains no key-value pairs.
|
22
21
|
def empty?
|
23
22
|
size == 0
|
24
23
|
end
|
25
24
|
|
26
25
|
# Returns <tt>true</tt> if the given key is present in the trie.
|
27
|
-
def
|
28
|
-
!!
|
26
|
+
def key?(key)
|
27
|
+
!!get(key)
|
29
28
|
end
|
30
29
|
|
31
30
|
# Calls <tt>block</tt> once for each entry in the trie, passing the key-value pair as parameters.
|
32
|
-
def each
|
31
|
+
def each(&block)
|
33
32
|
@entries.each { |entry| yield(entry) if entry }
|
34
33
|
@children.each do |child|
|
35
|
-
child.each
|
34
|
+
child.each(&block) if child
|
35
|
+
end
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def reverse_each(&block)
|
40
|
+
@children.reverse_each do |child|
|
41
|
+
child.reverse_each(&block) if child
|
36
42
|
end
|
43
|
+
@entries.reverse_each { |entry| yield(entry) if entry }
|
37
44
|
nil
|
38
45
|
end
|
39
46
|
|
@@ -42,60 +49,215 @@ module Hamster
|
|
42
49
|
memo
|
43
50
|
end
|
44
51
|
|
45
|
-
def
|
46
|
-
|
52
|
+
def select
|
53
|
+
keys_to_delete = []
|
54
|
+
each { |entry| keys_to_delete << entry[0] unless yield(entry) }
|
55
|
+
bulk_delete(keys_to_delete)
|
47
56
|
end
|
48
57
|
|
49
|
-
#
|
58
|
+
# @return [Trie] A copy of `self` with the given value associated with the
|
59
|
+
# key (or `self` if no modification was needed because an identical
|
60
|
+
# key-value pair wes already stored
|
50
61
|
def put(key, value)
|
51
62
|
index = index_for(key)
|
52
63
|
entry = @entries[index]
|
53
64
|
|
54
65
|
if !entry
|
55
66
|
entries = @entries.dup
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
67
|
+
key = key.dup.freeze if key.is_a?(String) && !key.frozen?
|
68
|
+
entries[index] = [key, value].freeze
|
69
|
+
Trie.new(@significant_bits, @size + 1, entries, @children)
|
70
|
+
elsif entry[0].eql?(key)
|
71
|
+
if entry[1].equal?(value)
|
72
|
+
self
|
73
|
+
else
|
74
|
+
entries = @entries.dup
|
75
|
+
key = key.dup.freeze if key.is_a?(String) && !key.frozen?
|
76
|
+
entries[index] = [key, value].freeze
|
77
|
+
Trie.new(@significant_bits, @size, entries, @children)
|
78
|
+
end
|
79
|
+
else
|
80
|
+
child = @children[index]
|
81
|
+
if child
|
82
|
+
new_child = child.put(key, value)
|
83
|
+
if new_child.equal?(child)
|
84
|
+
self
|
85
|
+
else
|
86
|
+
children = @children.dup
|
87
|
+
children[index] = new_child
|
88
|
+
new_self_size = @size + (new_child.size - child.size)
|
89
|
+
Trie.new(@significant_bits, new_self_size, @entries, children)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
children = @children.dup
|
93
|
+
children[index] = Trie.new(@significant_bits + 5).put!(key, value)
|
94
|
+
Trie.new(@significant_bits, @size + 1, @entries, children)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Put multiple elements into a Trie. This is more efficient than several
|
100
|
+
# calls to `#put`.
|
101
|
+
#
|
102
|
+
# @param key_value_pairs Enumerable of pairs (`[key, value]`)
|
103
|
+
# @return [Trie] A copy of `self` after associated the given keys and
|
104
|
+
# values (or `self` if no modifications where needed).
|
105
|
+
def bulk_put(key_value_pairs)
|
106
|
+
new_entries = nil
|
107
|
+
new_children = nil
|
108
|
+
new_size = @size
|
109
|
+
|
110
|
+
key_value_pairs.each do |key, value|
|
111
|
+
index = index_for(key)
|
112
|
+
entry = (new_entries || @entries)[index]
|
113
|
+
|
114
|
+
if !entry
|
115
|
+
new_entries ||= @entries.dup
|
116
|
+
key = key.dup.freeze if key.is_a?(String) && !key.frozen?
|
117
|
+
new_entries[index] = [key, value].freeze
|
118
|
+
new_size += 1
|
119
|
+
elsif entry[0].eql?(key)
|
120
|
+
if !entry[1].equal?(value)
|
121
|
+
new_entries ||= @entries.dup
|
122
|
+
key = key.dup.freeze if key.is_a?(String) && !key.frozen?
|
123
|
+
new_entries[index] = [key, value].freeze
|
124
|
+
end
|
125
|
+
else
|
126
|
+
child = (new_children || @children)[index]
|
127
|
+
if child
|
128
|
+
new_child = child.put(key, value)
|
129
|
+
if !new_child.equal?(child)
|
130
|
+
new_children ||= @children.dup
|
131
|
+
new_children[index] = new_child
|
132
|
+
new_size += new_child.size - child.size
|
133
|
+
end
|
134
|
+
else
|
135
|
+
new_children ||= @children.dup
|
136
|
+
new_children[index] = Trie.new(@significant_bits + 5).put!(key, value)
|
137
|
+
new_size += 1
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
if new_entries || new_children
|
143
|
+
Trie.new(@significant_bits, new_size, new_entries || @entries, new_children || @children)
|
144
|
+
else
|
145
|
+
self
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns <tt>self</tt> after overwriting the element associated with the specified key.
|
150
|
+
def put!(key, value)
|
151
|
+
index = index_for(key)
|
152
|
+
entry = @entries[index]
|
153
|
+
if !entry
|
154
|
+
@size += 1
|
155
|
+
key = key.dup.freeze if key.is_a?(String) && !key.frozen?
|
156
|
+
@entries[index] = [key, value].freeze
|
157
|
+
elsif entry[0].eql?(key)
|
158
|
+
key = key.dup.freeze if key.is_a?(String) && !key.frozen?
|
159
|
+
@entries[index] = [key, value].freeze
|
62
160
|
else
|
63
|
-
|
64
|
-
child
|
65
|
-
|
66
|
-
|
67
|
-
child.
|
161
|
+
child = @children[index]
|
162
|
+
if child
|
163
|
+
old_child_size = child.size
|
164
|
+
@children[index] = child.put!(key, value)
|
165
|
+
@size += child.size - old_child_size
|
68
166
|
else
|
69
|
-
|
167
|
+
@children[index] = Trie.new(@significant_bits + 5).put!(key, value)
|
168
|
+
@size += 1
|
70
169
|
end
|
71
|
-
new_child_size = children[index].size
|
72
|
-
new_self_size = @size + (new_child_size - child_size)
|
73
|
-
self.class.new(@significant_bits, new_self_size, @entries, children)
|
74
170
|
end
|
171
|
+
self
|
75
172
|
end
|
76
173
|
|
77
174
|
# Retrieves the entry corresponding to the given key. If not found, returns <tt>nil</tt>.
|
78
175
|
def get(key)
|
79
176
|
index = index_for(key)
|
80
177
|
entry = @entries[index]
|
81
|
-
if entry && entry.
|
178
|
+
if entry && entry[0].eql?(key)
|
82
179
|
entry
|
83
180
|
else
|
84
181
|
child = @children[index]
|
85
|
-
if child
|
86
|
-
child.get(key)
|
87
|
-
end
|
182
|
+
child.get(key) if child
|
88
183
|
end
|
89
184
|
end
|
90
185
|
|
91
186
|
# Returns a copy of <tt>self</tt> with the given key (and associated value) deleted. If not found, returns <tt>self</tt>.
|
92
187
|
def delete(key)
|
93
|
-
find_and_delete(key) ||
|
188
|
+
find_and_delete(key) || Trie.new(@significant_bits)
|
189
|
+
end
|
190
|
+
|
191
|
+
# Delete multiple elements from a Trie. This is more efficient than
|
192
|
+
# several calls to `#delete`.
|
193
|
+
#
|
194
|
+
# @param keys [Enumerable] The keys to delete
|
195
|
+
# @return [Trie]
|
196
|
+
def bulk_delete(keys)
|
197
|
+
new_entries = nil
|
198
|
+
new_children = nil
|
199
|
+
new_size = @size
|
200
|
+
|
201
|
+
keys.each do |key|
|
202
|
+
index = index_for(key)
|
203
|
+
entry = (new_entries || @entries)[index]
|
204
|
+
if !entry
|
205
|
+
next
|
206
|
+
elsif entry[0].eql?(key)
|
207
|
+
new_entries ||= @entries.dup
|
208
|
+
child = (new_children || @children)[index]
|
209
|
+
if child
|
210
|
+
# Bring up the first entry from the child into entries
|
211
|
+
new_children ||= @children.dup
|
212
|
+
new_children[index] = child.delete_at do |entry|
|
213
|
+
new_entries[index] = entry
|
214
|
+
end
|
215
|
+
else
|
216
|
+
new_entries[index] = nil
|
217
|
+
end
|
218
|
+
new_size -= 1
|
219
|
+
else
|
220
|
+
child = (new_children || @children)[index]
|
221
|
+
if child
|
222
|
+
copy = child.find_and_delete(key)
|
223
|
+
unless copy.equal?(child)
|
224
|
+
new_children ||= @children.dup
|
225
|
+
new_children[index] = copy
|
226
|
+
new_size -= (child.size - copy_size(copy))
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
if new_entries || new_children
|
233
|
+
Trie.new(@significant_bits, new_size, new_entries || @entries, new_children || @children)
|
234
|
+
else
|
235
|
+
self
|
236
|
+
end
|
94
237
|
end
|
95
238
|
|
96
239
|
def include?(key, value)
|
97
240
|
entry = get(key)
|
98
|
-
entry && value.eql?(entry
|
241
|
+
entry && value.eql?(entry[1])
|
242
|
+
end
|
243
|
+
|
244
|
+
def at(index)
|
245
|
+
@entries.each do |entry|
|
246
|
+
if entry
|
247
|
+
return entry if index == 0
|
248
|
+
index -= 1
|
249
|
+
end
|
250
|
+
end
|
251
|
+
@children.each do |child|
|
252
|
+
if child
|
253
|
+
if child.size >= index+1
|
254
|
+
return child.at(index)
|
255
|
+
else
|
256
|
+
index -= child.size
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
nil
|
99
261
|
end
|
100
262
|
|
101
263
|
# Returns <tt>true</tt> if . <tt>eql?</tt> is synonymous with <tt>==</tt>
|
@@ -103,40 +265,31 @@ module Hamster
|
|
103
265
|
return true if equal?(other)
|
104
266
|
return false unless instance_of?(other.class) && size == other.size
|
105
267
|
each do |entry|
|
106
|
-
return false unless other.include?(entry
|
268
|
+
return false unless other.include?(entry[0], entry[1])
|
107
269
|
end
|
108
270
|
true
|
109
271
|
end
|
110
|
-
|
272
|
+
alias :== :eql?
|
111
273
|
|
112
274
|
protected
|
113
275
|
|
114
|
-
# Returns <tt>self</tt> after overwriting the element associated with the specified key.
|
115
|
-
def put!(key, value)
|
116
|
-
index = index_for(key)
|
117
|
-
@size += 1 unless @entries[index]
|
118
|
-
@entries[index] = Entry.new(key, value)
|
119
|
-
self
|
120
|
-
end
|
121
|
-
|
122
276
|
# Returns a replacement instance after removing the specified key.
|
123
277
|
# If not found, returns <tt>self</tt>.
|
124
278
|
# If empty, returns <tt>nil</tt>.
|
125
279
|
def find_and_delete(key)
|
126
280
|
index = index_for(key)
|
127
281
|
entry = @entries[index]
|
128
|
-
if entry && entry.
|
282
|
+
if entry && entry[0].eql?(key)
|
129
283
|
return delete_at(index)
|
130
284
|
else
|
131
285
|
child = @children[index]
|
132
286
|
if child
|
133
287
|
copy = child.find_and_delete(key)
|
134
|
-
|
288
|
+
unless copy.equal?(child)
|
135
289
|
children = @children.dup
|
136
290
|
children[index] = copy
|
137
|
-
|
138
|
-
|
139
|
-
return self.class.new(@significant_bits, new_size, @entries, children)
|
291
|
+
new_size = @size - (child.size - copy_size(copy))
|
292
|
+
return Trie.new(@significant_bits, new_size, @entries, children)
|
140
293
|
end
|
141
294
|
end
|
142
295
|
end
|
@@ -157,7 +310,7 @@ module Hamster
|
|
157
310
|
else
|
158
311
|
entries[index] = nil
|
159
312
|
end
|
160
|
-
|
313
|
+
Trie.new(@significant_bits, @size - 1, entries, children || @children)
|
161
314
|
end
|
162
315
|
end
|
163
316
|
|
@@ -167,19 +320,11 @@ module Hamster
|
|
167
320
|
(key.hash.abs >> @significant_bits) & 31
|
168
321
|
end
|
169
322
|
|
170
|
-
|
171
|
-
|
172
|
-
attr_reader :key, :value
|
173
|
-
|
174
|
-
def initialize(key, value)
|
175
|
-
@key = key
|
176
|
-
@value = value
|
177
|
-
end
|
178
|
-
|
323
|
+
def copy_size(copy)
|
324
|
+
copy ? copy.size : 0
|
179
325
|
end
|
180
|
-
|
181
326
|
end
|
182
327
|
|
183
|
-
|
184
|
-
|
328
|
+
# @private
|
329
|
+
EmptyTrie = Hamster::Trie.new(0)
|
185
330
|
end
|
data/lib/hamster/undefined.rb
CHANGED
data/lib/hamster/vector.rb
CHANGED
@@ -1,163 +1,1409 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
4
|
-
require 'hamster/immutable'
|
5
|
-
require 'hamster/enumerable'
|
1
|
+
require "hamster/immutable"
|
2
|
+
require "hamster/enumerable"
|
3
|
+
require "hamster/hash"
|
6
4
|
|
7
5
|
module Hamster
|
8
|
-
|
6
|
+
# Create a new `Vector` populated with the given items.
|
7
|
+
# [Vector]
|
9
8
|
def self.vector(*items)
|
10
|
-
items.
|
9
|
+
items.empty? ? EmptyVector : Vector.new(items.freeze)
|
11
10
|
end
|
12
11
|
|
12
|
+
# A `Vector` is an ordered, integer-indexed collection of objects. Like `Array`,
|
13
|
+
# `Vector` indexing starts at 0. Also like `Array`, negative indexes count back
|
14
|
+
# from the end of the `Vector`.
|
15
|
+
#
|
16
|
+
# `Vector`'s interface is modeled after that of `Array`, minus all the methods
|
17
|
+
# which do destructive updates. Some methods which modify `Array`s destructively
|
18
|
+
# (like {#insert} or {#delete_at}) are included, but they return new `Vectors`
|
19
|
+
# and leave the existing one unchanged.
|
20
|
+
#
|
21
|
+
# ### Creating New Vectors
|
22
|
+
#
|
23
|
+
# Hamster.vector('a', 'b', 'c')
|
24
|
+
# Hamster::Vector.new([:first, :second, :third])
|
25
|
+
# Hamster::Vector[1, 2, 3, 4, 5]
|
26
|
+
#
|
27
|
+
# ### Retrieving Items from Vectors
|
28
|
+
#
|
29
|
+
# require 'hamster/vector'
|
30
|
+
# vector = Hamster.vector(1, 2, 3, 4, 5)
|
31
|
+
# vector[0] # => 1
|
32
|
+
# vector[-1] # => 5
|
33
|
+
# vector[0,3] # => Hamster::Vector[1, 2, 3]
|
34
|
+
# vector[1..-1] # => Hamster::Vector[2, 3, 4, 5]
|
35
|
+
# vector.first # => 1
|
36
|
+
# vector.last # => 5
|
37
|
+
#
|
38
|
+
# ### Creating Modified Vectors
|
39
|
+
#
|
40
|
+
# vector.add(6) # => Hamster::Vector[1, 2, 3, 4, 5, 6]
|
41
|
+
# vector.insert(1, :a, :b) # => Hamster::Vector[1, :a, :b, 2, 3, 4, 5]
|
42
|
+
# vector.delete_at(2) # => Hamster::Vector[1, 2, 4, 5]
|
43
|
+
# vector + [6, 7] # => Hamster::Vector[1, 2, 3, 4, 5, 6, 7]
|
44
|
+
#
|
45
|
+
# Other `Array`-like methods like {#select}, {#map}, {#shuffle}, {#uniq}, {#reverse},
|
46
|
+
# {#rotate}, {#flatten}, {#sort}, {#sort_by}, {#take}, {#drop}, {#take_while},
|
47
|
+
# {#drop_while}, {#fill}, {#product}, and {#transpose} are also supported.
|
48
|
+
#
|
13
49
|
class Vector
|
14
|
-
|
15
|
-
extend Forwardable
|
16
|
-
|
17
50
|
include Immutable
|
18
|
-
|
19
51
|
include Enumerable
|
20
52
|
|
53
|
+
# @private
|
21
54
|
BLOCK_SIZE = 32
|
55
|
+
# @private
|
22
56
|
INDEX_MASK = BLOCK_SIZE - 1
|
57
|
+
# @private
|
23
58
|
BITS_PER_LEVEL = 5
|
24
59
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
60
|
+
# Return the number of items in this `Vector`
|
61
|
+
# @return [Integer]
|
62
|
+
attr_reader :size
|
63
|
+
alias :length :size
|
64
|
+
|
65
|
+
class << self
|
66
|
+
# Create a new `Vector` populated with the given items.
|
67
|
+
# @return [Vector]
|
68
|
+
def [](*items)
|
69
|
+
new(items.freeze)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return an empty `Vector`. If used on a subclass, returns an empty instance
|
73
|
+
# of that class.
|
74
|
+
#
|
75
|
+
# @return [Vector]
|
76
|
+
def empty
|
77
|
+
@empty ||= self.new
|
78
|
+
end
|
79
|
+
|
80
|
+
# "Raw" allocation of a new `Vector`. Used internally to create a new
|
81
|
+
# instance quickly after building a modified trie.
|
82
|
+
#
|
83
|
+
# @return [Vector]
|
84
|
+
# @private
|
85
|
+
def alloc(root, size, levels)
|
86
|
+
obj = allocate
|
87
|
+
obj.instance_variable_set(:@root, root)
|
88
|
+
obj.instance_variable_set(:@size, size)
|
89
|
+
obj.instance_variable_set(:@levels, levels)
|
90
|
+
obj
|
91
|
+
end
|
29
92
|
end
|
30
93
|
|
31
|
-
def
|
32
|
-
|
94
|
+
def initialize(items=[].freeze)
|
95
|
+
items = items.to_a
|
96
|
+
if items.size <= 32
|
97
|
+
items = items.dup.freeze if !items.frozen?
|
98
|
+
@root, @size, @levels = items, items.size, 0
|
99
|
+
else
|
100
|
+
root, size, levels = items, items.size, 0
|
101
|
+
while root.size > 32
|
102
|
+
root = root.each_slice(32).to_a
|
103
|
+
levels += 1
|
104
|
+
end
|
105
|
+
@root, @size, @levels = root.freeze, size, levels
|
106
|
+
end
|
33
107
|
end
|
34
|
-
def_delegator :self, :empty?, :null?
|
35
108
|
|
36
|
-
|
37
|
-
|
109
|
+
# Return `true` if this `Vector` contains no items.
|
110
|
+
#
|
111
|
+
# @return [Boolean]
|
112
|
+
def empty?
|
113
|
+
@size == 0
|
38
114
|
end
|
39
|
-
def_delegator :self, :size, :length
|
40
115
|
|
116
|
+
# Return the first item in the `Vector`. If the vector is empty, return `nil`.
|
117
|
+
#
|
118
|
+
# @example
|
119
|
+
# Hamster::Vector["A", "B", "C"].first # => "A"
|
120
|
+
#
|
121
|
+
# @return [Object]
|
41
122
|
def first
|
42
123
|
get(0)
|
43
124
|
end
|
44
|
-
def_delegator :self, :first, :head
|
45
125
|
|
126
|
+
# Return the last item in the `Vector`. If the vector is empty, return `nil`.
|
127
|
+
#
|
128
|
+
# @example
|
129
|
+
# Hamster::Vector["A", "B", "C"].last # => "C"
|
130
|
+
#
|
131
|
+
# @return [Object]
|
46
132
|
def last
|
47
133
|
get(-1)
|
48
134
|
end
|
49
135
|
|
136
|
+
# Return a new `Vector` with `item` added after the last occupied position.
|
137
|
+
#
|
138
|
+
# @example
|
139
|
+
# Hamster::Vector[1, 2].add(99) # => Hamster::Vector[1, 2, 99]
|
140
|
+
#
|
141
|
+
# @param item [Object] The object to insert at the end of the vector
|
142
|
+
# @return [Vector]
|
50
143
|
def add(item)
|
51
|
-
|
52
|
-
update_leaf_node(@size, item)
|
53
|
-
@size += 1
|
54
|
-
end
|
144
|
+
update_root(@size, item)
|
55
145
|
end
|
56
|
-
|
57
|
-
|
146
|
+
alias :<< :add
|
147
|
+
alias :push :add
|
58
148
|
|
59
|
-
#
|
60
|
-
#
|
149
|
+
# Return a new `Vector` with the item at `index` replaced by `item`. If the
|
150
|
+
# `item` argument is missing, but an optional code block is provided, it will
|
151
|
+
# be passed the existing item and what the block returns will replace it.
|
152
|
+
#
|
153
|
+
# @example
|
154
|
+
# Hamster::Vector[1, 2, 3, 4].set(2, 99)
|
155
|
+
# # => Hamster::Vector[1, 2, 99, 4]
|
156
|
+
# Hamster::Vector[1, 2, 3, 4].set(2) { |v| v * 10 }
|
157
|
+
# # => Hamster::Vector[1, 2, 30, 4]
|
158
|
+
#
|
159
|
+
# @param index [Integer] The index to update
|
160
|
+
# @param item [Object] The object to insert into that position
|
161
|
+
# @return [Vector]
|
162
|
+
def set(index, item = yield(get(index)))
|
163
|
+
raise IndexError, "index #{index} outside of vector bounds" if index < -@size
|
164
|
+
index += @size if index < 0
|
165
|
+
if index > @size
|
166
|
+
suffix = Array.new(index - @size, nil)
|
167
|
+
suffix << item
|
168
|
+
replace_suffix(@size, suffix)
|
169
|
+
else
|
170
|
+
update_root(index, item)
|
171
|
+
end
|
172
|
+
end
|
61
173
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
174
|
+
# Return a new `Vector` with a deeply nested value modified to the result
|
175
|
+
# of the given code block. When traversing the nested `Vector`s and
|
176
|
+
# `Hash`es, non-existing keys are created with empty `Hash` values.
|
177
|
+
#
|
178
|
+
# The code block receives the existing value of the deeply nested key (or
|
179
|
+
# `nil` if it doesn't exist). This is useful for "transforming" the value
|
180
|
+
# associated with a certain key.
|
181
|
+
#
|
182
|
+
# Note that the original `Vector` and sub-`Vector`s and sub-`Hash`es are
|
183
|
+
# left unmodified; new data structure copies are created along the path
|
184
|
+
# wherever needed.
|
185
|
+
#
|
186
|
+
# @example
|
187
|
+
# v = Hamster::Vector[123, 456, 789, Hamster::Hash["a" => Hamster::Vector[5, 6, 7]]]
|
188
|
+
# v.update_in(3, "a", 1) { |value| value + 9 }
|
189
|
+
# # => Hamster::Vector[123, 456, 789, Hamster::Hash["a" => Hamster::Vector[5, 15, 7]]]
|
190
|
+
#
|
191
|
+
# @param key_path [Object(s)] List of keys which form the path to the key to be modified
|
192
|
+
# @yield [value] The previously stored value
|
193
|
+
# @yieldreturn [Object] The new value to store
|
194
|
+
# @return [Hash]
|
195
|
+
def update_in(*key_path, &block)
|
196
|
+
if key_path.empty?
|
197
|
+
raise ArgumentError, "must have at least one key in path"
|
198
|
+
end
|
199
|
+
key = key_path[0]
|
200
|
+
if key_path.size == 1
|
201
|
+
new_value = block.call(get(key))
|
202
|
+
else
|
203
|
+
value = fetch(key, EmptyHash)
|
204
|
+
new_value = value.update_in(*key_path[1..-1], &block)
|
69
205
|
end
|
206
|
+
set(key, new_value)
|
70
207
|
end
|
71
208
|
|
209
|
+
# Retrieve the item at `index`. If there is none (either the provided index
|
210
|
+
# is too high or too low), return `nil`.
|
211
|
+
#
|
212
|
+
# @example
|
213
|
+
# v = Hamster::Vector["A", "B", "C", "D"]
|
214
|
+
# v.get(2) # => "C"
|
215
|
+
# v.get(-1) # => "D"
|
216
|
+
# v.get(4) # => nil
|
217
|
+
#
|
218
|
+
# @param index [Integer] The index to retrieve
|
219
|
+
# @return [Object]
|
72
220
|
def get(index)
|
73
|
-
return nil if
|
74
|
-
|
75
|
-
return
|
76
|
-
leaf_node_for(@root,
|
221
|
+
return nil if @size == 0
|
222
|
+
index += @size if index < 0
|
223
|
+
return nil if index >= @size || index < 0
|
224
|
+
leaf_node_for(@root, @levels * BITS_PER_LEVEL, index)[index & INDEX_MASK]
|
225
|
+
end
|
226
|
+
alias :at :get
|
227
|
+
|
228
|
+
# Retrieve the value at `index`, or use the provided default value or block,
|
229
|
+
# or otherwise raise an `IndexError`.
|
230
|
+
#
|
231
|
+
# @overload fetch(index)
|
232
|
+
# Retrieve the value at the given index, or raise an `IndexError` if it is
|
233
|
+
# not found.
|
234
|
+
# @param index [Integer] The index to look up
|
235
|
+
# @overload fetch(index) { |index| ... }
|
236
|
+
# Retrieve the value at the given index, or call the optional
|
237
|
+
# code block (with the non-existent index) and get its return value.
|
238
|
+
# @yield [index] The index which does not exist
|
239
|
+
# @yieldreturn [Object] Object to return instead
|
240
|
+
# @param index [Integer] The index to look up
|
241
|
+
# @overload fetch(index, default)
|
242
|
+
# Retrieve the value at the given index, or else return the provided
|
243
|
+
# `default` value.
|
244
|
+
# @param index [Integer] The index to look up
|
245
|
+
# @param default [Object] Object to return if the key is not found
|
246
|
+
#
|
247
|
+
# @example
|
248
|
+
# v = Hamster::Vector["A", "B", "C", "D"]
|
249
|
+
# v.fetch(2) # => "C"
|
250
|
+
# v.fetch(-1) # => "D"
|
251
|
+
# v.fetch(4) # => IndexError: index 4 outside of vector bounds
|
252
|
+
# # With default value:
|
253
|
+
# v.fetch(2, "Z") # => "C"
|
254
|
+
# v.fetch(4, "Z") # => "Z"
|
255
|
+
# # With block:
|
256
|
+
# v.fetch(2) { |i| i * i } # => "C"
|
257
|
+
# v.fetch(4) { |i| i * i } # => 16
|
258
|
+
#
|
259
|
+
# @return [Object]
|
260
|
+
def fetch(index, default = (missing_default = true))
|
261
|
+
if index >= -@size && index < @size
|
262
|
+
get(index)
|
263
|
+
elsif block_given?
|
264
|
+
yield(index)
|
265
|
+
elsif !missing_default
|
266
|
+
default
|
267
|
+
else
|
268
|
+
raise IndexError, "index #{index} outside of vector bounds"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# Element reference. Return the item at a specific index, or a specified,
|
273
|
+
# contiguous range of items (as a new `Vector`).
|
274
|
+
#
|
275
|
+
# @overload vector[index]
|
276
|
+
# Return the item at `index`.
|
277
|
+
# @param index [Integer] The index to retrieve.
|
278
|
+
# @overload vector[start, length]
|
279
|
+
# Return a subvector starting at index `start` and continuing for `length` elements.
|
280
|
+
# @param start [Integer] The index to start retrieving items from.
|
281
|
+
# @param length [Integer] The number of items to retrieve.
|
282
|
+
# @overload vector[range]
|
283
|
+
# Return a subvector specified by the given `range` of indices.
|
284
|
+
# @param range [Range] The range of indices to retrieve.
|
285
|
+
#
|
286
|
+
# @example
|
287
|
+
# v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
|
288
|
+
# v[2] # => "C"
|
289
|
+
# v[-1] # => "D"
|
290
|
+
# v[6] # => nil
|
291
|
+
# v[2, 2] # => Hamster::Vector["C", "D"]
|
292
|
+
# v[2..3] # => Hamster::Vector["C", "D"]
|
293
|
+
#
|
294
|
+
# @return [Object]
|
295
|
+
def [](arg, length = (missing_length = true))
|
296
|
+
if missing_length
|
297
|
+
if arg.is_a?(Range)
|
298
|
+
from, to = arg.begin, arg.end
|
299
|
+
from += @size if from < 0
|
300
|
+
to += @size if to < 0
|
301
|
+
to += 1 if !arg.exclude_end?
|
302
|
+
length = to - from
|
303
|
+
length = 0 if length < 0
|
304
|
+
subsequence(from, length)
|
305
|
+
else
|
306
|
+
get(arg)
|
307
|
+
end
|
308
|
+
else
|
309
|
+
arg += @size if arg < 0
|
310
|
+
subsequence(arg, length)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
alias :slice :[]
|
314
|
+
|
315
|
+
# Return a new `Vector` with the given values inserted before the element at `index`.
|
316
|
+
#
|
317
|
+
# @example
|
318
|
+
# Hamster::Vector["A", "B", "C", "D"].insert(2, "X", "Y", "Z")
|
319
|
+
# # => Hamster::Vector["A", "B", "X", "Y", "Z", "C", "D"]
|
320
|
+
#
|
321
|
+
# @param index [Integer] The index where the new items should go
|
322
|
+
# @param items [Array] The items to add
|
323
|
+
# @return [Vector]
|
324
|
+
def insert(index, *items)
|
325
|
+
raise IndexError if index < -@size
|
326
|
+
index += @size if index < 0
|
327
|
+
|
328
|
+
if index < @size
|
329
|
+
suffix = flatten_suffix(@root, @levels * BITS_PER_LEVEL, index, [])
|
330
|
+
suffix.unshift(*items)
|
331
|
+
elsif index == @size
|
332
|
+
suffix = items
|
333
|
+
else
|
334
|
+
suffix = Array.new(index - @size, nil).concat(items)
|
335
|
+
index = @size
|
336
|
+
end
|
337
|
+
|
338
|
+
replace_suffix(index, suffix)
|
339
|
+
end
|
340
|
+
|
341
|
+
# Return a new `Vector` with the element at `index` removed. If the given `index`
|
342
|
+
# does not exist, return `self`.
|
343
|
+
#
|
344
|
+
# @example
|
345
|
+
# Hamster::Vector["A", "B", "C", "D"].delete_at(2)
|
346
|
+
# # => Hamster::Vector["A", "B", "D"]
|
347
|
+
#
|
348
|
+
# @param index [Integer] The index to remove
|
349
|
+
# @return [Vector]
|
350
|
+
def delete_at(index)
|
351
|
+
return self if index >= @size || index < -@size
|
352
|
+
index += @size if index < 0
|
353
|
+
|
354
|
+
suffix = flatten_suffix(@root, @levels * BITS_PER_LEVEL, index, [])
|
355
|
+
replace_suffix(index, suffix.tap { |a| a.shift })
|
356
|
+
end
|
357
|
+
|
358
|
+
# Return a new `Vector` with the last element removed. If empty, just return `self`.
|
359
|
+
#
|
360
|
+
# @example
|
361
|
+
# Hamster::Vector["A", "B", "C"].pop # => Hamster::Vector["A", "B"]
|
362
|
+
#
|
363
|
+
# @return [Vector]
|
364
|
+
def pop
|
365
|
+
return self if @size == 0
|
366
|
+
replace_suffix(@size-1, [])
|
367
|
+
end
|
368
|
+
|
369
|
+
# Return a new `Vector` with `obj` inserted before the first element, moving
|
370
|
+
# the other elements upwards.
|
371
|
+
#
|
372
|
+
# @example
|
373
|
+
# Hamster::Vector["A", "B"].unshift("Z") # => Hamster::Vector["Z", "A", "B"]
|
374
|
+
#
|
375
|
+
# @param obj [Object] The value to prepend
|
376
|
+
# @return [Vector]
|
377
|
+
def unshift(obj)
|
378
|
+
insert(0, obj)
|
379
|
+
end
|
380
|
+
|
381
|
+
# Return a new `Vector` with the first element removed. If empty, just return `self`.
|
382
|
+
#
|
383
|
+
# @example
|
384
|
+
# Hamster::Vector["A", "B", "C"].shift # => Hamster::Vector["B", "C"]
|
385
|
+
#
|
386
|
+
# @return [Vector]
|
387
|
+
def shift
|
388
|
+
delete_at(0)
|
77
389
|
end
|
78
|
-
def_delegator :self, :get, :[]
|
79
|
-
def_delegator :self, :get, :at
|
80
390
|
|
391
|
+
# Call the given block once for each item in the vector, passing each
|
392
|
+
# item from first to last successively to the block.
|
393
|
+
#
|
394
|
+
# @example
|
395
|
+
# Hamster::Vector["A", "B", "C"].each { |e| puts "Element: #{e}" }
|
396
|
+
#
|
397
|
+
# Element: A
|
398
|
+
# Element: B
|
399
|
+
# Element: C
|
400
|
+
# # => Hamster::Vector["A", "B", "C"]
|
401
|
+
#
|
402
|
+
# @return [self]
|
81
403
|
def each(&block)
|
82
|
-
return
|
83
|
-
traverse_depth_first(&block)
|
84
|
-
|
404
|
+
return to_enum unless block_given?
|
405
|
+
traverse_depth_first(@root, @levels, &block)
|
406
|
+
self
|
407
|
+
end
|
408
|
+
|
409
|
+
# Call the given block once for each item in the vector, passing each
|
410
|
+
# item starting from the last, and counting back to the first, successively to
|
411
|
+
# the block.
|
412
|
+
#
|
413
|
+
# @example
|
414
|
+
# Hamster::Vector["A", "B", "C"].reverse_each { |e| puts "Element: #{e}" }
|
415
|
+
#
|
416
|
+
# Element: C
|
417
|
+
# Element: B
|
418
|
+
# Element: A
|
419
|
+
#
|
420
|
+
# @return [self]
|
421
|
+
def reverse_each(&block)
|
422
|
+
return enum_for(:reverse_each) unless block_given?
|
423
|
+
reverse_traverse_depth_first(@root, @levels, &block)
|
424
|
+
self
|
425
|
+
end
|
426
|
+
|
427
|
+
# Return a new `Vector` containing all elements for which the given block returns
|
428
|
+
# true.
|
429
|
+
#
|
430
|
+
# @example
|
431
|
+
# Hamster::Vector["Bird", "Cow", "Elephant"].select { |e| e.size >= 4 }
|
432
|
+
# # => Hamster::Vector["Bird", "Elephant"]
|
433
|
+
#
|
434
|
+
# @return [Vector]
|
435
|
+
def select
|
436
|
+
return enum_for(:select) unless block_given?
|
437
|
+
reduce(self.class.empty) { |vector, item| yield(item) ? vector.add(item) : vector }
|
438
|
+
end
|
439
|
+
alias :find_all :select
|
440
|
+
alias :keep_if :select
|
441
|
+
|
442
|
+
# Return a new `Vector` with all items which are equal to `obj` removed.
|
443
|
+
# `#==` is used for checking equality.
|
444
|
+
#
|
445
|
+
# @example
|
446
|
+
# Hamster::Vector["C", "B", "A", "B"].delete("B") # => Hamster::Vector["C", "A"]
|
447
|
+
#
|
448
|
+
# @param obj [Object] The object to remove (every occurrence)
|
449
|
+
# @return [Vector]
|
450
|
+
def delete(obj)
|
451
|
+
select { |item| item != obj }
|
452
|
+
end
|
453
|
+
|
454
|
+
# Invoke the given block once for each item in the vector, and return a new
|
455
|
+
# `Vector` containing the values returned by the block.
|
456
|
+
#
|
457
|
+
# @example
|
458
|
+
# Hamster::Vector[3, 2, 1].map { |e| e * e } # => Hamster::Vector[9, 4, 1]
|
459
|
+
#
|
460
|
+
# @return [Vector]
|
461
|
+
def map
|
462
|
+
return enum_for(:map) if not block_given?
|
463
|
+
return self if empty?
|
464
|
+
self.class.new(super)
|
85
465
|
end
|
466
|
+
alias :collect :map
|
86
467
|
|
87
|
-
|
88
|
-
|
89
|
-
|
468
|
+
# Return a new `Vector` with the concatenated results of running the block once
|
469
|
+
# for every element in this `Vector`.
|
470
|
+
#
|
471
|
+
# @example
|
472
|
+
# Hamster.vector(1, 2, 3).flat_map { |x| [x, -x] }
|
473
|
+
# # => Hamster::Vector[1, -1, 2, -2, 3, -3]
|
474
|
+
#
|
475
|
+
# @return [Vector]
|
476
|
+
def flat_map
|
477
|
+
return enum_for(:flat_map) if not block_given?
|
478
|
+
return self if empty?
|
479
|
+
self.class.new(super)
|
90
480
|
end
|
91
|
-
def_delegator :self, :map, :collect
|
92
481
|
|
93
|
-
|
94
|
-
|
95
|
-
|
482
|
+
# Return a new `Vector` with the same elements as this one, but randomly permuted.
|
483
|
+
#
|
484
|
+
# @example
|
485
|
+
# Hamster::Vector[1, 2, 3, 4].shuffle # => Hamster::Vector[4, 1, 3, 2]
|
486
|
+
#
|
487
|
+
# @return [Vector]
|
488
|
+
def shuffle
|
489
|
+
self.class.new(((array = to_a).frozen? ? array.shuffle : array.shuffle!).freeze)
|
490
|
+
end
|
491
|
+
|
492
|
+
# Return a new `Vector` with no duplicate elements, as determined by `#hash` and
|
493
|
+
# `#eql?`. For each group of equivalent elements, only the first will be retained.
|
494
|
+
#
|
495
|
+
# @example
|
496
|
+
# Hamster::Vector["A", "B", "C", "B"].uniq # => Hamster::Vector["A", "B", "C"]
|
497
|
+
#
|
498
|
+
# @return [Vector]
|
499
|
+
def uniq
|
500
|
+
self.class.new(((array = to_a).frozen? ? array.uniq : array.uniq!).freeze)
|
501
|
+
end
|
502
|
+
|
503
|
+
# Return a new `Vector` with the same elements as this one, but in reverse order.
|
504
|
+
#
|
505
|
+
# @example
|
506
|
+
# Hamster::Vector["A", "B", "C"].reverse # => Hamster::Vector["C", "B", "A"]
|
507
|
+
#
|
508
|
+
# @return [Vector]
|
509
|
+
def reverse
|
510
|
+
self.class.new(((array = to_a).frozen? ? array.reverse : array.reverse!).freeze)
|
511
|
+
end
|
512
|
+
|
513
|
+
# Return a new `Vector` with the same elements, but rotated so that the one at
|
514
|
+
# index `count` is the first element of the new vector. If `count` is positive,
|
515
|
+
# the elements will be shifted left, and those shifted past the lowest position
|
516
|
+
# will be moved to the end. If `count` is negative, the elements will be shifted
|
517
|
+
# right, and those shifted past the last position will be moved to the beginning.
|
518
|
+
#
|
519
|
+
# @example
|
520
|
+
# v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
|
521
|
+
# v.rotate(2) # => Hamster::Vector["C", "D", "E", "F", "A", "B"]
|
522
|
+
# v.rotate(-1) # => Hamster::Vector["F", "A", "B", "C", "D", "E"]
|
523
|
+
#
|
524
|
+
# @param count [Integer] The number of positions to shift items by
|
525
|
+
# @return [Vector]
|
526
|
+
def rotate(count = 1)
|
527
|
+
return self if (count % @size) == 0
|
528
|
+
self.class.new(((array = to_a).frozen? ? array.rotate(count) : array.rotate!(count)).freeze)
|
529
|
+
end
|
530
|
+
|
531
|
+
# Return a new `Vector` with all nested vectors and arrays recursively "flattened
|
532
|
+
# out", that is, their elements inserted into the new `Vector` in the place where
|
533
|
+
# the nested array/vector originally was. If an optional `level` argument is
|
534
|
+
# provided, the flattening will only be done recursively that number of times.
|
535
|
+
# A `level` of 0 means not to flatten at all, 1 means to only flatten nested
|
536
|
+
# arrays/vectors which are directly contained within this `Vector`.
|
537
|
+
#
|
538
|
+
# @example
|
539
|
+
# v = Hamster::Vector["A", Hamster::Vector["B", "C", Hamster::Vector["D"]]]
|
540
|
+
# v.flatten(1)
|
541
|
+
# # => Hamster::Vector["A", "B", "C", Hamster::Vector["D"]]
|
542
|
+
# v.flatten
|
543
|
+
# # => Hamster::Vector["A", "B", "C", "D"]
|
544
|
+
#
|
545
|
+
# @param level [Integer] The depth to which flattening should be applied
|
546
|
+
# @return [Vector]
|
547
|
+
def flatten(level = -1)
|
548
|
+
return self if level == 0
|
549
|
+
self.class.new(((array = to_a).frozen? ? array.flatten(level) : array.flatten!(level)).freeze)
|
550
|
+
end
|
551
|
+
|
552
|
+
# Return a new `Vector` built by concatenating this one with `other`. `other`
|
553
|
+
# can be any object which is convertible to an `Array` using `#to_a`.
|
554
|
+
#
|
555
|
+
# @example
|
556
|
+
# Hamster::Vector["A", "B", "C"] + ["D", "E"]
|
557
|
+
# # => Hamster::Vector["A", "B", "C", "D", "E"]
|
558
|
+
#
|
559
|
+
# @param other [Enumerable] The collection to concatenate onto this vector
|
560
|
+
# @return [Vector]
|
561
|
+
def +(other)
|
562
|
+
other = other.to_a
|
563
|
+
other = other.dup if other.frozen?
|
564
|
+
replace_suffix(@size, other)
|
565
|
+
end
|
566
|
+
alias :concat :+
|
567
|
+
|
568
|
+
# `others` should be arrays and/or vectors. The corresponding elements from this
|
569
|
+
# `Vector` and each of `others` (that is, the elements with the same indices)
|
570
|
+
# will be gathered into arrays.
|
571
|
+
#
|
572
|
+
# If an optional block is provided, each such array will be passed successively
|
573
|
+
# to the block. Otherwise, a new `Vector` of all those arrays will be returned.
|
574
|
+
#
|
575
|
+
# @example
|
576
|
+
# v1 = Hamster::Vector["A", "B", "C"]
|
577
|
+
# v2 = Hamster::Vector[1, 2, 3]
|
578
|
+
# v1.zip(v2)
|
579
|
+
# # => Hamster::Vector[["A", 1], ["B", 2], ["C", 3]]
|
580
|
+
#
|
581
|
+
# @param others [Array] The arrays/vectors to zip together with this one
|
582
|
+
# @return [Vector, nil]
|
583
|
+
def zip(*others)
|
584
|
+
if block_given?
|
585
|
+
super
|
586
|
+
else
|
587
|
+
self.class.new(super)
|
588
|
+
end
|
96
589
|
end
|
97
590
|
|
591
|
+
# Return a new `Vector` with the same items, but sorted. The sort order will
|
592
|
+
# be determined by comparing items using `#<=>`, or if an optional code block
|
593
|
+
# is provided, by using it as a comparator. The block should accept 2 parameters,
|
594
|
+
# and should return 0, 1, or -1 if the first parameter is equal to, greater than,
|
595
|
+
# or less than the second parameter (respectively).
|
596
|
+
#
|
597
|
+
# @example
|
598
|
+
# Hamster::Vector["Elephant", "Dog", "Lion"].sort
|
599
|
+
# # => Hamster::Vector["Dog", "Elephant", "Lion"]
|
600
|
+
# Hamster::Vector["Elephant", "Dog", "Lion"].sort { |a,b| a.size <=> b.size }
|
601
|
+
# # => Hamster::Vector["Dog", "Lion", "Elephant"]
|
602
|
+
#
|
603
|
+
# @return [Vector]
|
604
|
+
def sort
|
605
|
+
self.class.new(super)
|
606
|
+
end
|
607
|
+
|
608
|
+
# Return a new `Vector` with the same items, but sorted. The sort order will be
|
609
|
+
# determined by mapping the items through the given block to obtain sort keys,
|
610
|
+
# and then sorting the keys according to their natural sort order.
|
611
|
+
#
|
612
|
+
# @example
|
613
|
+
# Hamster::Vector["Elephant", "Dog", "Lion"].sort_by { |e| e.size }
|
614
|
+
# # => Hamster::Vector["Dog", "Lion", "Elephant"]
|
615
|
+
#
|
616
|
+
# @return [Vector]
|
617
|
+
def sort_by
|
618
|
+
self.class.new(super)
|
619
|
+
end
|
620
|
+
|
621
|
+
# Drop the first `n` elements and return the rest in a new `Vector`.
|
622
|
+
#
|
623
|
+
# @example
|
624
|
+
# Hamster::Vector["A", "B", "C", "D", "E", "F"].drop(2)
|
625
|
+
# # => Hamster::Vector["C", "D", "E", "F"]
|
626
|
+
#
|
627
|
+
# @param n [Integer] The number of elements to remove
|
628
|
+
# @return [Vector]
|
629
|
+
def drop(n)
|
630
|
+
return self if n == 0
|
631
|
+
return self.class.empty if n >= @size
|
632
|
+
raise ArgumentError, "attempt to drop negative size" if n < 0
|
633
|
+
self.class.new(flatten_suffix(@root, @levels * BITS_PER_LEVEL, n, []))
|
634
|
+
end
|
635
|
+
|
636
|
+
# Return only the first `n` elements in a new `Vector`.
|
637
|
+
#
|
638
|
+
# @example
|
639
|
+
# Hamster::Vector["A", "B", "C", "D", "E", "F"].take(4)
|
640
|
+
# # => Hamster::Vector["A", "B", "C", "D"]
|
641
|
+
#
|
642
|
+
# @param n [Integer] The number of elements to retain
|
643
|
+
# @return [Vector]
|
644
|
+
def take(n)
|
645
|
+
return self if n >= @size
|
646
|
+
self.class.new(super)
|
647
|
+
end
|
648
|
+
|
649
|
+
# Drop elements up to, but not including, the first element for which the
|
650
|
+
# block returns `nil` or `false`. Gather the remaining elements into a new
|
651
|
+
# `Vector`. If no block is given, an `Enumerator` is returned instead.
|
652
|
+
#
|
653
|
+
# @example
|
654
|
+
# Hamster::Vector[1, 3, 5, 7, 6, 4, 2].drop_while { |e| e < 5 }
|
655
|
+
# # => Hamster::Vector[5, 7, 6, 4, 2]
|
656
|
+
#
|
657
|
+
# @return [Vector, Enumerator]
|
658
|
+
def drop_while
|
659
|
+
return enum_for(:drop_while) if not block_given?
|
660
|
+
self.class.new(super)
|
661
|
+
end
|
662
|
+
|
663
|
+
# Gather elements up to, but not including, the first element for which the
|
664
|
+
# block returns `nil` or `false`, and return them in a new `Vector`. If no block
|
665
|
+
# is given, an `Enumerator` is returned instead.
|
666
|
+
#
|
667
|
+
# @example
|
668
|
+
# Hamster::Vector[1, 3, 5, 7, 6, 4, 2].take_while { |e| e < 5 }
|
669
|
+
# # => Hamster::Vector[1, 3]
|
670
|
+
#
|
671
|
+
# @return [Vector, Enumerator]
|
672
|
+
def take_while
|
673
|
+
return enum_for(:take_while) if not block_given?
|
674
|
+
self.class.new(super)
|
675
|
+
end
|
676
|
+
|
677
|
+
# Repetition. Return a new `Vector` built by concatenating `times` copies
|
678
|
+
# of this one together.
|
679
|
+
#
|
680
|
+
# @example
|
681
|
+
# Hamster::Vector["A", "B"] * 3
|
682
|
+
# # => Hamster::Vector["A", "B", "A", "B", "A", "B"]
|
683
|
+
#
|
684
|
+
# @param times [Integer] The number of times to repeat the elements in this vector
|
685
|
+
# @return [Vector]
|
686
|
+
def *(times)
|
687
|
+
return self.class.empty if times == 0
|
688
|
+
return self if times == 1
|
689
|
+
result = (to_a * times)
|
690
|
+
result.is_a?(Array) ? self.class.new(result) : result
|
691
|
+
end
|
692
|
+
|
693
|
+
# Replace a range of indexes with the given object.
|
694
|
+
#
|
695
|
+
# @overload fill(obj)
|
696
|
+
# Return a new `Vector` of the same size, with every index set to `obj`.
|
697
|
+
# @overload fill(obj, start)
|
698
|
+
# Return a new `Vector` with all indexes from `start` to the end of the
|
699
|
+
# vector set to `obj`.
|
700
|
+
# @overload fill(obj, start, length)
|
701
|
+
# Return a new `Vector` with `length` indexes, beginning from `start`,
|
702
|
+
# set to `obj`.
|
703
|
+
#
|
704
|
+
# @example
|
705
|
+
# v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
|
706
|
+
# v.fill("Z")
|
707
|
+
# # => Hamster::Vector["Z", "Z", "Z", "Z", "Z", "Z"]
|
708
|
+
# v.fill("Z", 3)
|
709
|
+
# # => Hamster::Vector["A", "B", "C", "Z", "Z", "Z"]
|
710
|
+
# v.fill("Z", 3, 2)
|
711
|
+
# # => Hamster::Vector["A", "B", "C", "Z", "Z", "F"]
|
712
|
+
#
|
713
|
+
# @return [Vector]
|
714
|
+
def fill(obj, index = 0, length = nil)
|
715
|
+
raise IndexError if index < -@size
|
716
|
+
index += @size if index < 0
|
717
|
+
length ||= @size - index # to the end of the array, if no length given
|
718
|
+
|
719
|
+
if index < @size
|
720
|
+
suffix = flatten_suffix(@root, @levels * BITS_PER_LEVEL, index, [])
|
721
|
+
suffix.fill(obj, 0, length)
|
722
|
+
elsif index == @size
|
723
|
+
suffix = Array.new(length, obj)
|
724
|
+
else
|
725
|
+
suffix = Array.new(index - @size, nil).concat(Array.new(length, obj))
|
726
|
+
index = @size
|
727
|
+
end
|
728
|
+
|
729
|
+
replace_suffix(index, suffix)
|
730
|
+
end
|
731
|
+
|
732
|
+
# When invoked with a block, yields all combinations of length `n` of items
|
733
|
+
# from the `Vector`, and then returns `self`. There is no guarantee about
|
734
|
+
# which order the combinations will be yielded in.
|
735
|
+
#
|
736
|
+
# If no block is given, an `Enumerator` is returned instead.
|
737
|
+
#
|
738
|
+
# @example
|
739
|
+
# v = Hamster::Vector[5, 6, 7, 8]
|
740
|
+
# v.combination(3) { |c| puts "Combination: #{c}" }
|
741
|
+
#
|
742
|
+
# Combination: [5, 6, 7]
|
743
|
+
# Combination: [5, 6, 8]
|
744
|
+
# Combination: [5, 7, 8]
|
745
|
+
# Combination: [6, 7, 8]
|
746
|
+
# #=> Hamster::Vector[5, 6, 7, 8]
|
747
|
+
#
|
748
|
+
# @return [self, Enumerator]
|
749
|
+
def combination(n)
|
750
|
+
return enum_for(:combination, n) if not block_given?
|
751
|
+
return self if n < 0 || @size < n
|
752
|
+
if n == 0
|
753
|
+
yield []
|
754
|
+
elsif n == 1
|
755
|
+
each { |item| yield [item] }
|
756
|
+
elsif n == @size
|
757
|
+
yield self.to_a
|
758
|
+
else
|
759
|
+
combos = lambda do |result,index,remaining|
|
760
|
+
while @size - index > remaining
|
761
|
+
if remaining == 1
|
762
|
+
yield result.dup << get(index)
|
763
|
+
else
|
764
|
+
combos[result.dup << get(index), index+1, remaining-1]
|
765
|
+
end
|
766
|
+
index += 1
|
767
|
+
end
|
768
|
+
index.upto(@size-1) { |i| result << get(i) }
|
769
|
+
yield result
|
770
|
+
end
|
771
|
+
combos[[], 0, n]
|
772
|
+
end
|
773
|
+
self
|
774
|
+
end
|
775
|
+
|
776
|
+
# When invoked with a block, yields all repeated combinations of length `n` of
|
777
|
+
# items from the `Vector`, and then returns `self`. A "repeated combination" is
|
778
|
+
# one in which any item from the `Vector` can appear consecutively any number of
|
779
|
+
# times.
|
780
|
+
#
|
781
|
+
# There is no guarantee about which order the combinations will be yielded in.
|
782
|
+
#
|
783
|
+
# If no block is given, an `Enumerator` is returned instead.
|
784
|
+
#
|
785
|
+
# @example
|
786
|
+
# v = Hamster::Vector[5, 6, 7, 8]
|
787
|
+
# v.repeated_combination(2) { |c| puts "Combination: #{c}" }
|
788
|
+
#
|
789
|
+
# Combination: [5, 5]
|
790
|
+
# Combination: [5, 6]
|
791
|
+
# Combination: [5, 7]
|
792
|
+
# Combination: [5, 8]
|
793
|
+
# Combination: [6, 6]
|
794
|
+
# Combination: [6, 7]
|
795
|
+
# Combination: [6, 8]
|
796
|
+
# Combination: [7, 7]
|
797
|
+
# Combination: [7, 8]
|
798
|
+
# Combination: [8, 8]
|
799
|
+
# # => Hamster::Vector[5, 6, 7, 8]
|
800
|
+
#
|
801
|
+
# @return [self, Enumerator]
|
802
|
+
def repeated_combination(n)
|
803
|
+
return enum_for(:repeated_combination, n) if not block_given?
|
804
|
+
if n < 0
|
805
|
+
# yield nothing
|
806
|
+
elsif n == 0
|
807
|
+
yield []
|
808
|
+
elsif n == 1
|
809
|
+
each { |item| yield [item] }
|
810
|
+
elsif @size == 0
|
811
|
+
# yield nothing
|
812
|
+
else
|
813
|
+
combos = lambda do |result,index,remaining|
|
814
|
+
while index < @size-1
|
815
|
+
if remaining == 1
|
816
|
+
yield result.dup << get(index)
|
817
|
+
else
|
818
|
+
combos[result.dup << get(index), index, remaining-1]
|
819
|
+
end
|
820
|
+
index += 1
|
821
|
+
end
|
822
|
+
item = get(index)
|
823
|
+
remaining.times { result << item }
|
824
|
+
yield result
|
825
|
+
end
|
826
|
+
combos[[], 0, n]
|
827
|
+
end
|
828
|
+
self
|
829
|
+
end
|
830
|
+
|
831
|
+
# Yields all permutations of length `n` of items from the `Vector`, and then
|
832
|
+
# returns `self`. If no length `n` is specified, permutations of all elements
|
833
|
+
# will be yielded.
|
834
|
+
#
|
835
|
+
# There is no guarantee about which order the permutations will be yielded in.
|
836
|
+
#
|
837
|
+
# If no block is given, an `Enumerator` is returned instead.
|
838
|
+
#
|
839
|
+
# @example
|
840
|
+
# v = Hamster::Vector[5, 6, 7]
|
841
|
+
# v.permutation(2) { |p| puts "Permutation: #{p}" }
|
842
|
+
#
|
843
|
+
# Permutation: [5, 6]
|
844
|
+
# Permutation: [5, 7]
|
845
|
+
# Permutation: [6, 5]
|
846
|
+
# Permutation: [6, 7]
|
847
|
+
# Permutation: [7, 5]
|
848
|
+
# Permutation: [7, 6]
|
849
|
+
# # => Hamster::Vector[5, 6, 7]
|
850
|
+
#
|
851
|
+
# @return [self, Enumerator]
|
852
|
+
def permutation(n = @size)
|
853
|
+
return enum_for(:permutation, n) if not block_given?
|
854
|
+
if n < 0 || @size < n
|
855
|
+
# yield nothing
|
856
|
+
elsif n == 0
|
857
|
+
yield []
|
858
|
+
elsif n == 1
|
859
|
+
each { |item| yield [item] }
|
860
|
+
else
|
861
|
+
used, result = [], []
|
862
|
+
perms = lambda do |index|
|
863
|
+
0.upto(@size-1) do |i|
|
864
|
+
if !used[i]
|
865
|
+
result[index] = get(i)
|
866
|
+
if index < n-1
|
867
|
+
used[i] = true
|
868
|
+
perms[index+1]
|
869
|
+
used[i] = false
|
870
|
+
else
|
871
|
+
yield result.dup
|
872
|
+
end
|
873
|
+
end
|
874
|
+
end
|
875
|
+
end
|
876
|
+
perms[0]
|
877
|
+
end
|
878
|
+
self
|
879
|
+
end
|
880
|
+
|
881
|
+
# When invoked with a block, yields all repeated permutations of length `n` of
|
882
|
+
# items from the `Vector`, and then returns `self`. A "repeated permutation" is
|
883
|
+
# one where any item from the `Vector` can appear any number of times, and in
|
884
|
+
# any position (not just consecutively)
|
885
|
+
#
|
886
|
+
# If no length `n` is specified, permutations of all elements will be yielded.
|
887
|
+
# There is no guarantee about which order the permutations will be yielded in.
|
888
|
+
#
|
889
|
+
# If no block is given, an `Enumerator` is returned instead.
|
890
|
+
#
|
891
|
+
# @example
|
892
|
+
# v = Hamster::Vector[5, 6, 7]
|
893
|
+
# v.repeated_permutation(2) { |p| puts "Permutation: #{p}" }
|
894
|
+
#
|
895
|
+
# Permutation: [5, 5]
|
896
|
+
# Permutation: [5, 6]
|
897
|
+
# Permutation: [5, 7]
|
898
|
+
# Permutation: [6, 5]
|
899
|
+
# Permutation: [6, 6]
|
900
|
+
# Permutation: [6, 7]
|
901
|
+
# Permutation: [7, 5]
|
902
|
+
# Permutation: [7, 6]
|
903
|
+
# Permutation: [7, 7]
|
904
|
+
# # => Hamster::Vector[5, 6, 7]
|
905
|
+
#
|
906
|
+
# @return [self, Enumerator]
|
907
|
+
def repeated_permutation(n = @size)
|
908
|
+
return enum_for(:repeated_permutation, n) if not block_given?
|
909
|
+
if n < 0
|
910
|
+
# yield nothing
|
911
|
+
elsif n == 0
|
912
|
+
yield []
|
913
|
+
elsif n == 1
|
914
|
+
each { |item| yield [item] }
|
915
|
+
else
|
916
|
+
result = []
|
917
|
+
perms = lambda do |index|
|
918
|
+
0.upto(@size-1) do |i|
|
919
|
+
result[index] = get(i)
|
920
|
+
if index < n-1
|
921
|
+
perms[index+1]
|
922
|
+
else
|
923
|
+
yield result.dup
|
924
|
+
end
|
925
|
+
end
|
926
|
+
end
|
927
|
+
perms[0]
|
928
|
+
end
|
929
|
+
self
|
930
|
+
end
|
931
|
+
|
932
|
+
# With one or more vector or array arguments, return the cartesian product of
|
933
|
+
# this vector's elements and those of each argument; with no arguments, return the
|
934
|
+
# result of multiplying all this vector's items together.
|
935
|
+
#
|
936
|
+
# @overload product(*vectors)
|
937
|
+
# Return a `Vector` of all combinations of elements from this `Vector` and each
|
938
|
+
# of the given vectors or arrays. The length of the returned `Vector` is the product
|
939
|
+
# of `self.size` and the size of each argument vector or array.
|
940
|
+
# @overload product
|
941
|
+
# Return the result of multiplying all the items in this `Vector` together.
|
942
|
+
#
|
943
|
+
# @example
|
944
|
+
# # Cartesian product:
|
945
|
+
# v1 = Hamster::Vector[1, 2, 3]
|
946
|
+
# v2 = Hamster::Vector["A", "B"]
|
947
|
+
# v1.product(v2)
|
948
|
+
# # => [[1, "A"], [1, "B"], [2, "A"], [2, "B"], [3, "A"], [3, "B"]]
|
949
|
+
#
|
950
|
+
# # Multiply all items:
|
951
|
+
# Hamster::Vector[1, 2, 3, 4, 5].product # => 120
|
952
|
+
#
|
953
|
+
# @return [Vector]
|
954
|
+
def product(*vectors)
|
955
|
+
# if no vectors passed, return "product" as in result of multiplying all items
|
956
|
+
return super if vectors.empty?
|
957
|
+
|
958
|
+
vectors.unshift(self)
|
959
|
+
|
960
|
+
if vectors.any?(&:empty?)
|
961
|
+
return block_given? ? self : []
|
962
|
+
end
|
963
|
+
|
964
|
+
counters = Array.new(vectors.size, 0)
|
965
|
+
|
966
|
+
bump_counters = lambda do
|
967
|
+
i = vectors.size-1
|
968
|
+
counters[i] += 1
|
969
|
+
while counters[i] == vectors[i].size
|
970
|
+
counters[i] = 0
|
971
|
+
i -= 1
|
972
|
+
return true if i == -1 # we are done
|
973
|
+
counters[i] += 1
|
974
|
+
end
|
975
|
+
false # not done yet
|
976
|
+
end
|
977
|
+
build_array = lambda do
|
978
|
+
array = []
|
979
|
+
counters.each_with_index { |index,i| array << vectors[i][index] }
|
980
|
+
array
|
981
|
+
end
|
982
|
+
|
983
|
+
if block_given?
|
984
|
+
while true
|
985
|
+
yield build_array[]
|
986
|
+
return self if bump_counters[]
|
987
|
+
end
|
988
|
+
else
|
989
|
+
result = []
|
990
|
+
while true
|
991
|
+
result << build_array[]
|
992
|
+
return result if bump_counters[]
|
993
|
+
end
|
994
|
+
end
|
995
|
+
end
|
996
|
+
|
997
|
+
# Assume all elements are vectors or arrays and transpose the rows and columns.
|
998
|
+
# In other words, take the first element of each nested vector/array and gather
|
999
|
+
# them together into a new `Vector`. Do likewise for the second, third, and so on
|
1000
|
+
# down to the end of each nested vector/array. Gather all the resulting `Vectors`
|
1001
|
+
# into a new `Vector` and return it.
|
1002
|
+
#
|
1003
|
+
# This operation is closely related to {#zip}. The result is almost the same as
|
1004
|
+
# calling {#zip} on the first nested vector/array with the others supplied as
|
1005
|
+
# arguments.
|
1006
|
+
#
|
1007
|
+
# @example
|
1008
|
+
# Hamster::Vector[["A", 10], ["B", 20], ["C", 30]].transpose
|
1009
|
+
# # => Hamster::Vector[Hamster::Vector["A", "B", "C"], Hamster::Vector[10, 20, 30]]
|
1010
|
+
#
|
1011
|
+
# @return [Vector]
|
1012
|
+
def transpose
|
1013
|
+
return self.class.empty if empty?
|
1014
|
+
result = Array.new(first.size) { [] }
|
1015
|
+
|
1016
|
+
0.upto(@size-1) do |i|
|
1017
|
+
source = get(i)
|
1018
|
+
if source.size != result.size
|
1019
|
+
raise IndexError, "element size differs (#{source.size} should be #{result.size})"
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
0.upto(result.size-1) do |j|
|
1023
|
+
result[j].push(source[j])
|
1024
|
+
end
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
result.map! { |a| self.class.new(a) }
|
1028
|
+
self.class.new(result)
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
# By using binary search, finds a value from this `Vector` which meets the
|
1032
|
+
# condition defined by the provided block. Behavior is just like `Array#bsearch`.
|
1033
|
+
# See `Array#bsearch` for details.
|
1034
|
+
#
|
1035
|
+
# @example
|
1036
|
+
# v = Hamster::Vector[1, 3, 5, 7, 9, 11, 13]
|
1037
|
+
# # Block returns true/false for exact element match:
|
1038
|
+
# v.bsearch { |e| e > 4 } # => 5
|
1039
|
+
# # Block returns number to match an element in 4 <= e <= 7:
|
1040
|
+
# v.bsearch { |e| 1 - e / 4 } # => 7
|
1041
|
+
#
|
1042
|
+
# @return [Object]
|
1043
|
+
def bsearch
|
1044
|
+
low, high, result = 0, @size, nil
|
1045
|
+
while low < high
|
1046
|
+
mid = (low + ((high - low) >> 1))
|
1047
|
+
val = get(mid)
|
1048
|
+
v = yield val
|
1049
|
+
if v.is_a? Numeric
|
1050
|
+
if v == 0
|
1051
|
+
return val
|
1052
|
+
elsif v > 0
|
1053
|
+
high = mid
|
1054
|
+
else
|
1055
|
+
low = mid + 1
|
1056
|
+
end
|
1057
|
+
elsif v == true
|
1058
|
+
result = val
|
1059
|
+
high = mid
|
1060
|
+
elsif !v
|
1061
|
+
low = mid + 1
|
1062
|
+
else
|
1063
|
+
raise TypeError, "wrong argument type #{v.class} (must be numeric, true, false, or nil)"
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
result
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
# Return an empty `Vector` instance, of the same class as this one. Useful if you
|
1070
|
+
# have multiple subclasses of `Vector` and want to treat them polymorphically.
|
1071
|
+
#
|
1072
|
+
# @return [Vector]
|
98
1073
|
def clear
|
99
|
-
|
1074
|
+
self.class.empty
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
# Return a randomly chosen item from this `Vector`. If the vector is empty, return `nil`.
|
1078
|
+
#
|
1079
|
+
# @example
|
1080
|
+
# Hamster::Vector[1, 2, 3, 4, 5].sample # => 2
|
1081
|
+
#
|
1082
|
+
# @return [Object]
|
1083
|
+
def sample
|
1084
|
+
get(rand(@size))
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
# Return a new `Vector` with only the elements at the given `indices`, in the
|
1088
|
+
# order specified by `indices`. If any of the `indices` do not exist, `nil`s will
|
1089
|
+
# appear in their places.
|
1090
|
+
#
|
1091
|
+
# @example
|
1092
|
+
# v = Hamster::Vector["A", "B", "C", "D", "E", "F"]
|
1093
|
+
# v.values_at(2, 4, 5) # => Hamster::Vector["C", "E", "F"]
|
1094
|
+
#
|
1095
|
+
# @param indices [Array] The indices to retrieve and gather into a new `Vector`
|
1096
|
+
# @return [Vector]
|
1097
|
+
def values_at(*indices)
|
1098
|
+
self.class.new(indices.map { |i| get(i) }.freeze)
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
# Return the index of the last element which is equal to the provided object,
|
1102
|
+
# or for which the provided block returns true.
|
1103
|
+
#
|
1104
|
+
# @overload rindex(obj)
|
1105
|
+
# Return the index of the last element in this `Vector` which is `#==` to `obj`.
|
1106
|
+
# @overload rindex { |item| ... }
|
1107
|
+
# Return the index of the last element in this `Vector` for which the block
|
1108
|
+
# returns true. (Iteration starts from the last element, counts back, and
|
1109
|
+
# stops as soon as a matching element is found.)
|
1110
|
+
#
|
1111
|
+
# @example
|
1112
|
+
# v = Hamster::Vector[7, 8, 9, 7, 8, 9]
|
1113
|
+
# v.rindex(8) # => 4
|
1114
|
+
# v.rindex { |e| e.even? } # => 4
|
1115
|
+
#
|
1116
|
+
# @return [Index]
|
1117
|
+
def rindex(obj = (missing_arg = true))
|
1118
|
+
i = @size - 1
|
1119
|
+
if missing_arg
|
1120
|
+
if block_given?
|
1121
|
+
reverse_each { |item| return i if yield item; i -= 1 }
|
1122
|
+
nil
|
1123
|
+
else
|
1124
|
+
enum_for(:rindex)
|
1125
|
+
end
|
1126
|
+
else
|
1127
|
+
reverse_each { |item| return i if item == obj; i -= 1 }
|
1128
|
+
nil
|
1129
|
+
end
|
1130
|
+
end
|
1131
|
+
|
1132
|
+
# Assumes all elements are nested, indexable collections, and searches through them,
|
1133
|
+
# comparing `obj` with the first element of each nested collection. Return the
|
1134
|
+
# first nested collection which matches, or `nil` if none is found.
|
1135
|
+
#
|
1136
|
+
# @example
|
1137
|
+
# v = Hamster::Vector[["A", 10], ["B", 20], ["C", 30]]
|
1138
|
+
# v.assoc("B") # => ["B", 20]
|
1139
|
+
#
|
1140
|
+
# @param obj [Object] The object to search for
|
1141
|
+
# @return [Object]
|
1142
|
+
def assoc(obj)
|
1143
|
+
each { |array| return array if obj == array[0] }
|
1144
|
+
nil
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
# Assumes all elements are nested, indexable collections, and searches through them,
|
1148
|
+
# comparing `obj` with the second element of each nested collection. Return the
|
1149
|
+
# first nested collection which matches, or `nil` if none is found.
|
1150
|
+
#
|
1151
|
+
# @example
|
1152
|
+
# v = Hamster::Vector[["A", 10], ["B", 20], ["C", 30]]
|
1153
|
+
# v.rassoc(20) # => ["B", 20]
|
1154
|
+
#
|
1155
|
+
# @param obj [Object] The object to search for
|
1156
|
+
# @return [Object]
|
1157
|
+
def rassoc(obj)
|
1158
|
+
each { |array| return array if obj == array[1] }
|
1159
|
+
nil
|
100
1160
|
end
|
101
1161
|
|
102
|
-
|
103
|
-
|
1162
|
+
# Return an `Array` with the same elements, in the same order. The returned
|
1163
|
+
# `Array` may or may not be frozen.
|
1164
|
+
#
|
1165
|
+
# @return [Array]
|
1166
|
+
def to_a
|
1167
|
+
if @levels == 0
|
1168
|
+
@root
|
1169
|
+
else
|
1170
|
+
flatten_node(@root, @levels * BITS_PER_LEVEL, [])
|
1171
|
+
end
|
104
1172
|
end
|
1173
|
+
alias :to_ary :to_a
|
105
1174
|
|
1175
|
+
# Return true if `other` has the same type and contents as this `Vector`.
|
1176
|
+
#
|
1177
|
+
# @param other [Object] The collection to compare with
|
1178
|
+
# @return [Boolean]
|
106
1179
|
def eql?(other)
|
107
1180
|
return true if other.equal?(self)
|
108
1181
|
return false unless instance_of?(other.class) && @size == other.size
|
109
1182
|
@root.eql?(other.instance_variable_get(:@root))
|
110
1183
|
end
|
111
|
-
|
1184
|
+
|
1185
|
+
# See `Object#hash`.
|
1186
|
+
# @return [Integer]
|
1187
|
+
def hash
|
1188
|
+
reduce(0) { |hash, item| (hash << 5) - hash + item.hash }
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
# @return [::Array]
|
1192
|
+
# @private
|
1193
|
+
def marshal_dump
|
1194
|
+
to_a
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
# @private
|
1198
|
+
def marshal_load(array)
|
1199
|
+
initialize(array.freeze)
|
1200
|
+
end
|
112
1201
|
|
113
1202
|
private
|
114
1203
|
|
115
|
-
def traverse_depth_first(node
|
1204
|
+
def traverse_depth_first(node, level, &block)
|
116
1205
|
return node.each(&block) if level == 0
|
117
1206
|
node.each { |child| traverse_depth_first(child, level - 1, &block) }
|
118
1207
|
end
|
119
1208
|
|
120
|
-
def
|
121
|
-
return node if
|
122
|
-
|
123
|
-
leaf_node_for(node[child_index], child_index_bits - BITS_PER_LEVEL, index)
|
1209
|
+
def reverse_traverse_depth_first(node, level, &block)
|
1210
|
+
return node.reverse_each(&block) if level == 0
|
1211
|
+
node.reverse_each { |child| reverse_traverse_depth_first(child, level - 1, &block) }
|
124
1212
|
end
|
125
1213
|
|
126
|
-
def
|
127
|
-
|
1214
|
+
def leaf_node_for(node, bitshift, index)
|
1215
|
+
while bitshift > 0
|
1216
|
+
node = node[(index >> bitshift) & INDEX_MASK]
|
1217
|
+
bitshift -= BITS_PER_LEVEL
|
1218
|
+
end
|
1219
|
+
node
|
128
1220
|
end
|
129
1221
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
1222
|
+
def update_root(index, item)
|
1223
|
+
root, levels = @root, @levels
|
1224
|
+
while index >= (1 << (BITS_PER_LEVEL * (levels + 1)))
|
1225
|
+
root = [root].freeze
|
1226
|
+
levels += 1
|
1227
|
+
end
|
1228
|
+
new_root = update_leaf_node(root, levels * BITS_PER_LEVEL, index, item)
|
1229
|
+
if new_root.equal?(root)
|
1230
|
+
self
|
135
1231
|
else
|
136
|
-
|
1232
|
+
self.class.alloc(new_root, @size > index ? @size : index + 1, levels)
|
137
1233
|
end
|
138
|
-
node[child_index] = child_node
|
139
|
-
copy_leaf_node_for(child_node, child_index_bits - BITS_PER_LEVEL, index)
|
140
1234
|
end
|
141
1235
|
|
142
|
-
def
|
143
|
-
|
144
|
-
|
145
|
-
|
1236
|
+
def update_leaf_node(node, bitshift, index, item)
|
1237
|
+
slot_index = (index >> bitshift) & INDEX_MASK
|
1238
|
+
if bitshift > 0
|
1239
|
+
old_child = node[slot_index] || []
|
1240
|
+
item = update_leaf_node(old_child, bitshift - BITS_PER_LEVEL, index, item)
|
1241
|
+
end
|
1242
|
+
existing_item = node[slot_index]
|
1243
|
+
if existing_item.equal?(item)
|
1244
|
+
node
|
146
1245
|
else
|
147
|
-
|
1246
|
+
node.dup.tap { |n| n[slot_index] = item }.freeze
|
148
1247
|
end
|
149
1248
|
end
|
150
1249
|
|
151
|
-
def
|
152
|
-
(
|
1250
|
+
def flatten_range(node, bitshift, from, to)
|
1251
|
+
from_slot = (from >> bitshift) & INDEX_MASK
|
1252
|
+
to_slot = (to >> bitshift) & INDEX_MASK
|
1253
|
+
|
1254
|
+
if bitshift == 0 # are we at the bottom?
|
1255
|
+
node.slice(from_slot, to_slot-from_slot+1)
|
1256
|
+
elsif from_slot == to_slot
|
1257
|
+
flatten_range(node[from_slot], bitshift - BITS_PER_LEVEL, from, to)
|
1258
|
+
else
|
1259
|
+
# the following bitmask can be used to pick out the part of the from/to indices
|
1260
|
+
# which will be used to direct path BELOW this node
|
1261
|
+
mask = ((1 << bitshift) - 1)
|
1262
|
+
result = []
|
1263
|
+
|
1264
|
+
if from & mask == 0
|
1265
|
+
flatten_node(node[from_slot], bitshift - BITS_PER_LEVEL, result)
|
1266
|
+
else
|
1267
|
+
result.concat(flatten_range(node[from_slot], bitshift - BITS_PER_LEVEL, from, from | mask))
|
1268
|
+
end
|
1269
|
+
|
1270
|
+
(from_slot+1).upto(to_slot-1) do |slot_index|
|
1271
|
+
flatten_node(node[slot_index], bitshift - BITS_PER_LEVEL, result)
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
if to & mask == mask
|
1275
|
+
flatten_node(node[to_slot], bitshift - BITS_PER_LEVEL, result)
|
1276
|
+
else
|
1277
|
+
result.concat(flatten_range(node[to_slot], bitshift - BITS_PER_LEVEL, to & ~mask, to))
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
result
|
1281
|
+
end
|
153
1282
|
end
|
154
1283
|
|
155
|
-
def
|
156
|
-
|
1284
|
+
def flatten_node(node, bitshift, result)
|
1285
|
+
if bitshift == 0
|
1286
|
+
result.concat(node)
|
1287
|
+
elsif bitshift == BITS_PER_LEVEL
|
1288
|
+
node.each { |a| result.concat(a) }
|
1289
|
+
else
|
1290
|
+
bitshift -= BITS_PER_LEVEL
|
1291
|
+
node.each { |a| flatten_node(a, bitshift, result) }
|
1292
|
+
end
|
1293
|
+
result
|
157
1294
|
end
|
158
1295
|
|
159
|
-
|
1296
|
+
def subsequence(from, length)
|
1297
|
+
return nil if from > @size || from < 0 || length < 0
|
1298
|
+
length = @size - from if @size < from + length
|
1299
|
+
return self.class.empty if length == 0
|
1300
|
+
self.class.new(flatten_range(@root, @levels * BITS_PER_LEVEL, from, from + length - 1))
|
1301
|
+
end
|
1302
|
+
|
1303
|
+
def flatten_suffix(node, bitshift, from, result)
|
1304
|
+
from_slot = (from >> bitshift) & INDEX_MASK
|
1305
|
+
|
1306
|
+
if bitshift == 0
|
1307
|
+
if from_slot == 0
|
1308
|
+
result.concat(node)
|
1309
|
+
else
|
1310
|
+
result.concat(node.slice(from_slot, 32)) # entire suffix of node. excess length is ignored by #slice
|
1311
|
+
end
|
1312
|
+
else
|
1313
|
+
mask = ((1 << bitshift) - 1)
|
1314
|
+
if from & mask == 0
|
1315
|
+
from_slot.upto(node.size-1) do |i|
|
1316
|
+
flatten_node(node[i], bitshift - BITS_PER_LEVEL, result)
|
1317
|
+
end
|
1318
|
+
elsif child = node[from_slot]
|
1319
|
+
flatten_suffix(child, bitshift - BITS_PER_LEVEL, from, result)
|
1320
|
+
(from_slot+1).upto(node.size-1) do |i|
|
1321
|
+
flatten_node(node[i], bitshift - BITS_PER_LEVEL, result)
|
1322
|
+
end
|
1323
|
+
end
|
1324
|
+
result
|
1325
|
+
end
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
def replace_suffix(from, suffix)
|
1329
|
+
# new suffix can go directly after existing elements
|
1330
|
+
raise IndexError if from > @size
|
1331
|
+
root, levels = @root, @levels
|
1332
|
+
|
1333
|
+
if (from >> (BITS_PER_LEVEL * (@levels + 1))) != 0
|
1334
|
+
# index where new suffix goes doesn't fall within current tree
|
1335
|
+
# we will need to deepen tree
|
1336
|
+
root = [root].freeze
|
1337
|
+
levels += 1
|
1338
|
+
end
|
160
1339
|
|
161
|
-
|
1340
|
+
new_size = from + suffix.size
|
1341
|
+
root = replace_node_suffix(root, levels * BITS_PER_LEVEL, from, suffix)
|
1342
|
+
|
1343
|
+
if !suffix.empty?
|
1344
|
+
levels.times { suffix = suffix.each_slice(32).to_a }
|
1345
|
+
root.concat(suffix)
|
1346
|
+
while root.size > 32
|
1347
|
+
root = root.each_slice(32).to_a
|
1348
|
+
levels += 1
|
1349
|
+
end
|
1350
|
+
else
|
1351
|
+
while root.size == 1 && levels > 0
|
1352
|
+
root = root[0]
|
1353
|
+
levels -= 1
|
1354
|
+
end
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
self.class.alloc(root.freeze, new_size, levels)
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
def replace_node_suffix(node, bitshift, from, suffix)
|
1361
|
+
from_slot = (from >> bitshift) & INDEX_MASK
|
1362
|
+
|
1363
|
+
if bitshift == 0
|
1364
|
+
if from_slot == 0
|
1365
|
+
suffix.shift(32)
|
1366
|
+
else
|
1367
|
+
node.take(from_slot).concat(suffix.shift(32 - from_slot))
|
1368
|
+
end
|
1369
|
+
else
|
1370
|
+
mask = ((1 << bitshift) - 1)
|
1371
|
+
if from & mask == 0
|
1372
|
+
if from_slot == 0
|
1373
|
+
new_node = suffix.shift(32 * (1 << bitshift))
|
1374
|
+
while bitshift != 0
|
1375
|
+
new_node = new_node.each_slice(32).to_a
|
1376
|
+
bitshift -= BITS_PER_LEVEL
|
1377
|
+
end
|
1378
|
+
new_node
|
1379
|
+
else
|
1380
|
+
result = node.take(from_slot)
|
1381
|
+
remainder = suffix.shift((32 - from_slot) * (1 << bitshift))
|
1382
|
+
while bitshift != 0
|
1383
|
+
remainder = remainder.each_slice(32).to_a
|
1384
|
+
bitshift -= BITS_PER_LEVEL
|
1385
|
+
end
|
1386
|
+
result.concat(remainder)
|
1387
|
+
end
|
1388
|
+
elsif child = node[from_slot]
|
1389
|
+
result = node.take(from_slot)
|
1390
|
+
result.push(replace_node_suffix(child, bitshift - BITS_PER_LEVEL, from, suffix))
|
1391
|
+
remainder = suffix.shift((31 - from_slot) * (1 << bitshift))
|
1392
|
+
while bitshift != 0
|
1393
|
+
remainder = remainder.each_slice(32).to_a
|
1394
|
+
bitshift -= BITS_PER_LEVEL
|
1395
|
+
end
|
1396
|
+
result.concat(remainder)
|
1397
|
+
else
|
1398
|
+
raise "Shouldn't happen"
|
1399
|
+
end
|
1400
|
+
end
|
1401
|
+
end
|
1402
|
+
end
|
162
1403
|
|
1404
|
+
# The canonical empty `Vector`. Returned by `Hamster.vector` and `Vector[]` when
|
1405
|
+
# invoked with no arguments; also returned by `Vector.empty`. Prefer using this
|
1406
|
+
# one rather than creating many empty vectors using `Vector.new`.
|
1407
|
+
#
|
1408
|
+
EmptyVector = Hamster::Vector.empty
|
163
1409
|
end
|