You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.3 KiB

  1. # coding: utf-8
  2. import os, sys
  3. from z3 import *
  4. from itertools import combinations
  5. pretty_print = True
  6. # get the playground information
  7. if len(sys.argv) != 2:
  8. print("Usage: python3 seating-arrangement.py <wedding-file>")
  9. sys.exit(0)
  10. def faulty_line(line, num):
  11. print("Faulty input at line " + str(num) + ". Ignoring '" + line + "'")
  12. # data structures prepared for you
  13. guests = set()
  14. friends = []
  15. foes = []
  16. longest_name_len = 0
  17. def add_to_guest_list(a,b=None):
  18. guests.add(a)
  19. if b != None:
  20. guests.add(b)
  21. def longest_name(a,b=None):
  22. global longest_name_len
  23. if len(a) > longest_name_len: longest_name_len = len(a)
  24. if b != None and len(b) > longest_name_len : longest_name_len = len(b)
  25. solver = Solver()
  26. ################################### Parse Guests and Constraints ####################################
  27. # todo: create a sort Guest
  28. with open(sys.argv[1]) as f:
  29. wedding = f.read()
  30. wedding = wedding.strip().split("\n")
  31. linenum = 0
  32. for line in wedding:
  33. linenum += 1
  34. if line[0] == '#':
  35. continue
  36. if line.rstrip():
  37. info = line.split(" ")
  38. if len(info) == 1:
  39. # todo: initialize Z3 Const and add single guest to 'guests' list
  40. add_to_guest_list()
  41. longest_name(info[0])
  42. continue
  43. if len(info) != 3:
  44. faulty_line(line, linenum)
  45. continue
  46. # todo: initialize Z3 Consts and add two guests to 'guests' list
  47. longest_name(info[0], info[2])
  48. if info[1] == "dislikes":
  49. # todo add pair of guests as foes
  50. pass
  51. elif info[1] == "likes":
  52. # todo add pair of guests as friends
  53. else:
  54. faulty_line(line, linenum)
  55. continue
  56. # todo: add two guests to 'guests' list
  57. ################################### Wedding Guests ####################################
  58. # todo create an uninterpreted function from your sort to integers
  59. # todo create a function which returns whether two guests are sitting next to each other
  60. def neigbours(a, b):
  61. pass
  62. # todo all guests must be seated at the big table
  63. # check the indices here
  64. for guest in guests:
  65. pass
  66. # todo no two guests should sit on the same position
  67. for combination in combinations(guests,2): #todo
  68. pass
  69. #todo friends should be neigbours
  70. for (a,b) in friends: #todo
  71. pass
  72. #todo foes should not be neigbours
  73. for (a,b) in foes: # todo
  74. pass
  75. # check satisfiability
  76. res = solver.check()
  77. if res != sat:
  78. print("unsat")
  79. sys.exit(1)
  80. m = solver.model()
  81. ################################################################################
  82. arrangement = ["" for guest in range(len(guests))]
  83. for guest in guests:
  84. arrangement[m.evaluate(position(guest),model_completion=True).as_long()] = guest.decl().name()
  85. def print_table():
  86. side_length = round(len(guests)/4)
  87. top = arrangement[0:side_length]
  88. right = arrangement[side_length:2*side_length]
  89. bottom = arrangement[2*side_length:3*side_length]
  90. left = arrangement[3*side_length:]
  91. while len(left) < len(right):
  92. left.append("")
  93. while len(right) < len(left):
  94. right.append("")
  95. table_line_length = longest_name_len + 1
  96. print("\n")
  97. top_row = ""
  98. top_row += (longest_name_len + 1) * " "
  99. for top_guest in top:
  100. top_row += top_guest + " "
  101. table_line_length += len(top_guest) + 1
  102. print(top_row)
  103. print((longest_name_len + 1) * " " + table_line_length * "-")
  104. first_element = True
  105. for left_guest, right_guest in zip(reversed(left), right):
  106. row = ""
  107. if not first_element:
  108. row += longest_name_len * " "
  109. row += "|" + ">"* (table_line_length) + "|"
  110. print(row)
  111. row = ""
  112. else:
  113. first_element = False
  114. row += left_guest.rjust(longest_name_len) + "|" + "<"* (table_line_length) + "|" + right_guest
  115. print(row)
  116. print((longest_name_len + 1) * " " + table_line_length * "-")
  117. bottom_row = ""
  118. bottom_row += (longest_name_len + 1) * " "
  119. for bottom_guest in reversed(bottom):
  120. bottom_row += bottom_guest + " "
  121. print(bottom_row)
  122. print("\n")
  123. if(pretty_print):
  124. print_table()
  125. print("Seating plan:")
  126. print(arrangement)