Clone connected graph in Swift

Given a reference of a node in a connected undirected graph.

Return a deep copy (clone) of the graph.

Solution: Create a queue, process node and it’s neighbors, create copies of nodes processed and create a reference in a dictionary between original and new nodes. Traverse dictionary to reestablish a relationship for new neighbors for copied nodes.

import UIKit

class Node {
    let title: String
    var neigbors: [Node]
    
    init(title: String) {
        self.title = title //assuming that title is a unique key
        self.neigbors = []
    }
    
    var description: String {
        var temp = ""
        for (node) in neigbors {
            temp += node.title + " "
        }
           return "Node: \(title) with Neigbors: \(temp)"
       }
}

// needs to conform to hashable in order to be inserted into the dictionary
extension Node: Hashable {
    // Equatable is needed for class in order to support Hashable
    static func == (lhs: Node, rhs: Node) -> Bool {
        return (lhs.title == rhs.title) && (lhs.neigbors == rhs.neigbors)
    }
    
  func hash(into hasher: inout Hasher) {
    hasher.combine(title)
   // hasher.combine(neigbors) // adding this will throw in the infinite loop
  }
}

func cloneGraph(root: Node) -> Node{
    var queue = [root]
    var cloneDict: [Node: Node] = [:]
   
    while queue.count > 0 {
        let cloneNode = Node(title: queue.first!.title + "-cloned")
        cloneDict.updateValue(cloneNode, forKey: queue.first!)
        
        //add only nodes that we haven't visited before
        for neigbor in queue.first!.neigbors {
            if ((cloneDict[neigbor] == nil)) {
                queue.append(neigbor)
            }
        }
        
        queue.remove(at: 0)
    }
    
    // reassign neigbors
    for (key, value) in cloneDict {
        for neigbor in key.neigbors {
            value.neigbors.append(cloneDict[neigbor]!)
        }
    }
    
    return cloneDict[root]!
}

func main() {
    let tempNodeA = Node(title: "A")
    let tempNodeB = Node(title: "B")
    let tempNodeC = Node(title: "C")
    let tempNodeD = Node(title: "D")
    
    tempNodeA.neigbors.append(tempNodeB)
    tempNodeA.neigbors.append(tempNodeD)
    tempNodeB.neigbors.append(tempNodeA)
    tempNodeB.neigbors.append(tempNodeC)
    tempNodeC.neigbors.append(tempNodeB)
    tempNodeC.neigbors.append(tempNodeD)
    tempNodeD.neigbors.append(tempNodeA)
    tempNodeD.neigbors.append(tempNodeC)
    
    print(cloneGraph(root: tempNodeA).description)
}

main()

Count the number of ways to traverse a Matrix in Swift

Question: Count the number of ways to traverse a from the top left corner to the bottom, right corner.
Limitation: we can only move down or right.

Few solutions: first one brute force and second dynamic programming and measuring their time execution below.
To compute 10 x 10 matrix with recursive brute force took 1.4 seconds while using dynamic programming took 0.04 seconds.

matrix traversal swift 5

matrix traversal swift 5

import Foundation
// recursive solution that has exponential time complexity: O(2^n), since each function call calls itself twice unless it has been recursed n times
func traverse (x: Int,y: Int) -> Int {
  
 if (x == 1) || (y == 1) {
  return 1
 }
  
 return traverse(x: x-1, y: y) + traverse(x:x, y: y-1)
}

// Dynamic programing O(m * n)
func dynamicTraverse (x: Int,y: Int) -> Int {

    var matrix = Array(repeating: Array(repeating: 0, count: x+1), count: y+1)

    for i in 1...x {
        for j in 1...y {
            if i == 1 || j == 1 {
                matrix[i][j] = 1
            } else {
                matrix[i][j] = matrix[i-1][j] + matrix[i][j-1]
            }
        }
    }
    
    return matrix[x][y]
}

func main() {
    measureTime {print(traverse(x:10, y:10))}
    measureTime {print(dynamicTraverse(x:10, y:10))}
}

//comupute execution time of any function passed in
func measureTime(closure: () -> Void) {
    let start = CFAbsoluteTimeGetCurrent()
    closure()
    let diff = CFAbsoluteTimeGetCurrent() - start
    print("Took \(diff) seconds")
}

main()

Minimum absolute difference in an array with Go

Problem url:
https://www.hackerrank.com/challenges/minimum-absolute-difference-in-an-array/problem

Solution:
Results are generated in O(n)*log(n) since we are sorting the array first. We can transfer sorted array and compare each number with the next find to find the smallest difference.

func minimumAbsoluteDifference(arr []int32) int32 {
    var f foo
    f = arr
    temp := Abs(f[0] - f[1]) 
    
    sort.Sort(f)
    fmt.Println(f)

    for i:=0; i < len(f) - 1; i++ {
            if Abs(f[i] - f[i+1]) < temp {
                temp = Abs(f[i] - f[i+1])
             }
    }

    return temp
}

// Abs returns the absolute value of x.
func Abs(x int32) int32 {
    if x < 0 {
        return -x
    }
    return x
}

//type foo that implements Sort for int32 type
type foo []int32

func (f foo) Len() int {
    return len(f)
}

func (f foo) Less(i, j int) bool {
    return f[i] < f[j]
}

func (f foo) Swap(i, j int) {
    f[i], f[j] = f[j], f[i]
}

Migratory Birds problem from Hackerrank with Go

Problem url:
https://www.hackerrank.com/challenges/migratory-birds/problem

Solution:
Results are generated in O(1) while traversing an array. We need to keep track of the largest value and keep a record of the smallest key.

func migratoryBirds(arr []int32) int32 {
     //key value
     m := make(map[int32]int32)

    largest := int32(0)
    largestKey := int32(0) 

    for _, key := range arr {
        c := incrementKey(key, m)
        if (largest < c) {
            largest = c
            largestKey = key
            fmt.Println(largest, largestKey)
        } else if (largest == c) {
            //compare keys
            if (largestKey > key){
                largestKey = key
            }
        }
    }

     fmt.Println(largest)
     return largestKey
}

func incrementKey(k int32, m map[int32]int32) int32 {
    if _, ok := m[k]; ok {
        m[k] += 1
    } else {
        m[k] = 1
    }
    return m[k]
}
Crossfit Open 19.2
Crossfit Open 19.2

CROSSFIT GAMES OPEN 19.2 STRATEGY AND ANALYSIS

19.2 CrossFit Open includes the following workout:

Beginning on an 8 min clock, complete as many reps as possible of:

  1. 25 Toes-to-bars
  2. 50 Double Unders 15 Squat Cleans,
  3. 135/85 lbs

 

  1. 25 Toes-to-bars
  2. 50 Double Unders 13 Squat Cleans,
  3. 185/115 lbs

If completed before 8 mins, add 4 mins to the clock and proceed to:

  1. 25 Toes-to-bars
  2. 50 Double Unders
  3. 11 Squat Cleans, 225/145 lbs

If completed before 12 mins, add 4 mins to the clock and proceed to:

  1. 25 Toes-to-bars
  2. 50 Double Unders
  3. 9 Squat Cleans, 275/175 lbs

If completed before 16 mins, add 4 mins to the clock and proceed to:

  1. 25 Toes-to-bars
  2. 50 Double Unders
  3. 7 Squat Cleans, 315/205 lbs

Stop at 20 mins.

 

Read more