You are working hard to get married. The annual income you want from the other party is over 8 million yen. I would like to attend a speed dating party, but I don't think it makes sense to attend unless ** at least one of the participants ** has an annual income of 8 million yen or more. Given a list of participants and their annual income, do not answer whether it makes sense to attend.
Let's assume that the set of participants is $ M $ and the annual income is $ Y $ 10,000. The above condition uses logical symbols,
\exists M[Y\geq800]
Can be expressed as. $ \ exists $ means "there is". The point is ** "If even one person has an annual income of 8 million or more, it's OK immediately" **.
def main1(M):
for Y in M:
if Y >= 800:
return "Attendance"
return "Do not attend"
print(main1([800,900,1000,1100]))#Attendance
print(main1([500,600,700,800]))#Attendance
print(main1([400,500,600,700]))#Do not attend
You can look at the participants in order, and if you find a person of 8 million yen, you can stop the search there. It is the same no matter how many people there are after one.
You have become more and more bullish after having many experiences of speed dating. I have come to think that there is no point in attending unless all of the participants ** have an annual income of 8 million yen or more.
In this case,
\forall M[Y\geq800]
Can be expressed as. $ \ Forall $ means "about everything". However, if you try to implement this in the program as it is, it will be a little troublesome, so we will do a little logical conversion. The above proposition is
\lnot(\lnot \forall M[Y\geq800])
Is equivalent to. $ \ Lnot $ represents negation. For a two-choice question, ** "not'not A'" ** is equivalent to ** "is A" **. ** $ \ lnot $ can be moved to the right by swapping $ \ forall $ and $ \ exists $ **
\lnot(\lnot \forall M[Y\geq800])\\
\Leftrightarrow \lnot(\exists M\lnot[Y\geq800])\\
\Leftrightarrow \lnot(\exists M[Y<800])
The conversion is established. The point is ** "If even one person has an annual income of less than 800, he will be out immediately" **.
def main2(M):
for Y in M:
if Y < 800 :
return "Do not attend"
return "Attendance"
print(main2([800,900,1000,1100]))#Attendance
print(main2([500,600,700,800]))#Do not attend
print(main2([400,500,600,700]))#Do not attend
Judgment of attendance is also becoming strict.
You who attended the marriage party too much turned to the planning side before you knew it. We decided to arrange multiple groups to meet the needs of the attendees. However, you are not motivated, so I thought it would be nice if there was ** at least one ** group with ** at least one ** participant with an annual income of 8 million yen or more. At worst, only one person is enough! What an unmotivated planner! Attendees are not a collection.
Let the set of groups be $ G $
\exists G \exists M[Y\geq800]
It will be. This implementation is easy, and there is no change in saying that even one person should have an annual income of 8 million or more.
def main3(G):
for M in G:
for Y in M:
if Y >= 800:
return "Pass"
return "failure"
print(main3([[400,500,600,700],[500,600,700,800]]))#Pass
print(main3([[400,500,600,800],[500,600,700,800]]))#Pass
print(main3([[300,400,500,600],[800,900,1000,1100]]))#Pass
print(main3([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass
After receiving complaints about too much text, you decided to prepare a perfect lineup this time. ** All participants in all groups earn more than 8 million yen per year **.
\forall G \forall M[Y \geq 800]\\
\Leftrightarrow \lnot(\lnot \forall G \forall M[Y \geq 800])\\
\Leftrightarrow \lnot(\exists G \lnot(\forall M[Y \geq 800]))\\
\Leftrightarrow \lnot(\exists G \exists M[Y < 800])\\
If even one person has an annual income of less than 800, it will be out immediately. Implementation is just as easy.
def main4(G):
for M in G:
for Y in M:
if Y < 800:
return "failure"
return "Pass"
print(main4([[400,500,600,700],[500,600,700,800]]))#failure
print(main4([[400,500,600,800],[500,600,700,800]]))#failure
print(main4([[300,400,500,600],[800,900,1000,1100]]))#failure
print(main4([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass
The perfect lineup was well received, but it was too difficult to get people together and soon reached its limit. This time I thought about such a plan.
"There is at least one ** dream team ** in the group with all members earning more than 8 million a year."
\exists G \forall M[Y \geq 800]\\
\Leftrightarrow \exists G \lnot(\lnot \forall M[Y \geq 800])\\
\Leftrightarrow \exists G \lnot(\exists M[Y < 800])\\
It's difficult to implement this in one loop like it used to be, but it can be implemented simply by splitting the function.
def main5(M):
for Y in M:
if Y < 800:
return False
return True
def main6(G):
for M in G:
if main5(M):
return "Pass"
return "failure"
print(main6([[400,500,600,700],[500,600,700,800]]))#failure
print(main6([[400,500,600,800],[500,600,700,800]]))#failure
print(main6([[300,400,500,600],[800,900,1000,1100]]))#Pass
print(main6([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass
With this dream team plan, the attendees who were drawn by Baba started to complain as a matter of course. So you came up with the next plan.
"We guarantee that each team has at least one person with an annual income of 8 million or more."
\forall G \exists M[Y \geq 800]\\
\Leftrightarrow \lnot ( \lnot \forall G \exists M[Y \geq 800])\\
\Leftrightarrow \lnot (\exists G \lnot(\exists M[Y \geq 800]))\\
def main7(M):
for Y in M:
if Y >= 800:
return False
return True
def main8(G):
for M in G:
if main7(M):
return "failure"
return "Pass"
print(main8([[400,500,600,700],[500,600,700,800]]))#failure
print(main8([[400,500,600,800],[500,600,700,800]]))#Pass
print(main8([[300,400,500,600],[800,900,1000,1100]]))#failure
print(main8([[800,900,1000,1100],[900,1000,1100,1200]]))#Pass
With this, stable operation was finally possible. I'm happy.
If you want to complete the latter two cases in one function, you need to prepare a separate bool
variable for the flag.
\exists G \forall M[Y \geq 800]\\
\Leftrightarrow \exists G \lnot(\lnot \forall M[Y \geq 800])\\
\Leftrightarrow \exists G \lnot(\exists M[Y < 800])\\
def main9(G):
for M in G:
fail_at_least = 0
for Y in M:
if Y < 800:
fail_at_least = 1
if not fail_at_least:
return "Pass"
return "failure"
\forall G \exists M[Y \geq 800]\\
\Leftrightarrow \lnot ( \lnot \forall G \exists M[Y \geq 800])\\
\Leftrightarrow \lnot (\exists G \lnot ( \exists M[Y \geq 800]))\\
def main10(G):
for M in G:
success_at_least = 0
for Y in M:
if Y >= 800:
success_at_least = 1
if not success_at_least:
return "failure"
return "Pass"
Since the flag condition is easy to get confused, I personally try to give a variable name such as fail_at_least
(fail at least once) even if the name is long.
Recommended Posts