daily pastebin goal
41%
SHARE
TWEET

Untitled

a guest Jun 19th, 2017 46 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ///<reference path="NLA.ts"/>
  2.  
  3.  
  4.  
  5.  class CustomSet<T extends Equalable> implements Set<T> {
  6.     [Symbol.toStringTag]:'Set' = 'Set'
  7.  
  8.     forEach(callbackfn: (value: T, index: T, set: Set<T>)=>void, thisArg?: any): void {
  9.         for (const value of this.entries()) {
  10.             callbackfn.call(thisArg, value, value, this)
  11.         }
  12.     }
  13.     _map: Map<int, T[]>
  14.     _size: int
  15.  
  16.  
  17.     constructor(iterable?: Iterable<T>) {
  18.         this._map = new Map()
  19.         this._size = 0
  20.         if (iterable) {
  21.             this.addAll(iterable)
  22.         }
  23.     }
  24.  
  25.     add(val: T): this {
  26.         this.add2(val)
  27.         return this
  28.     }
  29.  
  30.     add2(val: T): boolean {
  31.         // you can't use this.canonicalize here, as there is no way to differentiate if val
  32.         // is new or if val was === the exisitng value (not only .equals)
  33.         const hashCode = val.hashCode(), bucket = this._map.get(hashCode)
  34.         if (bucket) {
  35.             if (bucket.some(x => x.equals(val))) {
  36.                 return false
  37.             }
  38.             bucket.push(val)
  39.         } else {
  40.             this._map.set(hashCode, [val])
  41.         }
  42.         this._size++
  43.         return true
  44.     }
  45.  
  46.     addAll(iterable: Iterable<T>): this {
  47.         for (const val of iterable) {
  48.             this.add(val)
  49.         }
  50.         return this
  51.     }
  52.  
  53.     canonicalize(val: T): T {
  54.         const hashCode = val.hashCode(), bucket = this._map.get(hashCode)
  55.         if (bucket) {
  56.             const existing = bucket.find(x => x.equals(val))
  57.             if (existing) {
  58.                 return existing
  59.             }
  60.             bucket.push(val)
  61.         } else {
  62.             this._map.set(hashCode, [val])
  63.         }
  64.         this._size++
  65.         return val
  66.     }
  67.  
  68.     has(val: T): boolean {
  69.         const hashCode = val.hashCode(), bucket = this._map.get(hashCode)
  70.         return bucket && bucket.some(x => x.equals(val))
  71.     }
  72.  
  73.     getLike(val: T) {
  74.         for (const hashCode of val.hashCodes()) {
  75.             const bucket = this._map.get(hashCode)
  76.             const canonVal = bucket && bucket.find(x => x.like(val))
  77.             if (canonVal) return canonVal
  78.         }
  79.     }
  80.  
  81.     canonicalizeLike(val: T) {
  82.         // if this.getLike(val) is defined, return it, otherwise add val and return val
  83.         return this.getLike(val) || this.canonicalize(val)
  84.     }
  85.  
  86.     addLike(val: T) {
  87.         return !this.getLike(val) && this.add(val)
  88.     }
  89.  
  90.     'delete'(val: T) {
  91.         const hashCode = val.hashCode(), bucket = this._map.get(hashCode)
  92.         if (bucket) {
  93.             const index = bucket.findIndex(x => x.equals(val))
  94.             if (-1 != index) {
  95.                 if (1 == bucket.length) {
  96.                     this._map.delete(hashCode)
  97.                 } else {
  98.                     bucket.splice(index, 1)
  99.                 }
  100.                 this._size--
  101.                 return true
  102.             }
  103.         }
  104.         return false
  105.     }
  106.  
  107.     deleteLike(val: T) {
  108.         for (let hashCode of val.hashCodes()) {
  109.             const bucket = this._map.get(hashCode)
  110.             if (bucket) {
  111.                 const index = bucket.findIndex(x => x.like(val))
  112.                 if (-1 != index) {
  113.                     const deleted = bucket[index]
  114.                     if (1 == bucket.length) {
  115.                         this._map.delete(hashCode)
  116.                     } else {
  117.                         bucket.splice(index, 1)
  118.                     }
  119.                     this._size--
  120.                     return deleted
  121.                 }
  122.             }
  123.         }
  124.     }
  125.  
  126.     *values(): IterableIterator<T> {
  127.         for (const bucket of this._map.values()) {
  128.             yield* bucket
  129.         }
  130.     }
  131.     *entries(): IterableIterator<[T, T]> {
  132.         for (const bucket of this._map.values()) {
  133.             for (const value of bucket) {
  134.                 yield [value, value]
  135.             }
  136.         }
  137.     }
  138.  
  139.     clear(): void {
  140.         this._map.clear()
  141.         this._size = 0
  142.     }
  143.  
  144.     get size(): int {
  145.         return this._size
  146.     }
  147.  
  148.     toString() {
  149.         return '{' + Array.from(this.values()).join(', ') + '}'
  150.     }
  151.  
  152.     [Symbol.iterator] = CustomSet.prototype.values
  153.     keys = CustomSet.prototype.values
  154. }
  155.  
  156. class Pair<L extends Equalable, R extends Equalable> implements Equalable {
  157.  
  158.     constructor(public left: L, public right: R) {}
  159.  
  160.     hashCode() {
  161.         return this.left.hashCode() * 31 + this.right.hashCode()
  162.     }
  163.  
  164.     equals(other: any) {
  165.         return this == other || Object.getPrototypeOf(other) == Pair.prototype && this.left.equals(other.left) && this.right.equals(other.right)
  166.     }
  167.  
  168.     toString() {
  169.         return '(' + this.left.toString() + ', ' + this.right.toString() + ')'
  170.     }
  171.  
  172.     toSource() {
  173.         return 'new Pair(' + this.left.toSource() + ', ' + this.right.toSource() + ')'
  174.     }
  175. }
RAW Paste Data
Top