@@ -0,0 +1,140 @@
5+// Created by Ilya Kos on 10/6/17.
6+// Copyright © 2017 Ilya Kos. All rights reserved.
13+ func run() -> [(inp: [Bool], result: Bool)] {
14+ var out: [(inp: [Bool], result: Bool)] = []
15+ for i in 0..<Int(pow(2, Double(formula.variables.count))) {
18+ for _ in formula.variables {
19+ inp.append((UInt(i)>>t) & 1 == 1)
23+ out.append((inp, formula.run(with: inp)))
30+ fileprivate func run(with inputs: [Bool]) -> Bool {
31+ var ins: [Variable: Bool] = [:]
32+ for (v, va) in zip(variables, inputs) {
35+ return value.evaluate(with: ins)
38+ var vars: Set<String> = Set()
39+ func process(_ s: Substring, startingLeft: FormulaElement? = nil) -> FormulaElement {
41+ guard let startingLeft = startingLeft else {
42+ print("Internal error: Empty input")
47+ var ns = s.trimmingCharacters(in: .whitespaces)
48+ if ns.trimmingCharacters(in: .whitespaces).reduce(true, {$0 && CharacterSet.letters.contains($1.unicodeScalars.first!)}) {
49+ vars.insert(String(s))
50+ return .variable(String(s))
52+ func extractVar() -> Substring {
54+ let parts = extractBrackets(from: ns)
55+ ns = parts.after.trimmingCharacters(in: .whitespaces)
56+ return Substring(parts.wasInside.trimmingCharacters(in: .whitespaces))
58+ if CharacterSet.whitespaces.contains((ns.first?.unicodeScalars.first)!) {
59+ print("Internal error: weird variable name first charecter \(ns.first!)")
62+ var i = ns.startIndex
63+ while i < ns.endIndex {
64+ if !CharacterSet.letters.contains(ns[i].unicodeScalars.first!) {
67+ i = ns.index(after: i)
70+ ns = ns[i...].trimmingCharacters(in: .whitespaces)
74+ let left = startingLeft ?? process(extractVar())
75+ ns = ns.trimmingCharacters(in: .whitespaces)
76+ let isLetterOrNot = CharacterSet.letters.contains((ns.first?.unicodeScalars.first)!)
77+ var i = ns.startIndex
78+ while i < ns.endIndex {
79+ if CharacterSet.letters.contains(ns[i].unicodeScalars.first!) != isLetterOrNot || ns[i] == " " {
82+ i = ns.index(after: i)
84+ guard let op = Operator.process(ns[..<i]) else {
85+ print("No such operator \(ns[..<i])")
88+ ns = ns[i...].trimmingCharacters(in: .whitespaces)
89+ let right = process(extractVar())
90+ return process(Substring(ns), startingLeft: .operation(left, op, right))
92+ self.value = process(Substring(f))
93+ self.variables = vars.sorted()
95+ let variables: [String]
96+ private let value: FormulaElement
99+private func extractBrackets(from s: String) -> (wasInside: Substring, after: Substring) {
100+ var i = s.startIndex
102+ while i < s.endIndex {
114+ i = s.index(after: i)
117+ print("Mismatched brackets")
120+ return (s[s.index(after: s.startIndex)..<i], s[s.index(after: i)...])
123+private typealias Variable = String
124+private indirect enum FormulaElement {
125+ case variable(Variable)
126+ case operation(FormulaElement, Operator, FormulaElement)
127+ func evaluate(with variables: [Variable: Bool]) -> Bool {
129+ case .variable(let v):
130+ if let va = variables[v] {
133+ print("Internal error: didn't initialize all variables")
136+ case .operation(let l, let op, let r):
137+ return op.value(l.evaluate(with: variables), r.evaluate(with: variables))