def find_solution(self): equation_selected = self.combo.currentText() input_oper,__,input_digits = cm.parse_eq(equation_selected) self.load_pics(input_oper,input_digits,1) input_match_cnt, input_eq_str, input_oper_det = cm.matching(input_oper, input_digits) self.solution_stack = [] for equation in self.equations: oper,__,digits = cm.parse_eq(equation) match_cnt, eq_str, oper_det = cm.matching(oper,digits) if (match_cnt == input_match_cnt): hardship = cm.hardship(input_eq_str, eq_str, input_oper_det, oper_det) self.solution_stack.append((oper,digits,hardship)) self.prompt_1 = QLabel('难度系数') self.grid.addWidget(self.prompt_1, 0, 6) self.display = QLabel() self.grid.addWidget(self.display, 0, 7) self.prompt_2 = QLabel('剩余答案数') self.grid.addWidget(self.prompt_2, 0, 8) self.countdown = QLabel() self.grid.addWidget(self.countdown, 0, 9) self.display_button = QPushButton('显示结果', self) self.display_button.clicked.connect(self.display_result) self.display_button.resize(self.display_button.sizeHint()) self.grid.addWidget(self.display_button, 0, 4) self.next_button = QPushButton('清除', self) self.next_button.clicked.connect(self.next_result) self.next_button.resize(self.next_button.sizeHint()) self.grid.addWidget(self.next_button, 0, 5)
def compute_2(self): if (self.send_from_2.text() == '从题库加载'): equation_selected = self.combo.currentText() elif (self.send_from_2.text() == '输入算式'): equation_selected = self.line.text() elif(self.send_from_2.text() == '随机生成'): equation_selected = cm.question_generator() ori_oper,__,ori_digits = cm.parse_eq(equation_selected) self.load_pics(ori_oper,ori_digits,1) found, solution, oper, isreversed = matches2.move_oper_2(equation_selected) if (found == True): self.load_pics(oper,solution,3,isreversed) else: found, solution, oper, isreversed = matches2.move_digit_2(equation_selected) if (found == True): self.load_pics(oper,solution,3,isreversed) else: QMessageBox.information(self, "无解信息", "该算式不能通过移动两根火柴变成等式!", QMessageBox.Ok) self.clear_button = QPushButton('清空', self) self.clear_button.clicked.connect(self.clear_result) self.clear_button.resize(self.clear_button.sizeHint()) self.grid.addWidget(self.clear_button, 0, 4)
def move_oper_1(equation): oper, nums, digits = cm.parse_eq(equation) #change - to +, so a match should be removed from digits (minus1) if (oper == '-'): if (int(nums[1]) - int(nums[2]) == int(nums[0])): final_solution = digits[:] return True, final_solution, '-', True else: for i in range(6): new_eqs = [] ans = digits[:] candidates = cm.minus.get(digits[i]) for new_digit in candidates: if (new_digit in cm.str_to_num.keys()): ans[i] = new_digit new_eqs.append(list(ans)) hasfound, solution = cm.check_correct(equation, new_eqs, '+') if (hasfound == True): final_solution = solution return True, final_solution, '+', False #change + to -, so a match should be added to digits (plus1) elif (oper == '+'): for i in range(6): new_eqs = [] ans = digits[:] candidates = cm.plus.get(digits[i]) for new_digit in candidates: if (new_digit in cm.str_to_num.keys()): ans[i] = new_digit new_eqs.append(list(ans)) hasfound, solution = cm.check_correct(equation, new_eqs, '-') if (hasfound == True): final_solution = solution return True, final_solution, '-', False return False, [], '', False
def move_digit_1(equation, new_oper=None, new_digits=None): oper, __, digits = cm.parse_eq(equation) # check for call from move_oper_2 if (new_oper != None): oper = new_oper if (new_digits != None): digits = new_digits[:] for i in range(6): new_eqs = [] ans = digits[:] # change the pos of match within the same digit (same1) candidates_1 = cm.same.get(ans[i]) for new_digit_1 in candidates_1: ans[i] = new_digit_1 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): final_solution = solution return True, final_solution, oper, False new_eqs = [] ans = digits[:] # remove a match from one digit and added to a following digit (minus1-plus1) candidates_1 = cm.minus.get(ans[i]) for new_digit_1 in candidates_1: ans[i] = new_digit_1 for j in range(i + 1, 6): candidates_2 = cm.plus.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans[j] = digits[j] hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): final_solution = solution return True, final_solution, oper, False new_eqs = [] ans = digits[:] # add a match removed from a following digit to the previous digit (plus1-minus1) candidates_1 = cm.plus.get(ans[i]) for new_digit_1 in candidates_1: ans[i] = new_digit_1 for j in range(i + 1, 6): candidates_2 = cm.minus.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans[j] = digits[j] hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): final_solution = solution return True, final_solution, oper, False return False, [], '', False
def move_oper_2(equation): oper, nums, digits = cm.parse_eq(equation) new_eqs = [] ans = digits[:] # 1. 移位问题 if (digits[0] == '0000000') and (digits[2] == '0000000') and (digits[4] != '0000000'): if (oper == '+') or (oper == '*'): ans = [ '0000000', digits[4], '0000000', digits[5], digits[1], digits[3] ] new_eqs.append(list(ans)) else: #移动‘=’ ans = [ '0000000', digits[1], digits[3], digits[4], '0000000', digits[5] ] new_eqs.append(list(ans)) elif (digits[0] == '0000000') and (digits[2] != '0000000'): if (oper == '=') and (digits[4] == '0000000'): #移动‘=’ ans = [ '0000000', digits[1], '0000000', digits[2], digits[3], digits[5] ] new_eqs.append(list(ans)) else: ans = [ digits[1], digits[2], '0000000', digits[3], digits[4], digits[5] ] new_eqs.append(list(ans)) elif (digits[0] != '0000000') and (digits[2] == '0000000') and (digits[4] != '0000000'): if (oper == '+') or (oper == '*'): ans = [ '0000000', digits[0], digits[1], digits[3], digits[4], digits[5] ] new_eqs.append(list(ans)) else: #移动‘=’ ans = [ digits[0], digits[1], digits[3], digits[4], '0000000', digits[5] ] new_eqs.append(list(ans)) elif (oper == '=') and (digits[0] != '0000000') and ( digits[2] != '0000000') and (digits[4] == '0000000'): ans = [ digits[0], digits[1], '0000000', digits[2], digits[3], digits[5] ] new_eqs.append(list(ans)) hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): if (digits[0] == '0000000') and (digits[2] == '0000000') and (digits[4] != '0000000'): if (oper == '+') or (oper == '*'): final_solution = [ solution[4], solution[5], solution[0], solution[1], solution[2], solution[3] ] return True, final_solution, oper, True else: final_solution = solution return True, final_solution, oper, False #2. 变符号问题 #2.1 if (oper == '-'): # 2.1.1 ’-‘ 变成 ‘+’: minus1 + search1 for i in range(6): new_eqs = [] ans = digits[:] solution = [] candidates = cm.minus.get(ans[i]) for new_digit in candidates: ans[i] = new_digit new_eqs.append(list(ans)) for new_digits in new_eqs: hasfound, solution, __, __ = matches1.move_digit_1( equation, '+', new_digits) if (hasfound == True): final_solution = solution return True, final_solution, '+', False # 2.1.2 ’-‘ 变成 ‘*’: minus1 for i in range(6): new_eqs = [] ans = digits[:] solution = [] candidates = cm.minus.get(ans[i]) for new_digit in candidates: ans[i] = new_digit if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) hasfound, solution = cm.check_correct(equation, new_eqs, '*') if (hasfound == True): final_solution = solution return True, final_solution, '*', False # 2.1.3 ’-‘ 变成 ‘=’: # 2.1.3.1 互换 + search_digit_1 solution = [] new_digits = [ digits[2], digits[3], digits[4], digits[5], digits[0], digits[1] ] hasfound, solution, __, __ = matches1.move_digit_1( equation, '-', new_digits) if (hasfound == True): final_solution = [ solution[4], solution[5], solution[0], solution[1], solution[2], solution[3] ] return True, final_solution, '-', True # 2.1.3.2 minus1, check A=B+C for i in range(6): ans = digits[:] new_eqs = [] solution = [] candidates = cm.minus.get(ans[i]) for new_digit in candidates: ans[i] = new_digit if set(ans).issubset(set(cm.str_to_num.keys())): new_ans = [ans[2], ans[3], ans[4], ans[5], ans[0], ans[1]] new_eqs.append(list(new_ans)) hasfound, solution = cm.check_correct(equation, new_eqs, '+') if (hasfound == True): final_solution = [ solution[4], solution[5], solution[0], solution[1], solution[2], solution[3] ] return True, final_solution, '+', True # 2.1.3.3 minus1(-to=) + plus1(=to-) for i in range(6): ans = digits[:] new_eqs = [] ans_stack = [] solution = [] candidates_1 = cm.minus.get(ans[i]) for new_digit_1 in candidates_1: ans[i] = new_digit_1 ans_stack.append(list(ans)) for j in range(6): candidates_2 = cm.plus.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() hasfound, solution = cm.check_correct(equation, new_eqs, '-') if (hasfound == True): final_solution = [ solution[4], solution[5], solution[0], solution[1], solution[2], solution[3] ] return True, final_solution, '-', True # 2.1.3.4 (=to-)plus1-(-to=)minus1 for i in range(6): ans = digits[:] new_eqs = [] ans_stack = [] solution = [] candidates_1 = cm.plus.get(ans[i]) for new_digit_1 in candidates_1: ans[i] = new_digit_1 ans_stack.append(list(ans)) for j in range(6): candidates_2 = cm.minus.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() hasfound, solution = cm.check_correct(equation, new_eqs, '-') if (hasfound == True): final_solution = [ solution[4], solution[5], solution[0], solution[1], solution[2], solution[3] ] return True, final_solution, '-', True #2.2 if (oper == '+'): # 2.2.1 ’+‘ 变成 ‘-’: plus1 + search1 for i in range(6): ans = digits[:] new_eqs = [] solution = [] candidates = cm.plus.get(ans[i]) for new_digit in candidates: ans[i] = new_digit new_eqs.append(list(ans)) for new_digits in new_eqs: hasfound, solution, __, __ = matches1.move_digit_1( equation, '-', new_digits) if (hasfound == True): final_solution = solution return True, final_solution, '-', False # 2.2.2 ’+‘ 变成 ‘*’: if (int(nums[0]) * int(nums[1]) == int(nums[2])): final_solution = digits[:] return True, final_solution, '*', False # 2.2.3 ’+‘ 变成 ‘=’ # 2.2.3.1 互换 if (int(nums[1]) + int(nums[2]) == int(nums[0])): final_solution = digits[:] return True, final_solution, '+', True # 2.2.3.2 plus1, check A=B-C for i in range(6): ans = digits[:] new_eqs = [] solution = [] candidates = cm.plus.get(ans[i]) for new_digit in candidates: ans[i] = new_digit if set(ans).issubset(set(cm.str_to_num.keys())): new_ans = [ans[2], ans[3], ans[4], ans[5], ans[0], ans[1]] new_eqs.append(list(new_ans)) hasfound, solution = cm.check_correct(equation, new_eqs, '-') if (hasfound == True): final_solution = [ solution[4], solution[5], solution[0], solution[1], solution[2], solution[3] ] return True, final_solution, '-', True #2.3 if (oper == '*'): # 2.3.1 ’*‘ 变成 ‘-’: for i in range(6): ans = digits[:] new_eqs = [] ans_stack = [] solution = [] candidates = cm.plus.get(ans[i]) for new_digit in candidates: ans[i] = new_digit if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) hasfound, solution = cm.check_correct(equation, new_eqs, '-') if (hasfound == True): final_solution = solution return True, final_solution, '-', False # 2.3.2 ’*‘ 变成 ‘+’: if (int(nums[0]) + int(nums[1]) == int(nums[2])): final_solution = digits[:] return True, final_solution, '+', False return False, [], '', False
def move_digit_2(equation): oper, __, digits = cm.parse_eq(equation) for i in range(6): ans = digits[:] ans_stack = [] new_eqs = [] solution = [] candidates_1 = cm.same.get( ans[i]) # there's a change within same digit for new_digit_1 in candidates_1: ans[i] = new_digit_1 ans_stack.append(list(ans)) for j in range(i, 6): candidates_2 = cm.same.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append( list(ans) ) #another change occurs within same digit again (same1-same1) ans = (ans_stack[-1])[:] candidates_2 = cm.minus.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 ans_stack.append(list(ans)) for k in range(j + 1, 6): candidates_3 = cm.plus.get( ans[k] ) #another change is removing from former digit and add it to the latter (same1-minus1-plus1) for new_digit_3 in candidates_3: ans[k] = new_digit_3 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] candidates_2 = cm.plus.get(ans[j]) for new_digit_2 in candidates_2: ans[j] = new_digit_2 ans_stack.append(list(ans)) for k in range(j + 1, 6): candidates_3 = cm.minus.get( ans[k] ) #another change is removing from latter digit and add it to the former (same1-plus1-minus1) for new_digit_3 in candidates_3: ans[k] = new_digit_3 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] ans_stack.pop() hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): final_solution = solution return True, final_solution, oper, False ans = digits[:] ans_stack = [] new_eqs = [] solution = [] candidates_1 = cm.minus.get( ans[i]) # remove a match from the first digit for new_digit_1 in candidates_1: ans[i] = new_digit_1 ans_stack.append(list(ans)) for j in range(i + 1, 6): candidates_2 = cm.plus.get( ans[j]) # another following digit gets the match for new_digit_2 in candidates_2: ans[j] = new_digit_2 ans_stack.append(list(ans)) for k in range(i, 6): candidates_3 = cm.same.get( ans[k] ) # another change occurs within the same digit (minus1-plus1-same1) for new_digit_3 in candidates_3: ans[k] = new_digit_3 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] candidates_3 = cm.minus.get(ans[k]) for new_digit_3 in candidates_3: ans[k] = new_digit_3 ans_stack.append(list(ans)) for m in range(k + 1, 6): candidates_4 = cm.plus.get( ans[m] ) # another change is removing from former digit and add it to the latter (minus1-plus1-minus1-plus1) for new_digit_4 in candidates_4: ans[m] = new_digit_4 if set(ans).issubset( set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] candidates_3 = cm.plus.get(ans[k]) for new_digit_3 in candidates_3: ans[k] = new_digit_3 ans_stack.append(list(ans)) for m in range(k + 1, 6): candidates_4 = cm.minus.get( ans[m] ) #another change is removing from latter digit and add it to the former (minus1-plus1-plus1-minus1) for new_digit_4 in candidates_4: ans[m] = new_digit_4 if set(ans).issubset( set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] ans_stack.pop() hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): final_solution = solution return True, final_solution, oper, False ans = digits[:] ans_stack = [] new_eqs = [] solution = [] candidates_1 = cm.plus.get(ans[i]) # add a match to the first digit for new_digit_1 in candidates_1: ans[i] = new_digit_1 ans_stack.append(list(ans)) for j in range(i + 1, 6): candidates_2 = cm.minus.get( ans[j]) # another following digit loses the match for new_digit_2 in candidates_2: ans[j] = new_digit_2 ans_stack.append(list(ans)) for k in range(i, 6): candidates_3 = cm.same.get( ans[k] ) # another change occurs within the same digit (plus1-minus1-same1) for new_digit_3 in candidates_3: ans[k] = new_digit_3 if set(ans).issubset(set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] candidates_3 = cm.minus.get(ans[k]) for new_digit_3 in candidates_3: ans[k] = new_digit_3 ans_stack.append(list(ans)) for m in range(k + 1, 6): candidates_4 = cm.plus.get( ans[m] ) #another change is removing from former digit and add it to the latter (plus1-minus-minus1-plus1) for new_digit_4 in candidates_4: ans[m] = new_digit_4 if set(ans).issubset( set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] candidates_3 = cm.plus.get(ans[k]) for new_digit_3 in candidates_3: ans[k] = new_digit_3 ans_stack.append(list(ans)) for m in range(k + 1, 6): candidates_4 = cm.minus.get( ans[m] ) #another change is removing from latter digit and add it to the former (plus1-minus1-plus1-minus1) for new_digit_4 in candidates_4: ans[m] = new_digit_4 if set(ans).issubset( set(cm.str_to_num.keys())): new_eqs.append(list(ans)) ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] ans_stack.pop() ans = (ans_stack[-1])[:] ans_stack.pop() hasfound, solution = cm.check_correct(equation, new_eqs, oper) if (hasfound == True): final_solution = solution return True, final_solution, oper, False return False, [], '', False