Created
August 11, 2015 14:50
-
-
Save cornedriesprong/98a6a11497b42014cb6b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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