So as part of a script I'm writing to play tic tac toe, I have a 'win checker' which takes as its input:
a list of numbers which denote positions
who started the game
It's not really important for the problem I'm having, but I thought some background might help. Here is the code:
import matplotlib.pyplot as plt
import math
import numpy as np
import random
import pdb
def win_checker(position_list, turn2):
win_list1 = []
win_list2 = []
for bud in xrange(len(position_list)):
if bud % 2 == 0:
win_list1.append(position_list[bud])
print win_list1
if 1 and 2 and 3 in win_list1:
return True
if 4 and 5 and 6 in win_list1:
return True
if 7 and 8 and 9 in win_list1:
return True
if 1 and 4 and 7 in win_list1:
return True
if 2 and 5 and 8 in win_list1:
return True
if 3 and 6 and 9 in win_list1:
return True
if 1 and 5 and 9 in win_list1:
return True
if 3 and 5 and 7 in win_list1:
return True
elif bud % 1 == 0:
win_list2.append(position_list[bud])
print win_list2
if 1 and 2 and 3 in win_list2:
return True
if 4 and 5 and 6 in win_list2:
return True
if 7 and 8 and 9 in win_list2:
return True
if 1 and 4 and 7 in win_list2:
return True
if 2 and 5 and 8 in win_list2:
return True
if 3 and 6 and 9 in win_list2:
return True
if 1 and 5 and 9 in win_list2:
return True
if 3 and 5 and 7 in win_list2:
return True
else:
return False
Then when I try the script for a certain position:
win_checker([5,1,3,2], 1)
[5]
[1]
[5, 3]
Out[57]: True
I don't understand why the output is True, if someone could explain what I'm missing that would be very helpful to me
Detail of the problem:
The and operator works on boolean values only. It does not distribute over the in operator (remember the distributive law of multiplication over addition?). Your expression
1 and 2 and 3 in win_list1
becomes
bool(1) and bool(2) and bool (3 in win_list1)
bool(n) is False for n=0, True for everything else.
Immediate fix:
Alex Hall already gave you that
Better fix (perhaps):
Renumber your array of choices to be a magic square:
6 7 2
1 5 9
8 3 4
Now, all you have to do is check whether you have a sum of 15 for any combination of three chosen positions. You can generate all of those with
itertools.combinations(win_list1, 3)
This would reduce your checking from 18 lines to 1 (or 2-4, if you prefer that readability).
Extra issue:
Your logic on bud is a little weird. I do understand the odd/even checking on the turn number:
if bud % 2 == 0:
However, the second one,
elif bud % 1 == 0:
is True for any integer. The percent sign is the modulus operator: divide by the mod and keep the remainder. In short, the second one is always true. Just make it an else.
Another ...
Why not make win_list a 2-D list? Use win_list[0] and win_list[1], so you can fold their code together. You can simply have
player = bud % 2
win_list[player].append(position_list[bud])
if any(sum(itertools.combinations(win_list[player], 3)) == 15):
...
if 1 and 5 and 9 in win_list2:
should be:
if 1 in win_list2 and 5 in win_list2 and 9 in win_list2:
In python
>> 1 and 2 and 3 in win_list1
is evaluated as
>> 3 in win_list1
which is True
Related
t= int(input())
while t>0:
n =int(input())
a =list(map(int,input().strip().split()))
if n==1:
print(a[0])
else:
c= []
c.append(a[n-1])
for i in range(n-1):
c.append(a[i])
for x in c:
print(x,end =" ")
t= t-1
# ERROR is : !!!Wrong Answer
Possibly your code doesn't work correctly for multiple test-cases (TCs).
The first test case where your code failed:
Input:
2
1 2
Its Correct output is:
2 1
And Your Code's output is:
2 1 3 1 2 4 1 2 3 7 1 8 7 5 6 7 8 3 9 8 7 6 4 2 1 17 ...
But this is not the output with this input . On compile and run the output is same as expected but now it is changing my output.
My dataframe looks like this:
s gamma_star
0 0.000000 0.6261
1 0.000523 0.6262
2 0.000722 0.6263
3 0.000861 0.6267
4 0.000972 0.6269
5 0.001061 0.6260
6 0.001147 0.6263
7 0.001218 0.6261
I have a value s = 0.000871, what I need to look for is the related gamma_star that belongs to this s. In the example above it would be s is between 3 0.000861 0.6261 and 4 0.000972 0.6261 then it's related gamma_star is 0.6267! I am a bit stuck and do not know how to sart, any idea? Thanks!
You could do:
df.loc[(df.s > s).idxmax()-1, 'gamma_star']
# 0.6267
Where the use condition will be indicating the starting point on which the condition is satisfied
(df.s > s)
0 False
1 False
2 False
3 False
4 True
5 True
6 True
7 True
Name: s, dtype: bool
and by taking the idxmax() we can find the beginning of the interval:
(df.s > s).idxmax()-1
# 3
You could do it with a loop, if you go through the s-values.
for i in range(len(s)-1):
if given_value > s[i] and given_value < s[i+1]:
gamma_s_wanted = gamma_star[i]
break
else:
gamma_s_wanted = gamma_star[-1]
def estDiviseur(i,n):
return n%i==0
def estPremier(n):
b=0
if n==1:
return False
for i in range(1 , n+1):
if estDiviseur(i,n)==True:
b=b+1
if b>2:
return False
else:
return True
def nbPremiers(n):
c=0
for i in range(0,n):
if estPremier(i)==True:
c=c+1
return c
problem is with nbPremiers, if n = 2 it returns to me 2 when it should be 0. the 2 first functions are right and they work exactly as i wanted to. last one is to count the numbers of primal numbers stricly less than n.
All those functions can be written as one-liners:
from math import sqrt
def is_divisor(i,n):
return n % i == 0
def is_prime(n):
return n >= 2 and not any(is_divisor(i, n) for i in range(2,int(sqrt(n)) + 1))
def primes_count(n):
return sum(1 for x in range(2,n+1) if is_prime(x))
print(primes_count(100))
# 25
Whichever country you're coming from, it's usually a good idea to write function names in English, especially if you're asking questions on an internation, english-speaking website.
Note that you only need to check divisors between 2 and sqrt(n).
A more efficient way would be to use the sieve of Erathostenes.
Finally, this prime-counting function is usually defined for primes lower than or equal to n.
You had several mistakes in your code; one of which was getting confused with i and n - using better names for parameters will help you.
Note that 0, and '1' are not primes.
def est_diviseur(diviseur, n):
return n % diviseur == 0
def est_premier(n):
b = 0
if n < 2:
return False
for diviseur in range(1, n+1):
if est_diviseur(diviseur, n) == True:
b = b + 1
if b > 2:
return False
else:
return True
def nb_de_premiers_inferieurs_a(nombre):
"""retourne le nombre de nombres premiers inferieurs a n
returns the number of primes whose value is lower than n
"""
compteur = 0
for n in range(nombre):
if est_premier(n):
compteur += 1
return compteur
for n in range(20):
print(n, est_premier(n), nb_de_premiers_inferieurs_a(n))
output:
0 False 0
1 False 0
2 True 0
3 True 1
4 False 2
5 True 2
6 False 3
7 True 3
8 False 4
9 False 4
10 False 4
11 True 4
12 False 5
13 True 5
14 False 6
15 False 6
16 False 6
17 True 6
18 False 7
19 True 7
I'm writing a program, and the goal is to take a list of numbers and return all the six-letter combinations for it using a recursive function (without importing a function to do it for me). Say, for example, my numbers are "1 2 3 4 5 6 7 8 9", output would be:
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 5 8
1 2 3 4 5 9
1 2 3 4 6 7
1 2 3 4 6 8
1 2 3 4 6 9
1 2 3 4 7 8
... etcetera, all the way down to
4 5 6 7 8 9
I'm not looking for code, persay, just a push in the right direction conceptually. What I've attempted thus far has failed and I've driven myself into a logical rut.
I've included the code I used before below, but it isn't really a recursive function and only seems to work for 6-8-digit values. It's very messy, and I'd be fine with scrapping it entirely:
# Function prints all the possible 6-number combinations for a group of numbers
def lotto(constantnumbers, variablenumbers):
# Base case: No more constant variables, or only 6 numbers to begin with
if len(constantnumbers) == 0 or len(variablenumbers) == 0:
if len(constantnumbers) == 0:
print(" ".join(variablenumbers[1:7]))
else:
print(" ".join(constantnumbers[0:6]))
i = 6 - len(constantnumbers)
outvars = variablenumbers[1:i + 1]
if len(variablenumbers) > len(outvars) + 1:
print(" ".join(constantnumbers + outvars))
for index in range(len(outvars), 0, -1):
outvars[index - 1] = variablenumbers[index + 1]
print(" ".join(constantnumbers + outvars))
else:
i = 6 - len(constantnumbers)
outvars = variablenumbers[1:i + 1]
print(" ".join(constantnumbers + outvars))
if len(variablenumbers) > len(outvars) + 1:
for index in range(len(outvars), 0, -1):
outvars[index - 1] = variablenumbers[index + 1]
print(" ".join(constantnumbers + outvars))
#Reiterates the function until there are no more constant numbers
lotto(constantnumbers[0:-1], constantnumbers[-1:] + variablenumbers)
import itertools
for combo in itertools.combinations(range(1,10), 6):
print(" ".join(str(c) for c in combo))
which gives
1 2 3 4 5 6
1 2 3 4 5 7
1 2 3 4 5 8
...
3 4 6 7 8 9
3 5 6 7 8 9
4 5 6 7 8 9
Edit: ok, here is a recursive definition:
def combinations(basis, howmany):
for index in range(0, len(basis) - howmany + 1):
if howmany == 1:
yield [basis[index]]
else:
this, remainder = basis[index], basis[index+1:]
for rest in combinations(remainder, howmany - 1):
yield [this] + rest
Edit2:
Base case: A 1-item combination is any basis item.
Induction: An N-item combination is any basis item plus an (N-1)-item combination from the remaining basis.
What is the value of i at the end of the loop body when a is 6?
def loopIdentification():
i=0
for a in range(2,8):
i=i+a-3
return i
5
>>> def loopIdentification():
i=0
for a in range(2,8):
i=i+a-3
print a, i
return i
>>> loopIdentification()
2 -1
3 -1
4 0
5 2
6 5
7 9
9