Advertisement
Guest User

Functional Union Find!

a guest
Jul 10th, 2014
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.41 KB | None | 0 0
  1. package _01UnionFind
  2.  
  3. object UnionFind {
  4.    
  5.   /***functional union find!  Need to define a data type for connections
  6.    *
  7.    * A node is an int and a char, which are the ID and the Value
  8.    *
  9.    * A connected group is a set of nodes connected to each other.  If an node
  10.    * isnt connected to anything, it is in its own group.
  11.    *
  12.    * Connections is the set of all the connected groups.  Some of which may only have 1
  13.    * element in them.
  14.    */
  15.   type ConnectedGroup = List[ ( Int, Char ) ]
  16.   type Connections = List[ ConnectedGroup ]
  17.  
  18.   //Simple method to generate an intial Connections from a list of chars.
  19.   def CreateConnections( inlist: List[ Char ] ): Connections = {    
  20.     def CreateLoop( in: List[ Char ], id: Int ): Connections = in match {
  21.         case Nil => Nil
  22.         case x::xs => List(( id, x ))::CreateLoop( xs, id+1 )
  23.     }
  24.     CreateLoop(inlist, 0)
  25.   }
  26.  
  27.   /*** Now the fun stuff. ***/
  28.  
  29.   /* Union - given two IDs, combine them.
  30.    * We want to return a new Connections that represents the updated set.  So as we step through the old
  31.    * Connections, we can return, untouched, connected groups that do not contain p or q.  p and q's connected
  32.    * groups need to be combined, and then have them returned.  
  33.    *
  34.    */
  35.   def union( inlist: Connections, p: Int, q: Int ): Connections = {
  36.     def unionloop( in: Connections, carry: ConnectedGroup, p: Int, q: Int, found: Int ): Connections = in match {
  37.       case Nil => Nil
  38.       case node::nodes => {
  39.         if ( (contains( node, p ) || contains( node, q )) && ( found < 0 ) ) unionloop( nodes, node, p, q, 1 )
  40.         else if ( contains( node, p ) || contains( node, q ) ) ( carry:::node )::unionloop( nodes, carry, p, q, 1 )
  41.         else node::unionloop( nodes, carry, p, q, found )
  42.       }
  43.     }
  44.     unionloop( inlist, Nil, p, q, -1)
  45.   }
  46.  
  47.   def contains( group: ConnectedGroup, id: Int ): Boolean = group match {
  48.     case Nil => false
  49.     case node::nodes => if( node._1 == id ) true else contains( nodes, id )
  50.   }
  51.  
  52.   /* Find -Given an ID, return its value.
  53.    *  
  54.    *  I'm lazy, so this is gonna return a list of the chars with that ID, which should only ever
  55.    *  be a list of 1 or 0 char
  56.    *  
  57.    *  Inefficient algo though, touches every single node to find the value, so N
  58.    *
  59.    */
  60.   def find( inlist: Connections, p: Int ): List[Char] =
  61.     for (group <- inlist; node <- group; if node._1 == p ) yield node._2  
  62. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement