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.

160 lines
4.4 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. Guest = DeclareSort("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. guest = Const(info[0], Guest)
  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. longest_name(info[0], info[2])
  47. if info[1] == "dislikes":
  48. first_guest = Const(info[0], Guest)
  49. second_guest = Const(info[2], Guest)
  50. add_to_guest_list(first_guest, second_guest)
  51. # todo add the pair of guests as foes
  52. elif info[1] == "likes":
  53. first_guest = Const(info[0], Guest)
  54. second_guest = Const(info[2], Guest)
  55. add_to_guest_list(first_guest, second_guest)
  56. # todo add pair of guests as friends
  57. else:
  58. faulty_line(line, linenum)
  59. continue
  60. ################################### Wedding Guests ####################################
  61. # todo create an uninterpreted function from the Guest sort to an IntSort()
  62. # todo create a function which returns whether two guests are sitting next to each other
  63. def neigbours(a, b):
  64. pass
  65. # todo all guests must be seated at the big table
  66. # check the indices here
  67. for guest in guests:
  68. pass
  69. # todo no two guests should sit on the same position
  70. for combination in combinations(guests,2): #todo
  71. pass
  72. #todo friends should be neigbours
  73. for (a,b) in friends: #todo
  74. pass
  75. #todo foes should not be neigbours
  76. for (a,b) in foes: # todo
  77. pass
  78. # check satisfiability
  79. res = solver.check()
  80. if res != sat:
  81. print("unsat")
  82. sys.exit(1)
  83. m = solver.model()
  84. ################################################################################
  85. arrangement = ["" for guest in range(len(guests))]
  86. for guest in guests:
  87. arrangement[m.evaluate(position(guest),model_completion=True).as_long()] = guest.decl().name()
  88. def print_table():
  89. side_length = round(len(guests)/4)
  90. top = arrangement[0:side_length]
  91. right = arrangement[side_length:2*side_length]
  92. bottom = arrangement[2*side_length:3*side_length]
  93. left = arrangement[3*side_length:]
  94. while len(left) < len(right):
  95. left.append("")
  96. while len(right) < len(left):
  97. right.append("")
  98. table_line_length = longest_name_len + 1
  99. print("\n")
  100. top_row = ""
  101. top_row += (longest_name_len + 1) * " "
  102. for top_guest in top:
  103. top_row += top_guest + " "
  104. table_line_length += len(top_guest) + 1
  105. print(top_row)
  106. print((longest_name_len + 1) * " " + table_line_length * "-")
  107. first_element = True
  108. for left_guest, right_guest in zip(reversed(left), right):
  109. row = ""
  110. if not first_element:
  111. row += longest_name_len * " "
  112. row += "|" + ">"* (table_line_length) + "|"
  113. print(row)
  114. row = ""
  115. else:
  116. first_element = False
  117. row += left_guest.rjust(longest_name_len) + "|" + "<"* (table_line_length) + "|" + right_guest
  118. print(row)
  119. print((longest_name_len + 1) * " " + table_line_length * "-")
  120. bottom_row = ""
  121. bottom_row += (longest_name_len + 1) * " "
  122. for bottom_guest in reversed(bottom):
  123. bottom_row += bottom_guest + " "
  124. print(bottom_row)
  125. print("\n")
  126. if(pretty_print):
  127. print_table()
  128. print("Seating plan:")
  129. print(arrangement)