PageRenderTime 57ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/ruby/1.8/set.rb

https://bitbucket.org/nicksieger/jruby
Ruby | 1293 lines | 773 code | 212 blank | 308 comment | 33 complexity | b150fd61909b0310137f1f91ccafa3f0 MD5 | raw file
Possible License(s): GPL-3.0, JSON
  1. #!/usr/bin/env ruby
  2. #--
  3. # set.rb - defines the Set class
  4. #++
  5. # Copyright (c) 2002-2008 Akinori MUSHA <knu@iDaemons.org>
  6. #
  7. # Documentation by Akinori MUSHA and Gavin Sinclair.
  8. #
  9. # All rights reserved. You can redistribute and/or modify it under the same
  10. # terms as Ruby.
  11. #
  12. # $Id$
  13. #
  14. # == Overview
  15. #
  16. # This library provides the Set class, which deals with a collection
  17. # of unordered values with no duplicates. It is a hybrid of Array's
  18. # intuitive inter-operation facilities and Hash's fast lookup. If you
  19. # need to keep values ordered, use the SortedSet class.
  20. #
  21. # The method +to_set+ is added to Enumerable for convenience.
  22. #
  23. # See the Set and SortedSet documentation for examples of usage.
  24. #
  25. # Set implements a collection of unordered values with no duplicates.
  26. # This is a hybrid of Array's intuitive inter-operation facilities and
  27. # Hash's fast lookup.
  28. #
  29. # Several methods accept any Enumerable object (implementing +each+)
  30. # for greater flexibility: new, replace, merge, subtract, |, &, -, ^.
  31. #
  32. # The equality of each couple of elements is determined according to
  33. # Object#eql? and Object#hash, since Set uses Hash as storage.
  34. #
  35. # Finally, if you are using class Set, you can also use Enumerable#to_set
  36. # for convenience.
  37. #
  38. # == Example
  39. #
  40. # require 'set'
  41. # s1 = Set.new [1, 2] # -> #<Set: {1, 2}>
  42. # s2 = [1, 2].to_set # -> #<Set: {1, 2}>
  43. # s1 == s2 # -> true
  44. # s1.add("foo") # -> #<Set: {1, 2, "foo"}>
  45. # s1.merge([2, 6]) # -> #<Set: {6, 1, 2, "foo"}>
  46. # s1.subset? s2 # -> false
  47. # s2.subset? s1 # -> true
  48. #
  49. # == Contact
  50. #
  51. # - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
  52. #
  53. class Set
  54. include Enumerable
  55. # Creates a new set containing the given objects.
  56. def self.[](*ary)
  57. new(ary)
  58. end
  59. # Creates a new set containing the elements of the given enumerable
  60. # object.
  61. #
  62. # If a block is given, the elements of enum are preprocessed by the
  63. # given block.
  64. def initialize(enum = nil, &block) # :yields: o
  65. @hash ||= Hash.new
  66. enum.nil? and return
  67. if block
  68. enum.each { |o| add(block[o]) }
  69. else
  70. merge(enum)
  71. end
  72. end
  73. # Copy internal hash.
  74. def initialize_copy(orig)
  75. @hash = orig.instance_eval{@hash}.dup
  76. end
  77. # Returns the number of elements.
  78. def size
  79. @hash.size
  80. end
  81. alias length size
  82. # Returns true if the set contains no elements.
  83. def empty?
  84. @hash.empty?
  85. end
  86. # Removes all elements and returns self.
  87. def clear
  88. @hash.clear
  89. self
  90. end
  91. # Replaces the contents of the set with the contents of the given
  92. # enumerable object and returns self.
  93. def replace(enum)
  94. if enum.class == self.class
  95. @hash.replace(enum.instance_eval { @hash })
  96. else
  97. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  98. clear
  99. enum.each { |o| add(o) }
  100. end
  101. self
  102. end
  103. # Converts the set to an array. The order of elements is uncertain.
  104. def to_a
  105. @hash.keys
  106. end
  107. def flatten_merge(set, seen = Set.new)
  108. set.each { |e|
  109. if e.is_a?(Set)
  110. if seen.include?(e_id = e.object_id)
  111. raise ArgumentError, "tried to flatten recursive Set"
  112. end
  113. seen.add(e_id)
  114. flatten_merge(e, seen)
  115. seen.delete(e_id)
  116. else
  117. add(e)
  118. end
  119. }
  120. self
  121. end
  122. protected :flatten_merge
  123. # Returns a new set that is a copy of the set, flattening each
  124. # containing set recursively.
  125. def flatten
  126. self.class.new.flatten_merge(self)
  127. end
  128. # Equivalent to Set#flatten, but replaces the receiver with the
  129. # result in place. Returns nil if no modifications were made.
  130. def flatten!
  131. if detect { |e| e.is_a?(Set) }
  132. replace(flatten())
  133. else
  134. nil
  135. end
  136. end
  137. # Returns true if the set contains the given object.
  138. def include?(o)
  139. @hash.include?(o)
  140. end
  141. alias member? include?
  142. # Returns true if the set is a superset of the given set.
  143. def superset?(set)
  144. set.is_a?(Set) or raise ArgumentError, "value must be a set"
  145. return false if size < set.size
  146. set.all? { |o| include?(o) }
  147. end
  148. # Returns true if the set is a proper superset of the given set.
  149. def proper_superset?(set)
  150. set.is_a?(Set) or raise ArgumentError, "value must be a set"
  151. return false if size <= set.size
  152. set.all? { |o| include?(o) }
  153. end
  154. # Returns true if the set is a subset of the given set.
  155. def subset?(set)
  156. set.is_a?(Set) or raise ArgumentError, "value must be a set"
  157. return false if set.size < size
  158. all? { |o| set.include?(o) }
  159. end
  160. # Returns true if the set is a proper subset of the given set.
  161. def proper_subset?(set)
  162. set.is_a?(Set) or raise ArgumentError, "value must be a set"
  163. return false if set.size <= size
  164. all? { |o| set.include?(o) }
  165. end
  166. # Calls the given block once for each element in the set, passing
  167. # the element as parameter. Returns an enumerator if no block is
  168. # given.
  169. def each
  170. block_given? or return enum_for(__method__)
  171. @hash.each_key { |o| yield(o) }
  172. self
  173. end
  174. # Adds the given object to the set and returns self. Use +merge+ to
  175. # add several elements at once.
  176. def add(o)
  177. @hash[o] = true
  178. self
  179. end
  180. alias << add
  181. # Adds the given object to the set and returns self. If the
  182. # object is already in the set, returns nil.
  183. def add?(o)
  184. if include?(o)
  185. nil
  186. else
  187. add(o)
  188. end
  189. end
  190. # Deletes the given object from the set and returns self. Use +subtract+ to
  191. # delete several items at once.
  192. def delete(o)
  193. @hash.delete(o)
  194. self
  195. end
  196. # Deletes the given object from the set and returns self. If the
  197. # object is not in the set, returns nil.
  198. def delete?(o)
  199. if include?(o)
  200. delete(o)
  201. else
  202. nil
  203. end
  204. end
  205. # Deletes every element of the set for which block evaluates to
  206. # true, and returns self.
  207. def delete_if
  208. to_a.each { |o| @hash.delete(o) if yield(o) }
  209. self
  210. end
  211. # Do collect() destructively.
  212. def collect!
  213. set = self.class.new
  214. each { |o| set << yield(o) }
  215. replace(set)
  216. end
  217. alias map! collect!
  218. # Equivalent to Set#delete_if, but returns nil if no changes were
  219. # made.
  220. def reject!
  221. n = size
  222. delete_if { |o| yield(o) }
  223. size == n ? nil : self
  224. end
  225. # Merges the elements of the given enumerable object to the set and
  226. # returns self.
  227. def merge(enum)
  228. if enum.instance_of?(self.class)
  229. @hash.update(enum.instance_variable_get(:@hash))
  230. else
  231. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  232. enum.each { |o| add(o) }
  233. end
  234. self
  235. end
  236. # Deletes every element that appears in the given enumerable object
  237. # and returns self.
  238. def subtract(enum)
  239. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  240. enum.each { |o| delete(o) }
  241. self
  242. end
  243. # Returns a new set built by merging the set and the elements of the
  244. # given enumerable object.
  245. def |(enum)
  246. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  247. dup.merge(enum)
  248. end
  249. alias + | ##
  250. alias union | ##
  251. # Returns a new set built by duplicating the set, removing every
  252. # element that appears in the given enumerable object.
  253. def -(enum)
  254. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  255. dup.subtract(enum)
  256. end
  257. alias difference - ##
  258. # Returns a new set containing elements common to the set and the
  259. # given enumerable object.
  260. def &(enum)
  261. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  262. n = self.class.new
  263. enum.each { |o| n.add(o) if include?(o) }
  264. n
  265. end
  266. alias intersection & ##
  267. # Returns a new set containing elements exclusive between the set
  268. # and the given enumerable object. (set ^ enum) is equivalent to
  269. # ((set | enum) - (set & enum)).
  270. def ^(enum)
  271. enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  272. n = Set.new(enum)
  273. each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
  274. n
  275. end
  276. # Returns true if two sets are equal. The equality of each couple
  277. # of elements is defined according to Object#eql?.
  278. def ==(set)
  279. equal?(set) and return true
  280. set.is_a?(Set) && size == set.size or return false
  281. hash = @hash.dup
  282. set.all? { |o| hash.include?(o) }
  283. end
  284. def hash # :nodoc:
  285. @hash.hash
  286. end
  287. def eql?(o) # :nodoc:
  288. return false unless o.is_a?(Set)
  289. @hash.eql?(o.instance_eval{@hash})
  290. end
  291. # Classifies the set by the return value of the given block and
  292. # returns a hash of {value => set of elements} pairs. The block is
  293. # called once for each element of the set, passing the element as
  294. # parameter.
  295. #
  296. # e.g.:
  297. #
  298. # require 'set'
  299. # files = Set.new(Dir.glob("*.rb"))
  300. # hash = files.classify { |f| File.mtime(f).year }
  301. # p hash # => {2000=>#<Set: {"a.rb", "b.rb"}>,
  302. # # 2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
  303. # # 2002=>#<Set: {"f.rb"}>}
  304. def classify # :yields: o
  305. h = {}
  306. each { |i|
  307. x = yield(i)
  308. (h[x] ||= self.class.new).add(i)
  309. }
  310. h
  311. end
  312. # Divides the set into a set of subsets according to the commonality
  313. # defined by the given block.
  314. #
  315. # If the arity of the block is 2, elements o1 and o2 are in common
  316. # if block.call(o1, o2) is true. Otherwise, elements o1 and o2 are
  317. # in common if block.call(o1) == block.call(o2).
  318. #
  319. # e.g.:
  320. #
  321. # require 'set'
  322. # numbers = Set[1, 3, 4, 6, 9, 10, 11]
  323. # set = numbers.divide { |i,j| (i - j).abs == 1 }
  324. # p set # => #<Set: {#<Set: {1}>,
  325. # # #<Set: {11, 9, 10}>,
  326. # # #<Set: {3, 4}>,
  327. # # #<Set: {6}>}>
  328. def divide(&func)
  329. if func.arity == 2
  330. require 'tsort'
  331. class << dig = {} # :nodoc:
  332. include TSort
  333. alias tsort_each_node each_key
  334. def tsort_each_child(node, &block)
  335. fetch(node).each(&block)
  336. end
  337. end
  338. each { |u|
  339. dig[u] = a = []
  340. each{ |v| func.call(u, v) and a << v }
  341. }
  342. set = Set.new()
  343. dig.each_strongly_connected_component { |css|
  344. set.add(self.class.new(css))
  345. }
  346. set
  347. else
  348. Set.new(classify(&func).values)
  349. end
  350. end
  351. InspectKey = :__inspect_key__ # :nodoc:
  352. # Returns a string containing a human-readable representation of the
  353. # set. ("#<Set: {element1, element2, ...}>")
  354. def inspect
  355. ids = (Thread.current[InspectKey] ||= [])
  356. if ids.include?(object_id)
  357. return sprintf('#<%s: {...}>', self.class.name)
  358. end
  359. begin
  360. ids << object_id
  361. return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
  362. ensure
  363. ids.pop
  364. end
  365. end
  366. def pretty_print(pp) # :nodoc:
  367. pp.text sprintf('#<%s: {', self.class.name)
  368. pp.nest(1) {
  369. pp.seplist(self) { |o|
  370. pp.pp o
  371. }
  372. }
  373. pp.text "}>"
  374. end
  375. def pretty_print_cycle(pp) # :nodoc:
  376. pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
  377. end
  378. end
  379. #
  380. # SortedSet implements a Set that guarantees that it's element are
  381. # yielded in sorted order (according to the return values of their
  382. # #<=> methods) when iterating over them.
  383. #
  384. # All elements that are added to a SortedSet must respond to the <=>
  385. # method for comparison.
  386. #
  387. # Also, all elements must be <em>mutually comparable</em>: <tt>el1 <=>
  388. # el2</tt> must not return <tt>nil</tt> for any elements <tt>el1</tt>
  389. # and <tt>el2</tt>, else an ArgumentError will be raised when
  390. # iterating over the SortedSet.
  391. #
  392. # == Example
  393. #
  394. # require "set"
  395. #
  396. # set = SortedSet.new(2, 1, 5, 6, 4, 5, 3, 3, 3)
  397. # ary = []
  398. #
  399. # set.each do |obj|
  400. # ary << obj
  401. # end
  402. #
  403. # p ary # => [1, 2, 3, 4, 5, 6]
  404. #
  405. # set2 = SortedSet.new(1, 2, "3")
  406. # set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed
  407. #
  408. class SortedSet < Set
  409. @@setup = false
  410. class << self
  411. def [](*ary) # :nodoc:
  412. new(ary)
  413. end
  414. def setup # :nodoc:
  415. @@setup and return
  416. module_eval {
  417. # a hack to shut up warning
  418. alias old_init initialize
  419. remove_method :old_init
  420. }
  421. begin
  422. require 'rbtree'
  423. module_eval %{
  424. def initialize(*args, &block)
  425. @hash = RBTree.new
  426. super
  427. end
  428. def add(o)
  429. o.respond_to?(:<=>) or raise ArgumentError, "value must repond to <=>"
  430. super
  431. end
  432. alias << add
  433. }
  434. rescue LoadError
  435. module_eval %{
  436. def initialize(*args, &block)
  437. @keys = nil
  438. super
  439. end
  440. def clear
  441. @keys = nil
  442. super
  443. end
  444. def replace(enum)
  445. @keys = nil
  446. super
  447. end
  448. def add(o)
  449. o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
  450. @keys = nil
  451. super
  452. end
  453. alias << add
  454. def delete(o)
  455. @keys = nil
  456. @hash.delete(o)
  457. self
  458. end
  459. def delete_if
  460. n = @hash.size
  461. super
  462. @keys = nil if @hash.size != n
  463. self
  464. end
  465. def merge(enum)
  466. @keys = nil
  467. super
  468. end
  469. def each
  470. block_given? or return enum_for(__method__)
  471. to_a.each { |o| yield(o) }
  472. self
  473. end
  474. def to_a
  475. (@keys = @hash.keys).sort! unless @keys
  476. @keys
  477. end
  478. }
  479. end
  480. @@setup = true
  481. end
  482. end
  483. def initialize(*args, &block) # :nodoc:
  484. SortedSet.setup
  485. initialize(*args, &block)
  486. end
  487. end
  488. module Enumerable
  489. # Makes a set from the enumerable object with given arguments.
  490. # Needs to +require "set"+ to use this method.
  491. def to_set(klass = Set, *args, &block)
  492. klass.new(self, *args, &block)
  493. end
  494. end
  495. # =begin
  496. # == RestricedSet class
  497. # RestricedSet implements a set with restrictions defined by a given
  498. # block.
  499. #
  500. # === Super class
  501. # Set
  502. #
  503. # === Class Methods
  504. # --- RestricedSet::new(enum = nil) { |o| ... }
  505. # --- RestricedSet::new(enum = nil) { |rset, o| ... }
  506. # Creates a new restricted set containing the elements of the given
  507. # enumerable object. Restrictions are defined by the given block.
  508. #
  509. # If the block's arity is 2, it is called with the RestrictedSet
  510. # itself and an object to see if the object is allowed to be put in
  511. # the set.
  512. #
  513. # Otherwise, the block is called with an object to see if the object
  514. # is allowed to be put in the set.
  515. #
  516. # === Instance Methods
  517. # --- restriction_proc
  518. # Returns the restriction procedure of the set.
  519. #
  520. # =end
  521. #
  522. # class RestricedSet < Set
  523. # def initialize(*args, &block)
  524. # @proc = block or raise ArgumentError, "missing a block"
  525. #
  526. # if @proc.arity == 2
  527. # instance_eval %{
  528. # def add(o)
  529. # @hash[o] = true if @proc.call(self, o)
  530. # self
  531. # end
  532. # alias << add
  533. #
  534. # def add?(o)
  535. # if include?(o) || !@proc.call(self, o)
  536. # nil
  537. # else
  538. # @hash[o] = true
  539. # self
  540. # end
  541. # end
  542. #
  543. # def replace(enum)
  544. # enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  545. # clear
  546. # enum.each { |o| add(o) }
  547. #
  548. # self
  549. # end
  550. #
  551. # def merge(enum)
  552. # enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  553. # enum.each { |o| add(o) }
  554. #
  555. # self
  556. # end
  557. # }
  558. # else
  559. # instance_eval %{
  560. # def add(o)
  561. # if @proc.call(o)
  562. # @hash[o] = true
  563. # end
  564. # self
  565. # end
  566. # alias << add
  567. #
  568. # def add?(o)
  569. # if include?(o) || !@proc.call(o)
  570. # nil
  571. # else
  572. # @hash[o] = true
  573. # self
  574. # end
  575. # end
  576. # }
  577. # end
  578. #
  579. # super(*args)
  580. # end
  581. #
  582. # def restriction_proc
  583. # @proc
  584. # end
  585. # end
  586. if $0 == __FILE__
  587. eval DATA.read, nil, $0, __LINE__+4
  588. end
  589. __END__
  590. require 'test/unit'
  591. class TC_Set < Test::Unit::TestCase
  592. def test_aref
  593. assert_nothing_raised {
  594. Set[]
  595. Set[nil]
  596. Set[1,2,3]
  597. }
  598. assert_equal(0, Set[].size)
  599. assert_equal(1, Set[nil].size)
  600. assert_equal(1, Set[[]].size)
  601. assert_equal(1, Set[[nil]].size)
  602. set = Set[2,4,6,4]
  603. assert_equal(Set.new([2,4,6]), set)
  604. end
  605. def test_s_new
  606. assert_nothing_raised {
  607. Set.new()
  608. Set.new(nil)
  609. Set.new([])
  610. Set.new([1,2])
  611. Set.new('a'..'c')
  612. Set.new('XYZ')
  613. }
  614. assert_raises(ArgumentError) {
  615. Set.new(false)
  616. }
  617. assert_raises(ArgumentError) {
  618. Set.new(1)
  619. }
  620. assert_raises(ArgumentError) {
  621. Set.new(1,2)
  622. }
  623. assert_equal(0, Set.new().size)
  624. assert_equal(0, Set.new(nil).size)
  625. assert_equal(0, Set.new([]).size)
  626. assert_equal(1, Set.new([nil]).size)
  627. ary = [2,4,6,4]
  628. set = Set.new(ary)
  629. ary.clear
  630. assert_equal(false, set.empty?)
  631. assert_equal(3, set.size)
  632. ary = [1,2,3]
  633. s = Set.new(ary) { |o| o * 2 }
  634. assert_equal([2,4,6], s.sort)
  635. end
  636. def test_clone
  637. set1 = Set.new
  638. set2 = set1.clone
  639. set1 << 'abc'
  640. assert_equal(Set.new, set2)
  641. end
  642. def test_dup
  643. set1 = Set[1,2]
  644. set2 = set1.dup
  645. assert_not_same(set1, set2)
  646. assert_equal(set1, set2)
  647. set1.add(3)
  648. assert_not_equal(set1, set2)
  649. end
  650. def test_size
  651. assert_equal(0, Set[].size)
  652. assert_equal(2, Set[1,2].size)
  653. assert_equal(2, Set[1,2,1].size)
  654. end
  655. def test_empty?
  656. assert_equal(true, Set[].empty?)
  657. assert_equal(false, Set[1, 2].empty?)
  658. end
  659. def test_clear
  660. set = Set[1,2]
  661. ret = set.clear
  662. assert_same(set, ret)
  663. assert_equal(true, set.empty?)
  664. end
  665. def test_replace
  666. set = Set[1,2]
  667. ret = set.replace('a'..'c')
  668. assert_same(set, ret)
  669. assert_equal(Set['a','b','c'], set)
  670. end
  671. def test_to_a
  672. set = Set[1,2,3,2]
  673. ary = set.to_a
  674. assert_equal([1,2,3], ary.sort)
  675. end
  676. def test_flatten
  677. # test1
  678. set1 = Set[
  679. 1,
  680. Set[
  681. 5,
  682. Set[7,
  683. Set[0]
  684. ],
  685. Set[6,2],
  686. 1
  687. ],
  688. 3,
  689. Set[3,4]
  690. ]
  691. set2 = set1.flatten
  692. set3 = Set.new(0..7)
  693. assert_not_same(set2, set1)
  694. assert_equal(set3, set2)
  695. # test2; destructive
  696. orig_set1 = set1
  697. set1.flatten!
  698. assert_same(orig_set1, set1)
  699. assert_equal(set3, set1)
  700. # test3; multiple occurrences of a set in an set
  701. set1 = Set[1, 2]
  702. set2 = Set[set1, Set[set1, 4], 3]
  703. assert_nothing_raised {
  704. set2.flatten!
  705. }
  706. assert_equal(Set.new(1..4), set2)
  707. # test4; recursion
  708. set2 = Set[]
  709. set1 = Set[1, set2]
  710. set2.add(set1)
  711. assert_raises(ArgumentError) {
  712. set1.flatten!
  713. }
  714. # test5; miscellaneous
  715. empty = Set[]
  716. set = Set[Set[empty, "a"],Set[empty, "b"]]
  717. assert_nothing_raised {
  718. set.flatten
  719. }
  720. set1 = empty.merge(Set["no_more", set])
  721. assert_nil(Set.new(0..31).flatten!)
  722. x = Set[Set[],Set[1,2]].flatten!
  723. y = Set[1,2]
  724. assert_equal(x, y)
  725. end
  726. def test_include?
  727. set = Set[1,2,3]
  728. assert_equal(true, set.include?(1))
  729. assert_equal(true, set.include?(2))
  730. assert_equal(true, set.include?(3))
  731. assert_equal(false, set.include?(0))
  732. assert_equal(false, set.include?(nil))
  733. set = Set["1",nil,"2",nil,"0","1",false]
  734. assert_equal(true, set.include?(nil))
  735. assert_equal(true, set.include?(false))
  736. assert_equal(true, set.include?("1"))
  737. assert_equal(false, set.include?(0))
  738. assert_equal(false, set.include?(true))
  739. end
  740. def test_superset?
  741. set = Set[1,2,3]
  742. assert_raises(ArgumentError) {
  743. set.superset?()
  744. }
  745. assert_raises(ArgumentError) {
  746. set.superset?(2)
  747. }
  748. assert_raises(ArgumentError) {
  749. set.superset?([2])
  750. }
  751. assert_equal(true, set.superset?(Set[]))
  752. assert_equal(true, set.superset?(Set[1,2]))
  753. assert_equal(true, set.superset?(Set[1,2,3]))
  754. assert_equal(false, set.superset?(Set[1,2,3,4]))
  755. assert_equal(false, set.superset?(Set[1,4]))
  756. assert_equal(true, Set[].superset?(Set[]))
  757. end
  758. def test_proper_superset?
  759. set = Set[1,2,3]
  760. assert_raises(ArgumentError) {
  761. set.proper_superset?()
  762. }
  763. assert_raises(ArgumentError) {
  764. set.proper_superset?(2)
  765. }
  766. assert_raises(ArgumentError) {
  767. set.proper_superset?([2])
  768. }
  769. assert_equal(true, set.proper_superset?(Set[]))
  770. assert_equal(true, set.proper_superset?(Set[1,2]))
  771. assert_equal(false, set.proper_superset?(Set[1,2,3]))
  772. assert_equal(false, set.proper_superset?(Set[1,2,3,4]))
  773. assert_equal(false, set.proper_superset?(Set[1,4]))
  774. assert_equal(false, Set[].proper_superset?(Set[]))
  775. end
  776. def test_subset?
  777. set = Set[1,2,3]
  778. assert_raises(ArgumentError) {
  779. set.subset?()
  780. }
  781. assert_raises(ArgumentError) {
  782. set.subset?(2)
  783. }
  784. assert_raises(ArgumentError) {
  785. set.subset?([2])
  786. }
  787. assert_equal(true, set.subset?(Set[1,2,3,4]))
  788. assert_equal(true, set.subset?(Set[1,2,3]))
  789. assert_equal(false, set.subset?(Set[1,2]))
  790. assert_equal(false, set.subset?(Set[]))
  791. assert_equal(true, Set[].subset?(Set[1]))
  792. assert_equal(true, Set[].subset?(Set[]))
  793. end
  794. def test_proper_subset?
  795. set = Set[1,2,3]
  796. assert_raises(ArgumentError) {
  797. set.proper_subset?()
  798. }
  799. assert_raises(ArgumentError) {
  800. set.proper_subset?(2)
  801. }
  802. assert_raises(ArgumentError) {
  803. set.proper_subset?([2])
  804. }
  805. assert_equal(true, set.proper_subset?(Set[1,2,3,4]))
  806. assert_equal(false, set.proper_subset?(Set[1,2,3]))
  807. assert_equal(false, set.proper_subset?(Set[1,2]))
  808. assert_equal(false, set.proper_subset?(Set[]))
  809. assert_equal(false, Set[].proper_subset?(Set[]))
  810. end
  811. def test_each
  812. ary = [1,3,5,7,10,20]
  813. set = Set.new(ary)
  814. ret = set.each { |o| }
  815. assert_same(set, ret)
  816. e = set.each
  817. assert_instance_of(Enumerable::Enumerator, e)
  818. assert_nothing_raised {
  819. set.each { |o|
  820. ary.delete(o) or raise "unexpected element: #{o}"
  821. }
  822. ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
  823. }
  824. end
  825. def test_add
  826. set = Set[1,2,3]
  827. ret = set.add(2)
  828. assert_same(set, ret)
  829. assert_equal(Set[1,2,3], set)
  830. ret = set.add?(2)
  831. assert_nil(ret)
  832. assert_equal(Set[1,2,3], set)
  833. ret = set.add(4)
  834. assert_same(set, ret)
  835. assert_equal(Set[1,2,3,4], set)
  836. ret = set.add?(5)
  837. assert_same(set, ret)
  838. assert_equal(Set[1,2,3,4,5], set)
  839. end
  840. def test_delete
  841. set = Set[1,2,3]
  842. ret = set.delete(4)
  843. assert_same(set, ret)
  844. assert_equal(Set[1,2,3], set)
  845. ret = set.delete?(4)
  846. assert_nil(ret)
  847. assert_equal(Set[1,2,3], set)
  848. ret = set.delete(2)
  849. assert_equal(set, ret)
  850. assert_equal(Set[1,3], set)
  851. ret = set.delete?(1)
  852. assert_equal(set, ret)
  853. assert_equal(Set[3], set)
  854. end
  855. def test_delete_if
  856. set = Set.new(1..10)
  857. ret = set.delete_if { |i| i > 10 }
  858. assert_same(set, ret)
  859. assert_equal(Set.new(1..10), set)
  860. set = Set.new(1..10)
  861. ret = set.delete_if { |i| i % 3 == 0 }
  862. assert_same(set, ret)
  863. assert_equal(Set[1,2,4,5,7,8,10], set)
  864. end
  865. def test_collect!
  866. set = Set[1,2,3,'a','b','c',-1..1,2..4]
  867. ret = set.collect! { |i|
  868. case i
  869. when Numeric
  870. i * 2
  871. when String
  872. i.upcase
  873. else
  874. nil
  875. end
  876. }
  877. assert_same(set, ret)
  878. assert_equal(Set[2,4,6,'A','B','C',nil], set)
  879. end
  880. def test_reject!
  881. set = Set.new(1..10)
  882. ret = set.reject! { |i| i > 10 }
  883. assert_nil(ret)
  884. assert_equal(Set.new(1..10), set)
  885. ret = set.reject! { |i| i % 3 == 0 }
  886. assert_same(set, ret)
  887. assert_equal(Set[1,2,4,5,7,8,10], set)
  888. end
  889. def test_merge
  890. set = Set[1,2,3]
  891. ret = set.merge([2,4,6])
  892. assert_same(set, ret)
  893. assert_equal(Set[1,2,3,4,6], set)
  894. end
  895. def test_subtract
  896. set = Set[1,2,3]
  897. ret = set.subtract([2,4,6])
  898. assert_same(set, ret)
  899. assert_equal(Set[1,3], set)
  900. end
  901. def test_plus
  902. set = Set[1,2,3]
  903. ret = set + [2,4,6]
  904. assert_not_same(set, ret)
  905. assert_equal(Set[1,2,3,4,6], ret)
  906. end
  907. def test_minus
  908. set = Set[1,2,3]
  909. ret = set - [2,4,6]
  910. assert_not_same(set, ret)
  911. assert_equal(Set[1,3], ret)
  912. end
  913. def test_and
  914. set = Set[1,2,3,4]
  915. ret = set & [2,4,6]
  916. assert_not_same(set, ret)
  917. assert_equal(Set[2,4], ret)
  918. end
  919. def test_xor
  920. set = Set[1,2,3,4]
  921. ret = set ^ [2,4,5,5]
  922. assert_not_same(set, ret)
  923. assert_equal(Set[1,3,5], ret)
  924. end
  925. def test_eq
  926. set1 = Set[2,3,1]
  927. set2 = Set[1,2,3]
  928. assert_equal(set1, set1)
  929. assert_equal(set1, set2)
  930. assert_not_equal(Set[1], [1])
  931. set1 = Class.new(Set)["a", "b"]
  932. set2 = Set["a", "b", set1]
  933. set1 = set1.add(set1.clone)
  934. # assert_equal(set1, set2)
  935. # assert_equal(set2, set1)
  936. assert_equal(set2, set2.clone)
  937. assert_equal(set1.clone, set1)
  938. assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]")
  939. end
  940. # def test_hash
  941. # end
  942. # def test_eql?
  943. # end
  944. def test_classify
  945. set = Set.new(1..10)
  946. ret = set.classify { |i| i % 3 }
  947. assert_equal(3, ret.size)
  948. assert_instance_of(Hash, ret)
  949. ret.each_value { |value| assert_instance_of(Set, value) }
  950. assert_equal(Set[3,6,9], ret[0])
  951. assert_equal(Set[1,4,7,10], ret[1])
  952. assert_equal(Set[2,5,8], ret[2])
  953. end
  954. def test_divide
  955. set = Set.new(1..10)
  956. ret = set.divide { |i| i % 3 }
  957. assert_equal(3, ret.size)
  958. n = 0
  959. ret.each { |s| n += s.size }
  960. assert_equal(set.size, n)
  961. assert_equal(set, ret.flatten)
  962. set = Set[7,10,5,11,1,3,4,9,0]
  963. ret = set.divide { |a,b| (a - b).abs == 1 }
  964. assert_equal(4, ret.size)
  965. n = 0
  966. ret.each { |s| n += s.size }
  967. assert_equal(set.size, n)
  968. assert_equal(set, ret.flatten)
  969. ret.each { |s|
  970. if s.include?(0)
  971. assert_equal(Set[0,1], s)
  972. elsif s.include?(3)
  973. assert_equal(Set[3,4,5], s)
  974. elsif s.include?(7)
  975. assert_equal(Set[7], s)
  976. elsif s.include?(9)
  977. assert_equal(Set[9,10,11], s)
  978. else
  979. raise "unexpected group: #{s.inspect}"
  980. end
  981. }
  982. end
  983. def test_inspect
  984. set1 = Set[1]
  985. assert_equal('#<Set: {1}>', set1.inspect)
  986. set2 = Set[Set[0], 1, 2, set1]
  987. assert_equal(false, set2.inspect.include?('#<Set: {...}>'))
  988. set1.add(set2)
  989. assert_equal(true, set1.inspect.include?('#<Set: {...}>'))
  990. end
  991. # def test_pretty_print
  992. # end
  993. # def test_pretty_print_cycle
  994. # end
  995. end
  996. class TC_SortedSet < Test::Unit::TestCase
  997. def test_sortedset
  998. s = SortedSet[4,5,3,1,2]
  999. assert_equal([1,2,3,4,5], s.to_a)
  1000. prev = nil
  1001. s.each { |o| assert(prev < o) if prev; prev = o }
  1002. assert_not_nil(prev)
  1003. s.map! { |o| -2 * o }
  1004. assert_equal([-10,-8,-6,-4,-2], s.to_a)
  1005. prev = nil
  1006. ret = s.each { |o| assert(prev < o) if prev; prev = o }
  1007. assert_not_nil(prev)
  1008. assert_same(s, ret)
  1009. s = SortedSet.new([2,1,3]) { |o| o * -2 }
  1010. assert_equal([-6,-4,-2], s.to_a)
  1011. s = SortedSet.new(['one', 'two', 'three', 'four'])
  1012. a = []
  1013. ret = s.delete_if { |o| a << o; o.start_with?('t') }
  1014. assert_same(s, ret)
  1015. assert_equal(['four', 'one'], s.to_a)
  1016. assert_equal(['four', 'one', 'three', 'two'], a)
  1017. s = SortedSet.new(['one', 'two', 'three', 'four'])
  1018. a = []
  1019. ret = s.reject! { |o| a << o; o.start_with?('t') }
  1020. assert_same(s, ret)
  1021. assert_equal(['four', 'one'], s.to_a)
  1022. assert_equal(['four', 'one', 'three', 'two'], a)
  1023. s = SortedSet.new(['one', 'two', 'three', 'four'])
  1024. a = []
  1025. ret = s.reject! { |o| a << o; false }
  1026. assert_same(nil, ret)
  1027. assert_equal(['four', 'one', 'three', 'two'], s.to_a)
  1028. assert_equal(['four', 'one', 'three', 'two'], a)
  1029. end
  1030. end
  1031. class TC_Enumerable < Test::Unit::TestCase
  1032. def test_to_set
  1033. ary = [2,5,4,3,2,1,3]
  1034. set = ary.to_set
  1035. assert_instance_of(Set, set)
  1036. assert_equal([1,2,3,4,5], set.sort)
  1037. set = ary.to_set { |o| o * -2 }
  1038. assert_instance_of(Set, set)
  1039. assert_equal([-10,-8,-6,-4,-2], set.sort)
  1040. set = ary.to_set(SortedSet)
  1041. assert_instance_of(SortedSet, set)
  1042. assert_equal([1,2,3,4,5], set.to_a)
  1043. set = ary.to_set(SortedSet) { |o| o * -2 }
  1044. assert_instance_of(SortedSet, set)
  1045. assert_equal([-10,-8,-6,-4,-2], set.sort)
  1046. end
  1047. end
  1048. # class TC_RestricedSet < Test::Unit::TestCase
  1049. # def test_s_new
  1050. # assert_raises(ArgumentError) { RestricedSet.new }
  1051. #
  1052. # s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
  1053. # assert_equal([2,3], s.sort)
  1054. # end
  1055. #
  1056. # def test_restriction_proc
  1057. # s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
  1058. #
  1059. # f = s.restriction_proc
  1060. # assert_instance_of(Proc, f)
  1061. # assert(f[1])
  1062. # assert(!f[0])
  1063. # end
  1064. #
  1065. # def test_replace
  1066. # s = RestricedSet.new(-3..3) { |o| o > 0 }
  1067. # assert_equal([1,2,3], s.sort)
  1068. #
  1069. # s.replace([-2,0,3,4,5])
  1070. # assert_equal([3,4,5], s.sort)
  1071. # end
  1072. #
  1073. # def test_merge
  1074. # s = RestricedSet.new { |o| o > 0 }
  1075. # s.merge(-5..5)
  1076. # assert_equal([1,2,3,4,5], s.sort)
  1077. #
  1078. # s.merge([10,-10,-8,8])
  1079. # assert_equal([1,2,3,4,5,8,10], s.sort)
  1080. # end
  1081. # end