Advertisement
Guest User

Untitled

a guest
Jul 18th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.15 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3.  
  4. from __future__ import (absolute_import, division, print_function,
  5. unicode_literals)
  6. import sys
  7. import logging
  8. import z3
  9.  
  10. log = logging.getLogger(__name__)
  11.  
  12.  
  13. def guestpuzzle():
  14. """Main script.
  15.  
  16. """
  17. # Define each room as a number.
  18. rooms = [11, 12, 13, 14, 15, 16, 17,
  19. 21, 22, 23, 24, 25, 26, 27, 28]
  20.  
  21. showers = [13, 17, 14, 15, 25, 28, 24, 23]
  22. baths = [11, 12, 16, 27, 26, 21, 22]
  23.  
  24. # These rooms have a balcony (24 is broken)
  25. balcony = [27, 25, 23, 21]
  26.  
  27. # Dir facing
  28. south_facing = [14, 12, 28, 26]
  29. east_facing = [16, 23, 22]
  30.  
  31. # Twins available
  32. twins = [17, 12, 24, 21, 22]
  33.  
  34. # Noisy rooms for disco
  35. disco = [11, 16, 24, 23]
  36.  
  37. # View of pool. Not 1.4 or 2.8 due to tree
  38. pool_view = [26, 12, 21]
  39.  
  40. # Primes
  41. primes = [11, 13, 17, 23]
  42.  
  43. canhold2 = [17, 15, 13, 11, 16, 25, 23, 22, 26, 14, 27, 28, 12, 24, 21]
  44. canhold3 = [14, 27, 28, 12, 24, 21]
  45. canhold4 = [12, 24, 21]
  46.  
  47. ground_floor = [11, 12, 13, 14, 15, 16, 17]
  48.  
  49. # Now do the bookings!
  50. constraints = []
  51. bookings = []
  52. columns = []
  53.  
  54. # Wilcotts want a balcony. There's 3 of them.
  55. booking1 = z3.Int("Wilcotts")
  56. constraints.append(isin(booking1, balcony))
  57. constraints.append(isin(booking1, canhold3))
  58. bookings.append(booking1)
  59. columns.append("Wilcotts")
  60.  
  61. # Carnfore want a south facing room. There's 3 of them.
  62. booking2 = z3.Int("Carnfore")
  63. constraints.append(isin(booking2, south_facing))
  64. constraints.append(isin(booking2, canhold3))
  65. bookings.append(booking2)
  66. columns.append("Carnfore")
  67.  
  68. # Osmonds want a bath. There's 4 of them.
  69. booking3 = z3.Int("Osmond")
  70. constraints.append(isin(booking3, baths))
  71. constraints.append(isin(booking3, canhold4))
  72. bookings.append(booking3)
  73. columns.append("Osmond")
  74.  
  75. # Wallers have no requests. There's 2 of them.
  76. booking4 = z3.Int("Waller")
  77. constraints.append(isin(booking4, canhold2))
  78. bookings.append(booking4)
  79. columns.append("Waller")
  80.  
  81. # PoitierVert want a twin.
  82. booking5 = z3.Int("PoitierVert")
  83. constraints.append(isin(booking5, twins))
  84. constraints.append(isin(booking5, canhold2))
  85. bookings.append(booking5)
  86. columns.append("PoitierVert")
  87.  
  88. # Jennings want no balcony. x4. Also quiet.
  89. booking6 = z3.Int("Jennings")
  90. constraints.append(z3.Not(isin(booking6, balcony)))
  91. constraints.append(z3.Not(isin(booking6, disco)))
  92. constraints.append(isin(booking6, canhold4))
  93. bookings.append(booking6)
  94. columns.append("Jennings")
  95.  
  96. # Tudor/Smith want no east. x2. And shower
  97. booking7 = z3.Int("TudorSmith")
  98. constraints.append(z3.Not(isin(booking7, east_facing)))
  99. constraints.append(isin(booking7, showers))
  100. constraints.append(isin(booking7, canhold2))
  101. bookings.append(booking7)
  102. columns.append("TudorSmith")
  103.  
  104. # FoxMoran don't want primes x2.
  105. booking9 = z3.Int("FoxMoran")
  106. constraints.append(isin(booking9, canhold2))
  107. constraints.append(z3.Not(isin(booking9, primes)))
  108. bookings.append(booking9)
  109. columns.append("FoxMoran")
  110.  
  111. # Proctors want a balcony. x2.
  112. booking10 = z3.Int("Proctor")
  113. constraints.append(isin(booking10, canhold2))
  114. constraints.append(isin(booking10, balcony))
  115. bookings.append(booking10)
  116. columns.append("Proctor")
  117.  
  118. # Vieras want ground floor. x3
  119. booking11 = z3.Int("Vieras")
  120. constraints.append(isin(booking11, canhold3))
  121. constraints.append(isin(booking11, ground_floor))
  122. bookings.append(booking11)
  123. columns.append("Vieras")
  124.  
  125. # WilliamsAdams want pool view. x2
  126. booking12 = z3.Int("WilliamsAdams")
  127. constraints.append(isin(booking12, canhold2))
  128. constraints.append(isin(booking12, pool_view))
  129. bookings.append(booking12)
  130. columns.append("WilliamsAdams")
  131.  
  132. # InglebyCooper want twin. x2
  133. booking13 = z3.Int("InglebyCooper")
  134. constraints.append(isin(booking13, canhold2))
  135. constraints.append(isin(booking13, twins))
  136. bookings.append(booking13)
  137. columns.append("InglebyCooper")
  138.  
  139. # Inglebys want to be adjoined to InglebyCooper. x2
  140. booking14 = z3.Int("Inglebys")
  141. constraints.append(isin(booking14, canhold2))
  142. constraints.append(adjacent(booking13, booking14))
  143. bookings.append(booking14)
  144. columns.append("Inglebys")
  145.  
  146. # Cheshams don't care. x3
  147. booking15 = z3.Int("Cheshams")
  148. constraints.append(isin(booking15, canhold3))
  149. bookings.append(booking15)
  150. columns.append("Cheshams")
  151.  
  152. # Grahams want no noise. x2.
  153. booking8 = z3.Int("Graham")
  154. constraints.append(isin(booking8, canhold2))
  155. constraints.append(z3.Not(isin(booking8, disco)))
  156. # No kids
  157. constraints.append(z3.Not(noiseadjacent(booking8, booking3)))
  158. constraints.append(z3.Not(noiseadjacent(booking8, booking4)))
  159. constraints.append(z3.Not(noiseadjacent(booking8, booking6)))
  160. constraints.append(z3.Not(noiseadjacent(booking8, booking11))) # ???
  161. bookings.append(booking8)
  162. columns.append("Graham")
  163.  
  164. # All bookings are distinct.
  165. constraints.append(z3.Distinct(*bookings))
  166.  
  167. # Show our constraints
  168. log.debug("Constraints: %s", constraints)
  169.  
  170. # Try and solve it!
  171. s = z3.Solver()
  172. s.add(constraints)
  173.  
  174. sol_num = 0
  175.  
  176. models = []
  177.  
  178. while s.check() == z3.sat:
  179. sol_num += 1
  180. log.info("Solution %d found!", sol_num)
  181.  
  182. model = s.model()
  183. log.info("%s", model)
  184.  
  185. models.append(model)
  186.  
  187. # Add a constraint such that we don't regenerate the same model.
  188. s.add(z3.Or(booking1 != model[booking1],
  189. booking2 != model[booking2],
  190. booking3 != model[booking3],
  191. booking4 != model[booking4],
  192. booking5 != model[booking5],
  193. booking6 != model[booking6],
  194. booking7 != model[booking7],
  195. booking8 != model[booking8],
  196. booking9 != model[booking9],
  197. booking10 != model[booking10],
  198. booking11 != model[booking11],
  199. booking12 != model[booking12],
  200. booking13 != model[booking13],
  201. booking14 != model[booking14],
  202. booking15 != model[booking15]))
  203.  
  204. if sol_num == 0:
  205. log.error("Solution not found :(")
  206. else:
  207. with open("guestpuzzle3.csv", "wt") as f:
  208. f.write(",".join(columns))
  209. f.write("\n")
  210.  
  211. for model in models:
  212. fields = [str(model[booking]) for booking in bookings]
  213. f.write(",".join(fields))
  214. f.write("\n")
  215.  
  216. return ScriptRC.SUCCESS
  217.  
  218.  
  219. def isin(z3int, intlist):
  220. constraints = [z3int == x for x in intlist]
  221. return z3.Or(*constraints)
  222.  
  223.  
  224. def adjacent(first, second):
  225. constraints = [
  226. # First floor
  227. z3.And(first == 17, second == 15),
  228. z3.And(first == 15, second == 17),
  229. z3.And(first == 15, second == 13),
  230. z3.And(first == 13, second == 15),
  231. z3.And(first == 13, second == 11),
  232. z3.And(first == 11, second == 13),
  233. z3.And(first == 14, second == 12),
  234. z3.And(first == 12, second == 14),
  235.  
  236. # Second floor
  237. z3.And(first == 27, second == 25),
  238. z3.And(first == 25, second == 27),
  239. z3.And(first == 25, second == 24),
  240. z3.And(first == 24, second == 25),
  241. z3.And(first == 24, second == 23),
  242. z3.And(first == 23, second == 24),
  243. z3.And(first == 23, second == 22),
  244. z3.And(first == 22, second == 23),
  245. z3.And(first == 28, second == 26),
  246. z3.And(first == 26, second == 28),
  247. ]
  248. return z3.Or(*constraints)
  249.  
  250.  
  251. def noiseadjacent(first, second):
  252. constraints = [
  253. # First floor
  254. z3.And(first == 17, second == 15),
  255. z3.And(first == 17, second == 27),
  256.  
  257. z3.And(first == 15, second == 17),
  258. z3.And(first == 15, second == 13),
  259. z3.And(first == 15, second == 27),
  260. z3.And(first == 15, second == 25),
  261.  
  262. z3.And(first == 13, second == 15),
  263. z3.And(first == 13, second == 11),
  264. z3.And(first == 13, second == 25),
  265.  
  266. z3.And(first == 11, second == 13),
  267. z3.And(first == 11, second == 25),
  268. z3.And(first == 11, second == 24),
  269.  
  270. z3.And(first == 14, second == 12),
  271. z3.And(first == 14, second == 28),
  272. z3.And(first == 12, second == 14),
  273. z3.And(first == 12, second == 26),
  274.  
  275. z3.And(first == 16, second == 22),
  276.  
  277. # Second floor
  278. z3.And(first == 27, second == 25),
  279. z3.And(first == 27, second == 17),
  280. z3.And(first == 27, second == 15),
  281.  
  282. z3.And(first == 25, second == 27),
  283. z3.And(first == 25, second == 24),
  284. z3.And(first == 25, second == 13),
  285. z3.And(first == 25, second == 15),
  286. z3.And(first == 25, second == 11),
  287.  
  288. z3.And(first == 24, second == 25),
  289. z3.And(first == 24, second == 23),
  290. z3.And(first == 24, second == 11),
  291.  
  292. z3.And(first == 23, second == 24),
  293. z3.And(first == 23, second == 22),
  294.  
  295. z3.And(first == 22, second == 23),
  296. z3.And(first == 22, second == 16),
  297.  
  298. z3.And(first == 28, second == 26),
  299. z3.And(first == 28, second == 14),
  300. z3.And(first == 26, second == 28),
  301. z3.And(first == 26, second == 12),
  302. ]
  303. return z3.Or(*constraints)
  304.  
  305.  
  306. def main():
  307. """Main handling function. Wraps program."""
  308.  
  309. # Set up basic logging
  310. logging.basicConfig(format="%(asctime)s %(levelname)-5.5s %(message)s",
  311. stream=sys.stdout,
  312. level=logging.DEBUG)
  313.  
  314. # Run main script.
  315. try:
  316. rc = guestpuzzle()
  317. except Exception as e:
  318. log.exception(e)
  319. rc = ScriptRC.EXCEPTION
  320.  
  321. log.info("Returning %d", rc)
  322. return rc
  323.  
  324.  
  325. class ScriptRC(object):
  326. SUCCESS = 0
  327. FAILURE = 1
  328. EXCEPTION = 2
  329.  
  330.  
  331. class ScriptException(Exception):
  332. pass
  333.  
  334.  
  335. if __name__ == '__main__':
  336. sys.exit(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement