Skip to content

Instantly share code, notes, and snippets.

@cornedriesprong
Created August 11, 2015 14:50
Show Gist options
  • Save cornedriesprong/98a6a11497b42014cb6b to your computer and use it in GitHub Desktop.
Save cornedriesprong/98a6a11497b42014cb6b to your computer and use it in GitHub Desktop.
// infix flatMap operator - copied verbatim from http://www.objc.io/blog/2014/10/27/functional-snippet-4-flattening-and-mapping-arrays/
infix operator >>= {}
func >>=<A, B>(xs: [A], f: A -> [B]) -> [B] {
return xs.map(f).reduce([], combine: +)
}
// decomposes array xs into a tuple containing the first element and the rest of the array. copied and edited from http://www.objc.io/blog/2014/10/06/functional-snippet-1-decomposing-arrays/
func decompose<T>(xs: [T]) -> (T, [T])? {
return xs.count > 0 ? (xs[0], Array(xs[1..<xs.count])) : nil
}
// recursive function to compute all possible ways to insert an element x into an array ys. this and next function copied verbatim from http://www.objc.io/blog/2014/12/08/functional-snippet-10-permutations/
func between<T>(x: T, ys: [T]) -> [[T]] {
if let (head, tail) = decompose(ys) {
return [[x] + ys] + between(x, tail).map { [head] + $0 }
} else {
return [[x]]
}
}
// recursive function to generate all possible permutations of array xs.
func permutations<T>(xs: [T]) -> [[T]] {
if let (head, tail) = decompose(xs) {
return permutations(tail) >>= { permTail in
between(head, permTail)
}
} else {
return [[]]
}
}
let operands = [2, 4, 8, 16, 32]
// generate all permutations of set of operands
let operandPermutations = permutations(operands)
let operators: [(Int, Int) -> Int] = [(+), (-), (*), (/)]
// generate all cartesian product of operator set with itself (i.e., all possible combinations (with repetitions) in every possible order
let operatorsCartesianProduct = operators >>= {
x1 in operators >>= {
x2 in operators >>= {
x3 in operators >>= {
x4 in [[x1, x2, x3, x4]]
}
}
}
}
// map and flatten all operator and operand sets into one array
let operatorAndOperandCombos = operandPermutations >>= { operandArray in
operatorsCartesianProduct >>= { operatorArray in [(operands: operandArray, operators: operatorArray)] }
}
var resultsArray = [(Array<Int>, Array<(Int, Int) -> Int>)]()
// iterate over operator + operand sets and put set in array when result is 11
for ts in operatorAndOperandCombos {
var count: Int = 0
let (head, tail) = decompose(ts.operands)!
let result: Int? = tail.reduce(head.0) { x, y in
let r = ts.operators[count](x, y)
count++
return r
}
if result == 11 {
resultsArray.append(ts)
}
}
// iterate over results to determine arithmetic functions and generate strings from results
var resultStringArray = [String]()
for r in resultsArray {
var operatorSymbols = [String]()
let fs = r.1
for f in fs {
switch f(2, 3) {
case 5:
operatorSymbols.append("+")
case -1:
operatorSymbols.append("-")
case 6:
operatorSymbols.append("*")
default:
operatorSymbols.append("/")
}
}
let x0 = r.0[0].description
let y0 = operatorSymbols[0]
let x1 = r.0[1].description
let y1 = operatorSymbols[1]
let x2 = r.0[2].description
let y2 = operatorSymbols[2]
let x3 = r.0[3].description
let y3 = operatorSymbols[3]
let x4 = r.0[4].description
let resultString = "(((" + x0 + y0 + x1 + ")" + y1 + x2 + ")" + y2 + x3 + ")" + y3 + x4
resultStringArray.append(resultString)
}
println(resultStringArray)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment