@@ -1,159 +0,0 @@
1−//
2−// Truther.swift
3−// Truther
4−//
5−// Created by Ilya Kos on 10/6/17.
6−// Copyright © 2017 Ilya Kos. All rights reserved.
7−//
8−
9−import Foundation
10−
11−struct Truther {
12− var formula: Formula
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))) {
16− var t = 0
17− var inp: [Bool] = []
18− for _ in formula.variables {
19− inp.append((UInt(i)>>t) & 1 == 1)
20− t += 1
21− }
22− inp = inp.reversed()
23− out.append((inp, formula.run(with: inp)))
24− }
25− return out
26− }
27−}
28−
29−struct Formula {
30− fileprivate func run(with inputs: [Bool]) -> Bool {
31− var ins: [Variable: Bool] = [:]
32− for (v, va) in zip(variables, inputs) {
33− ins[v] = va
34− }
35− return value.evaluate(with: ins)
36− }
37− init(_ f: String) {
38− var vars: Set<String> = Set()
39− func process(_ s: Substring, startingLeft: FormulaElement? = nil) -> FormulaElement {
40− if s.isEmpty {
41− guard let startingLeft = startingLeft else {
42− print("Internal error: Empty input")
43− exit(1)
44− }
45− return startingLeft
46− }
47− var ns = s.trimmingCharacters(in: .whitespaces)
48− if ns == "0" {
49− return .constant(false)
50− }
51− if ns == "1" {
52− return .constant(true)
53− }
54− if ns.trimmingCharacters(in: .whitespaces).reduce(true, {$0 && CharacterSet.letters.contains($1.unicodeScalars.first!)}) {
55− vars.insert(String(s))
56− return .variable(String(s))
57− }
58− func extractVar() -> Substring {
59− if ns.first == "(" {
60− let parts = extractBrackets(from: ns)
61− ns = parts.after.trimmingCharacters(in: .whitespaces)
62− return Substring(parts.wasInside.trimmingCharacters(in: .whitespaces))
63− } else {
64− if CharacterSet.whitespaces.contains((ns.first?.unicodeScalars.first)!) {
65− print("Internal error: weird variable name first charecter \(ns.first!)")
66− exit(1)
67− }
68− switch ns.first! {
69− case "0":
70− ns = ns.dropFirst().trimmingCharacters(in: .whitespaces)
71− return "0"
72− case "1":
73− ns = ns.dropFirst().trimmingCharacters(in: .whitespaces)
74− return "1"
75− default:
76− break
77− }
78− var i = ns.startIndex
79− while i < ns.endIndex {
80− if !CharacterSet.letters.contains(ns[i].unicodeScalars.first!) {
81− break
82− }
83− i = ns.index(after: i)
84− }
85− let out = ns[..<i]
86− ns = ns[i...].trimmingCharacters(in: .whitespaces)
87− return out
88− }
89− }
90− let left = startingLeft ?? process(extractVar())
91− ns = ns.trimmingCharacters(in: .whitespaces)
92− let isLetterOrNot = CharacterSet.letters.contains((ns.first?.unicodeScalars.first)!)
93− var i = ns.startIndex
94− while i < ns.endIndex {
95− if CharacterSet.letters.contains(ns[i].unicodeScalars.first!) != isLetterOrNot || ns[i] == " " {
96− break
97− }
98− i = ns.index(after: i)
99− }
100− guard let op = Operator.process(ns[..<i]) else {
101− print("No such operator \(ns[..<i])")
102− exit(1)
103− }
104− ns = ns[i...].trimmingCharacters(in: .whitespaces)
105− let right = process(extractVar())
106− return process(Substring(ns), startingLeft: .operation(left, op, right))
107− }
108− self.value = process(Substring(f))
109− self.variables = vars.sorted()
110− }
111− let variables: [String]
112− private let value: FormulaElement
113−}
114−
115−private func extractBrackets(from s: String) -> (wasInside: Substring, after: Substring) {
116− var i = s.startIndex
117− var brackets = 0
118− while i < s.endIndex {
119− switch s[i] {
120− case "(":
121− brackets += 1
122− case ")":
123− brackets -= 1
124− default:
125− break
126− }
127− if brackets == 0 {
128− break
129− }
130− i = s.index(after: i)
131− }
132− if brackets != 0 {
133− print("Mismatched brackets")
134− exit(1)
135− }
136− return (s[s.index(after: s.startIndex)..<i], s[s.index(after: i)...])
137−}
138−
139−private typealias Variable = String
140−private indirect enum FormulaElement {
141− case variable(Variable)
142− case constant(Bool)
143− case operation(FormulaElement, Operator, FormulaElement)
144− func evaluate(with variables: [Variable: Bool]) -> Bool {
145− switch self {
146− case .variable(let v):
147− if let va = variables[v] {
148− return va
149− } else {
150− print("Internal error: didn't initialize all variables")
151− exit(1)
152− }
153− case .operation(let l, let op, let r):
154− return op.value(l.evaluate(with: variables), r.evaluate(with: variables))
155− case .constant(let b):
156− return b
157− }
158− }
159−}