Guest User

Untitled

a guest
Nov 20th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.52 KB | None | 0 0
  1. //
  2. // main.swift
  3. // DiskraSolverHW2
  4. //
  5. // Created by Ilya Kos on 11/17/17.
  6. // Copyright © 2017 Ilya Kos. All rights reserved.
  7. //
  8.  
  9. import Foundation
  10.  
  11. protocol Descriptable {
  12. func description() -> String
  13. }
  14.  
  15. class TuringMachine<A: Hashable & Descriptable> {
  16. let names: [String]
  17. var states: [State<A>] = []
  18. init(names: [String]) {
  19. self.names = names
  20. }
  21. func consume(states inStates: [[A: Operation<A>]?]) {
  22. states = inStates.enumerated().flatMap({ (i, s) in
  23. if let s = s{
  24. return State.init(name: self.names[i], operations: s)
  25. }
  26. return nil
  27. })
  28. }
  29.  
  30. func description(`for` alphabet: [A]) -> String {
  31. let alphabet = alphabet.shuffled()
  32. var out = [alphabet.map {$0.description()}.reduce("Q/A") {$0 + "\t\($1)"}]
  33. out.append((states.first?.description(alphabet: alphabet, names: self.names))!)
  34. out += states.dropFirst().shuffled().map {$0.description(alphabet: alphabet, names: self.names)}
  35. return out.reduce("") {$0 + "\n" + $1}
  36. }
  37. }
  38.  
  39. struct State<A: Hashable & Descriptable> {
  40. let name: String
  41. let operations: [A:Operation<A>]
  42. func description(alphabet: [A], names: [String]) -> String {
  43. return alphabet.lazy.map {self.operations[$0]?.description(selfName: self.name, names: names) ?? ""}
  44. .reduce(name) {"\($0)\t\($1)"}
  45. }
  46. }
  47.  
  48. enum Direction: Character {
  49. case left = "l"
  50. case right = "r"
  51. case stay = "n"
  52. }
  53.  
  54. class Operation<A: Hashable & Descriptable & Equatable>: Equatable {
  55. static func ==(lhs: Operation<A>, rhs: Operation<A>) -> Bool {
  56. return lhs.place == rhs.place && lhs.move == rhs.move && lhs.nextState == rhs.nextState
  57. }
  58.  
  59. func replace(_ i: Int, with j: Int) {
  60. if nextState == .other(i) {
  61. nextState = .other(j)
  62. }
  63. }
  64.  
  65. let place: A
  66. let move: Direction
  67. var nextState: NextState
  68. func description(selfName: String, names: [String]) -> String {
  69. return "\(place.description()) \(move.rawValue) \(nextState.description(selfName: selfName, names: names))"
  70. }
  71.  
  72. init(place: A, move: Direction, next: NextState) {
  73. self.place = place
  74. self.move = move
  75. self.nextState = next
  76. }
  77. }
  78.  
  79. enum NextState: Equatable {
  80. static func ==(lhs: NextState, rhs: NextState) -> Bool {
  81. switch lhs {
  82. case .self:
  83. switch rhs {
  84. case .self:
  85. return true
  86. default:
  87. return false
  88. }
  89. case .other(let n):
  90. switch rhs {
  91. case .other(let m):
  92. return m == n
  93. default:
  94. return false
  95. }
  96. }
  97. }
  98.  
  99. case `self`
  100. case other(Int)
  101. func description(selfName: String, names: [String]) -> String {
  102. switch self {
  103. case .self:
  104. return selfName
  105. case .other(let s):
  106. return names[s]
  107. }
  108. }
  109. }
  110.  
  111. enum Alphabet: Descriptable {
  112. static var aChar: Character = "a"
  113.  
  114. func description() -> String {
  115. switch self {
  116. case .zero:
  117. return "0"
  118. case .one:
  119. return "1"
  120. case .a:
  121. return String(Alphabet.aChar)
  122. case .none:
  123. return "_"
  124. case .star:
  125. return "*"
  126. }
  127. }
  128.  
  129. case zero
  130. case one
  131. case a
  132. case star
  133. case none
  134. }
  135.  
  136. extension MutableCollection {
  137. /// Shuffles the contents of this collection.
  138. mutating func shuffle() {
  139. let c = count
  140. guard c > 1 else { return }
  141.  
  142. for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
  143. let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
  144. let i = index(firstUnshuffled, offsetBy: d)
  145. swapAt(firstUnshuffled, i)
  146. }
  147. }
  148. }
  149.  
  150. extension Sequence {
  151. /// Returns an array with the contents of this sequence, shuffled.
  152. func shuffled() -> [Element] {
  153. var result = Array(self)
  154. result.shuffle()
  155. return result
  156. }
  157. }
  158.  
  159. let alpha = "qwertyuiopasdfghjklzxcvbnm"
  160. var names: [String] {
  161. return alpha.map {c in alpha.map {"\(c)\($0)"}}
  162. .reduce([], (+)).shuffled()
  163. }
  164.  
  165. func generateMachine(function: [Alphabet]) -> TuringMachine<Alphabet> {
  166. let machine = TuringMachine<Alphabet>(names: names)
  167. var states: [[Alphabet: Operation<Alphabet>]] = [
  168. [ // 0
  169. .zero: Operation(place: .zero, move: .left, next: .self),
  170. .one: Operation(place: .one, move: .left, next: .self),
  171. .star: Operation(place: .star, move: .left, next: .self),
  172. .none: Operation(place: .star, move: .right, next: .other(1))
  173. ],
  174. [ // 1
  175. .zero: Operation(place: .zero, move: .right, next: .other(2)),
  176. .one: Operation(place: .one, move: .right, next: .other(2)),
  177. .a: Operation(place: .a, move: .right, next: .self),
  178. .star: Operation(place: .star, move: .right, next: .self),
  179. .none: Operation(place: .none, move: .left, next: .other(25))
  180. ],
  181. [ // 2
  182. .zero: Operation(place: .zero, move: .right, next: .self),
  183. .one: Operation(place: .one, move: .right, next: .self),
  184. .a: Operation(place: .a, move: .right, next: .self),
  185. .star: Operation(place: .star, move: .right, next: .self),
  186. .none: Operation(place: .none, move: .left, next: .other(3))
  187. ],
  188. [ // 3
  189. .zero: Operation(place: .none, move: .left, next: .other(4)),
  190. .one: Operation(place: .none, move: .left, next: .other(5)),
  191. .star: Operation(place: .star, move: .left, next: .other(6))
  192. ]
  193. ]
  194. states += (6...7).map {n in // 4-5
  195. [
  196. .zero: Operation(place: .zero, move: .left, next: .self),
  197. .one: Operation(place: .one, move: .left, next: .self),
  198. .star: Operation(place: .star, move: .left, next: .other(n))
  199. ]
  200. }
  201. states += [8, 10].map { n in // 6-7
  202. [
  203. .zero: Operation(place: .a, move: .left, next: .other(n)),
  204. .one: Operation(place: .a, move: .left, next: .other(n + 1)),
  205. .a: Operation(place: .a, move: .left, next: .self),
  206. .star: Operation(place: .star, move: .left, next: .other(n + 4))
  207. ]
  208. }
  209. states += (12...15).map {n in // 8-11
  210. [
  211. .zero: Operation(place: .zero, move: .left, next: .self),
  212. .one: Operation(place: .one, move: .left, next: .self),
  213. .star: Operation(place: .star, move: .left, next: .other(n))
  214. ]
  215. }
  216. states += [16, 18, 20, 22].map { n in //12-15
  217. [
  218. .zero: Operation(place: .a, move: .left, next: .other(n)),
  219. .one: Operation(place: .a, move: .left, next: .other(n + 1)),
  220. .a: Operation(place: .a, move: .left, next: .self),
  221. .star: Operation(place: .star, move: .left, next: .other(n))
  222. ]
  223. }
  224. states += function.map { n in // 16-23
  225. [
  226. .zero: Operation(place: .zero, move: .left, next: .self),
  227. .one: Operation(place: .one, move: .left, next: .self),
  228. .star: Operation(place: .star, move: .left, next: .self),
  229. .none: Operation(place: n, move: .right, next: .other(24))
  230. ]
  231. }
  232. states += [ // 24-26
  233. [ // 24
  234. .zero: Operation(place: .zero, move: .right, next: .self),
  235. .one: Operation(place: .one, move: .right, next: .self),
  236. .a: Operation(place: .a, move: .right, next: .self),
  237. .star: Operation(place: .star, move: .right, next: .other(1))
  238. ],
  239. [ //25
  240. .zero: Operation(place: .zero, move: .left, next: .self),
  241. .one: Operation(place: .one, move: .left, next: .self),
  242. .a: Operation(place: .a, move: .left, next: .self),
  243. .star: Operation(place: .star, move: .left, next: .self),
  244. .none: Operation(place: .zero, move: .right, next: .other(26))
  245. ],
  246. [ //26
  247. .zero: Operation(place: .zero, move: .right, next: .self),
  248. .one: Operation(place: .one, move: .right, next: .self),
  249. .a: Operation(place: .a, move: .right, next: .self),
  250. .star: Operation(place: .star, move: .right, next: .self),
  251. .none: Operation(place: .none, move: .left, next: .other(27))
  252. ],
  253. ]
  254. states += (28...30).map { n in // 27-29
  255. [ // 27
  256. .zero: Operation(place: .none, move: .left, next: .self),
  257. .one: Operation(place: .none, move: .left, next: .self),
  258. .a: Operation(place: .none, move: .left, next: .self),
  259. .star: Operation(place: .none, move: .left, next: .other(n))
  260. ]
  261. }
  262.  
  263. states += [
  264. [ // 30
  265. .zero: Operation(place: .zero, move: .left, next: .self),
  266. .one: Operation(place: .one, move: .left, next: .self),
  267. .none: Operation(place: .none, move: .right, next: .other(31))
  268. ],
  269. [ // 31
  270. .zero: Operation(place: .none, move: .right, next: .self),
  271. .one: Operation(place: .one, move: .stay, next: .self),
  272. .none: Operation(place: .zero, move: .stay, next: .other(32))
  273. ],
  274. [ // 32
  275. .zero: Operation(place: .zero, move: .stay, next: .self)
  276. ]
  277. ]
  278.  
  279. func optimize(states: [[Alphabet: Operation<Alphabet>]]) -> [[Alphabet: Operation<Alphabet>]?] {
  280. var inStates: [[Alphabet: Operation<Alphabet>]?] = states
  281. var didChange = true
  282. while didChange {
  283. didChange = false
  284. var i = 0
  285. while i < inStates.count {
  286. if let state = inStates[i] {
  287. for (j, nextState) in inStates.lazy.enumerated().dropFirst(i + 1) {
  288. if let nextState = nextState {
  289. if state.count == nextState.count && state.keys.reduce(true) {$0 && (state[$1] == nextState[$1])} {
  290. didChange = true
  291. // print(state.map {"\(i) \($0.key): \($0.value.description(selfName: "self", names: (0...32).map {String($0)}))"})
  292. // print(nextState.map {"\(j) \($0.key): \($0.value.description(selfName: "self", names: (0...32).map {String($0)}))"})
  293. // print()
  294. inStates[j] = nil
  295. inStates.forEach {$0?.values.forEach {$0.replace(j, with: i)}}
  296. }
  297. }
  298. }
  299. }
  300. i += 1
  301. }
  302. // inStates.forEach { print($0?.map {"\($0.key): \($0.value.description(selfName: "self", names: (0...32).map {String($0)}))"})}
  303. }
  304. return inStates
  305. }
  306. machine.consume(states: optimize(states: states))
  307. return machine
  308. }
  309.  
  310. //print(generateMachine(function: [.one, .zero,.one, .zero,.one, .zero,.one, .zero,]).description(for: [.a, .none, .one, .star, .zero]))
  311.  
  312.  
  313. print("Please enter your function values F(0,0,0) F(0,0,1) ... F(1,1,1): ", separator: "", terminator: "")
  314. if let input = readLine(strippingNewline: true) {
  315. let onesAndZeros = input.filter({$0 == "0" || $0 == "1"})
  316. if onesAndZeros.count != 8 {
  317. print("Honestly, I was expecting 8 values...")
  318. exit(0)
  319. }
  320. let machine = generateMachine(function: onesAndZeros.map{$0 == "0" ? .zero : .one})
  321. print("Copy the folowing text into a .txt file.")
  322. print("NOTE: you must preserve tabs. (Some text editors convert tabs to spaces.)")
  323. print(machine.description(for: [.a, .none, .one, .star, .zero]))
  324. }
Add Comment
Please, Sign In to add comment