Hello. It is 0kayu806059. This article is Qiita's first post. As the title says, this time I made a verbal arithmetic solver. It's a very simple web app, but I'd like to keep track of how it was completed.
Verbal arithmetic is a puzzle in which you are given a formula in which some (or all) of the numbers are replaced with alphabets, so you can find the numbers that apply to each alphabet and make the formula hold. For example ABC + BAC = CACA Is given the formula. In this case, it's like thinking about what numbers A, B, and C will contain. It's the one you see when you take the junior high school exam. By the way, the answer is A = 2, B = 9, C = 1. When I actually substitute the number, We get 291 + 921 = 1212, which shows that it certainly holds. There are three basic rules.
I usually do competitive programming. While studying programming to raise the rate, let's make something! I thought that was the trigger. When I was thinking about what to make, the algorithm book I was reading at that time said that I could make worm-eaten arithmetic (all the alphabets of masked arithmetic replaced with □) with DFS. After reading it, I thought, "I understand how to make an worm-eaten calculation. Can I make a masked calculation?", So I made it.
There are two places where I had a hard time. This is the algorithm of the Verbal Arithmetic Solver and the output method of the answer when making a Web application.
def solver(s):
s = s.replace(" ", "")
left_terms = []
now = 0
alphabet = []
equal = 0
right_term = ""
operation = ['+', '-', 'x', '/']
ope_num = [0]
ZeroNine = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
#List the terms and characters that appear in the expression
for i in range(len(s)):
if s[i] not in alphabet and s[i] not in operation and s[i] != '=' and s[i] not in ZeroNine:
alphabet.append(s[i])
if s[i] in operation:
tmp = s[now:i]
left_terms.append(tmp)
now = i + 1
if s[i] == '+':
ope_num.append(0)
elif s[i] == '-':
ope_num.append(1)
elif s[i] == 'x':
ope_num.append(2)
else:
ope_num.append(3)
if s[i] == '=':
equal = i
left_terms.append(s[now:equal])
right_term = s[equal+1:]
#Sort the characters that appear
alphabet = sorted(alphabet)
number = len(alphabet)
#Search all the answer candidates from 0 to 9
for i in itertools.permutations(ZeroNine, number):
cur = list(i)
answer = {}
#Make a correspondence table for each character
for j in range(number):
answer[alphabet[j]] = cur[j]
#Create a formula based on the correspondence table
ok = 1
#Calculation of the left side
Leftside, Rightside = 0, 0
for j in range(len(left_terms)):
#Restore formula
tmp = ""
for k in left_terms[j]:
if k in ZeroNine:
tmp += k
else:
tmp += answer[k]
if tmp[0] == '0':
ok = 0
else:
if ope_num[j] == 0:
Leftside += int(tmp)
elif ope_num[j] == 1:
Leftside -= int(tmp)
elif ope_num[j] == 2:
Leftside *= int(tmp)
else:
Leftside /= int(tmp)
#Calculation of the right side
tmp = ""
for k in right_term:
if k in ZeroNine:
tmp += k
else:
tmp += answer[k]
if tmp[0] == '0':
ok = 0
Rightside += int(tmp)
#At ok, we are checking if the condition that the highest rank does not come out is satisfied
if ok == 1:
if Leftside == Rightside:
res = ""
for key in answer:
res += str(key)
res += ": "
res += str(answer[key])
res += " "
return res
return "No answer found"
When you actually move it, it looks like this. Here, as input, the first example given is included. In fact, this Verbal arithmetic solver has its drawbacks. Expressions in parentheses cannot be calculated as they are. All you have to do is remove the parentheses, but it may be rather troublesome from the input side. Until now, when it came to web applications, I had no choice but to copy books or imitate videos, and I had never thought about it myself, so it was a very good experience. Thank you for reading.
Recommended Posts