PageRenderTime 120ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/vendor/jruby-1.1.6RC1/lib/ruby/1.8/set.rb

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