Skip to content

Instantly share code, notes, and snippets.

@shakked
Last active October 22, 2015 04:38
Show Gist options
  • Save shakked/2740b2e8105ba919a074 to your computer and use it in GitHub Desktop.
Save shakked/2740b2e8105ba919a074 to your computer and use it in GitHub Desktop.
Jug Problem
//
// main.swift
// Programming Assignment 4 - Water Jugs (Swift)
//
// Created by Zachary Shakked on 10/21/15.
// Copyright © 2015 Zachary Shakked. All rights reserved.
//
import Foundation
class Memo {
static let sharedMemo = Memo()
var values : Set<WaterJug> = Set<WaterJug>()
}
struct WaterJug: CustomStringConvertible, Hashable, Equatable {
let moveCount : Int
let capA : Int
let capB : Int
let capC : Int
let goalA : Int
let goalB : Int
let goalC : Int
let currA : Int
let currB : Int
let currC : Int
var description : String {
get {
return "[\(currA)/\(capA), \(currB)/\(capB), \(currC)/\(capC)]"
}
}
var goal : String {
get {
return "[\(goalA)/\(capA), \(goalB)/\(capB), \(goalC)/\(capC)]"
}
}
var state : (Int, Int, Int) {
get {
return (currA, currB, currC)
}
}
var hashValue : Int {
get {
return "\(currA)\(currB)\(currC)".hashValue
}
}
var currentHistory : String
init(moveCount: Int = 0, capA: Int, capB: Int, capC: Int, goalA: Int, goalB: Int, goalC: Int, currA: Int, currB: Int, currC: Int, currentHistory: String = "") {
self.moveCount = moveCount
self.capA = capA
self.capB = capB
self.capC = capC
self.goalA = goalA
self.goalB = goalB
self.goalC = goalC
self.currA = currA
self.currB = currB
self.currC = currC
self.currentHistory = currentHistory
}
func advance(count: Int) {
let newJugs : [WaterJug] = [c_to_a(), b_to_a(), c_to_b(), a_to_b(), b_to_c(), a_to_c()]
advanceHelper(count, jugs: newJugs)
}
func advanceHelper(count: Int, jugs: [WaterJug]) {
if count == 0 {
print("couldnt find nothing")
return
} else {
var futureJugs : [WaterJug] = []
for jug in jugs {
if jug.isComplete() {
print("FINALLY")
print("Current History:\n")
print(jug.currentHistory)
return
} else {
let newJugs : [WaterJug] = [jug.c_to_a(), jug.b_to_a(), jug.c_to_b(), jug.a_to_b(), jug.b_to_c(), jug.a_to_c()]
for jug in newJugs {
if !Memo.sharedMemo.values.contains(jug) {
Memo.sharedMemo.values.insert(jug)
futureJugs.append(jug)
}
}
}
}
advanceHelper(count - 1, jugs: futureJugs)
}
}
func isComplete() -> Bool {
let isComplete = currA == goalA && currB == goalB && currC == goalC
print("\(self) == \(goal) ? \(isComplete)\n")
return isComplete
}
func c_to_a() -> WaterJug {
print("\(self) C -> A")
var currC = self.currC
var currA = self.currA
while capA != currA && currC != 0 {
currA += 1
currC -= 1
}
var jugAfterTransfer = WaterJug(capA: capA, capB: capB, capC: capC, goalA: goalA, goalB: goalB, goalC: goalC, currA: currA, currB: currB, currC: currC)
jugAfterTransfer.currentHistory = self.currentHistory + "\n\(jugAfterTransfer) C -> A"
print("\(jugAfterTransfer)\n")
return jugAfterTransfer
}
func b_to_a() -> WaterJug {
print("\(self) B -> A")
var currB = self.currB
var currA = self.currA
while capA != currA && currB != 0 {
currA += 1
currB -= 1
}
var jugAfterTransfer = WaterJug(capA: capA, capB: capB, capC: capC, goalA: goalA, goalB: goalB, goalC: goalC, currA: currA, currB: currB, currC: currC)
jugAfterTransfer.currentHistory = self.currentHistory + "\n\(jugAfterTransfer) B -> A"
print("\(jugAfterTransfer)\n")
return jugAfterTransfer
}
func c_to_b() -> WaterJug {
print("\(self) C -> B")
var currC = self.currC
var currB = self.currB
while capB != currB && currC != 0 {
currB += 1
currC -= 1
}
var jugAfterTransfer = WaterJug(capA: capA, capB: capB, capC: capC, goalA: goalA, goalB: goalB, goalC: goalC, currA: currA, currB: currB, currC: currC)
jugAfterTransfer.currentHistory = self.currentHistory + "\n\(jugAfterTransfer) C -> B"
print("\(jugAfterTransfer)\n")
return jugAfterTransfer
}
func a_to_b() -> WaterJug {
print("\(self) A -> B")
var currA = self.currA
var currB = self.currB
while capB != currB && currA != 0 {
currB += 1
currA -= 1
}
var jugAfterTransfer = WaterJug(capA: capA, capB: capB, capC: capC, goalA: goalA, goalB: goalB, goalC: goalC, currA: currA, currB: currB, currC: currC)
jugAfterTransfer.currentHistory = self.currentHistory + "\n\(jugAfterTransfer) A -> B"
print("\(jugAfterTransfer)\n")
return jugAfterTransfer
}
func b_to_c() -> WaterJug {
print("\(self) B -> C")
var currB = self.currB
var currC = self.currC
while capC != currC && currB != 0 {
currC += 1
currB -= 1
}
var jugAfterTransfer = WaterJug(capA: capA, capB: capB, capC: capC, goalA: goalA, goalB: goalB, goalC: goalC, currA: currA, currB: currB, currC: currC)
jugAfterTransfer.currentHistory = self.currentHistory + "\n\(jugAfterTransfer) B -> C"
print("\(jugAfterTransfer)\n")
return jugAfterTransfer
}
func a_to_c() -> WaterJug {
print("\(self) A -> C")
var currA = self.currA
var currC = self.currC
while capC != currC && currA != 0 {
currC += 1
currA -= 1
}
var jugAfterTransfer = WaterJug(capA: capA, capB: capB, capC: capC, goalA: goalA, goalB: goalB, goalC: goalC, currA: currA, currB: currB, currC: currC)
jugAfterTransfer.currentHistory = self.currentHistory + "\n\(jugAfterTransfer) A -> C"
print("\(jugAfterTransfer)\n")
return jugAfterTransfer
}
}
func ==(lhs: WaterJug, rhs: WaterJug) -> Bool {
return lhs.hashValue == rhs.hashValue
}
let jug = WaterJug(capA: 3, capB: 5, capC: 8, goalA: 0, goalB: 4, goalC: 4, currA: 0, currB: 0, currC: 8)
jug.advance(25)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment