I want to check if, for example, the digit '2' is in 4059304593.
My aim is to then check if there are any of the digits 1-9 not in my integer. This is what I have tried:
for i in xrange(10):
for j in xrange(100):
num = str(i^j)
one_count = 0
two_count = 0
for k in xrange(len(num)):
if num[k] == 1:
one_count += 1
if num[k] == 2:
two_count += 1
Then my "counts" would go all the way down to nine_count, and if any of the counts are 0, then that digit isn't in 'num'. From what I've read on these sites, my script would be inefficient - can someone point out a better way?
This "digit" thing calls for a string approach, not a numeric one (reminds me of some Project Euler puzzles).
I'd create a set out of the digits of your number first (removing duplicates at the same time)
s = set(str(4059304593))
then to check for a digit:
print('2' in s)
(note that in for a set is performant)
then, to check whether s contains all the 013456789 digits:
print(s.issuperset("013456789"))
(if this must be done multiple times, it may be worth to create a set with the string, issuperset will work faster)
You could convert your number to a string, then to a set to get the unique digits.
You just have to iterate over digits in 0-9 to find the ones not present in your original number :
>>> set(map(int,str(4059304593)))
set([0, 9, 3, 4, 5])
>>> digits = _
>>> [i for i in range(10) if i not in digits]
[1, 2, 6, 7, 8]
L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
j = 0
nL = [0, 0, 0, 0, 0, 0, 0, 0, 0]
n = 1004 #number
while n:
i = n%10
nL[i] = 1
n //= 10
OUT
nL = [1, 1, 0, 0, 1, 0, 0, 0, 0, 0]
Explanation:
if nL[i] is 1, then the i-th digit is in n
Since you just want to find out which digits aren't in your number:
def not_in_number(n):
return {*range(10)} - {*map(int, {*str(n)})}
Usage:
>>> not_in_number(4059304593)
{1, 2, 6, 7, 8}
This takes the set of digits ({*range(10)}) and substracts from it the set of digits of your number ({*map(int, {*str(n)})}), created by mapping the set of digit characters to integers. If you find the {*...} notation confusing, you can always use set(...) instead, which will also work for Python 2.7+:
def not_in_number(n):
return set(range(10)) - set(map(int, set(str(n))))
Another way is using - with sets:
set('0123456789') - set(str(4059304593))
Result are all digits that aren't in your integer:
{'2', '7', '1', '6', '8'}
Related
Code:
n = int(input("Type n: "))
def some_function(n):
numbers, numbers_sum = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], 45
while True:
digit = n % 10
n //= 10
if digit in numbers:
numbers.remove(digit)
numbers_sum -= digit
else:
break
return numbers_sum
print(some_function(n))
Program needs to print the sum of numbers that are not found in the input.
I covered the scenario when numbers are not repeating and for this scenario if the input is 234567890 output is 1 .
But don't have an idea for scenario when numbers are repeating.Etc. if the input is 22334567890 or 223344556677889900 output still needs to be 1 but it's not.
P.S.
I can't do it with strings.
I know 0 doesn't make difference because we are doing with - and +.
the easier way to do it is to transform it to a string and do set operations
>>> n=22334567890
>>> numbers=set("123456789")
>>> numbers-set(str(n))
{'1'}
>>>
and then transform back to integers
>>> sum(map(int,{'1'}))
1
>>>
if you don't want the string conversion, just make a function that give you the digits of the numbers and do the same
>>> def digits(n): #this is a generator function
if n==0:
yield 0
while n:
n,d = divmod(n,10)
yield d
>>> n=22334567890
>>> numbers=set(range(10))
>>> numbers
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
>>> list(digits(n))
[0, 9, 8, 7, 6, 5, 4, 3, 3, 2, 2]
>>>
>>> numbers - set(digits(n))
{1}
>>> sum({1})
1
>>>
I solved it.Code:
n, finish = int(input("Type n: ")), 0
dig_list, num_list = [], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def sum(n):
while n > 0:
digit = n % 10
n //= 10
dig_list.append(digit)
for i in range (0, 11):
if i in dig_list:
num_list.remove(i)
return num_list
for e in (sum(n)):
finish += e
print(finish)
Purpose of code.
Explanation:
First, we create 2 lists.
The first one(dig_list) has no elements and there we are gonna put all digits of input(n).
The second list is a list of numbers from 0 to 9(num_list).
Then we put all digits of n in the first list.Then using for loop we go through the first list.If numbers from 0 to 9 are found in the first list we remove them from the second list.
In the end, we save the sum(+) of the remaining elements of the second list to a variable sum.
What I am trying to do is to find out how many sequences of '1' are in a list read from the user input. For example, if my list looks like:
mylist = [0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1]
, then I want to print '3', because I have 3 sequences of 1.
So far I have tried to find the indexes of '0' and see if those indexes are consecutive(which means is a sequence of 1 between my 2 zero's, but with no success.
You can use itertools.groupby in a generator expression for sum:
from itertools import groupby
sum(1 for k, _ in groupby(mylist) if k)
This returns: 3
If you know your list is just going to be made up of ones and zeroes, then you can join everything together as a string, split the string on every occurrence of '0', and then count up all of the strings of 1s (which will be any part that's not empty).
>>> mylist = [0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1]
>>> chunks_o_ones = [i for i in ''.join([str(i) for i in mylist]).split('0') if len(i) > 0]
>>> print(len(chunks_o_ones))
3
You could alternatively take the string and use a regular expression to find the '1' blocks:
>>> import re
>>> p = re.compile('1+')
>>> print(len(p.findall(''.join([str(i) for i in mylist]))))
3
You can apply diff to your list, which would be essentially
diff_list = []
for i in range(len(list)-1):
diff_list[i] = list[i+1]-list[i]
this will give you a 1 if there is a change from 0 to 1, 0 if there was no change or -1 if there is a change from 1 to 0. Then, you can use
nones = diff_list.count(1)
To count the number of times the transition from 0 to 1 took place. Although it wouldn't count the first sequence of ones, if the first element of your list is one so you can adjust it doing:
if list[0] == 1:
nones += 1
Subtract every element of an array from the subsequent element. Whenever there will be a change from 0 -> 1, this difference will be 1. When ever we have a difference as 1, it means a new 1s pattern has started. In the end just add them up.
mylist = [0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1]
sum([ 1 if (mylist[i+1] - mylist[i])==1 else 0 for i in range(len(mylist)-1)]+[1 if mylist[0]==1 else 0])
3
I need to implement Sieve of Eratosthenes algorithm.
I have list:
bar = [2, 3, 4, 5, 6, 7, 8, 9, 10]
I need to replace each odd element with "0".
Now I have code:
while viewIndex < maxNumber:
bar[viewIndex] = 0
viewIndex += 2
But I remember about slices. And for me it will be nice to write something like this:
bar[currentIndex::2] = 0
But I have error:
TypeError: must assign iterable to extended slice
Maybe you know a beautiful solution to this task.
You should assign the slice to an iterable of the same length as the number of odds:
bar[1::2] = [0]*(len(bar)//2)
print(bar)
# [2, 0, 4, 0, 6, 0, 8, 0, 10]
To extend this for even indices, you need to take into consideration lists with odd-lengths (not relevant for the above case) by adding the modulo 2 value of the list length:
bar[::2] = [0]*(len(bar)//2 + len(bar)%2)
Which is same as:
bar[::2] = [0]*sum(divmod(len(bar), 2))
I use numpy:
foo = np.ones(10)
foo[1::2] = 2
This just works.
You shouldn't have to keep track of indices -- the point of slicing is to make things more convenient, not to force you to keep track of which day of the week relative to the third Tuesday of last month you bought bread.
Use simple for loop
bar = [2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in range(len(bar)):
if bar[i] % 2 != 0:
bar[i] = 0
print(bar)
Output
[2, 0, 4, 0, 6, 0, 8, 0, 10]
You can use map to set elements on odd index to zero,
bar = [2, 3, 4, 5, 6, 7, 8, 9, 10]
print map(lambda i: 0 if bar.index(i)%2!=0 else i, bar)
[2, 0, 4, 0, 6, 0, 8, 0, 10]
or if you want to set odd element value to zero, you can do this,
map(lambda i: 0 if i%2!=0 else i, bar)
Thank to all for answers. My implementation of Sieve of Eatosthenes algorithm:
def resheto(data):
print("\tStart Resheto")
currentIndex = 0
while currentIndex < len(data) - 1:
data[currentIndex + data[currentIndex]::data[currentIndex]] = \
[0] * ((len(data) + 1) // data[currentIndex] - 1)
currentIndex += 1
while currentIndex < len(data) - 1 and data[currentIndex] == 0:
currentIndex += 1
if currentIndex >= len(data) - 1:
break
print("\tEnd Resheto") return data
How can I shift and merge elements of a matrix to have the following result ?
Move right:
[[0,0,2,2,0,2],[8,4,2,2,0,2]] ==> [[0,0,0,0,4,2],[0,0,8,4,4,2]]
or
Move left:
[[0,0,2,2,0,2],[8,4,2,2,0,2]] ==> [[4,2,0,0,0,0],[8,4,4,2,0,0]]
It's like the 2048 game. For example, when the user do a left move, every numbers go to the left of the list and if 2 numbers side-by-side are equals, tere is an addition of the two numbers.
I would like to do it with loops.
I tried with some codes that I have found on the internet but as a begineer, I didn't found a straightforward code to understand how to do this.
Thanks in advance for the help.
If I don't misunderstand your meaning,I write some code,hope this helps:
a = [[0, 0, 2, 2, 0, 2], [8, 4, 2, 2, 0, 2]]
f = lambda x: [2 * x[0]] if x[0] == x[1] else x
def move_left(l):
c, l = [], l + [0] if len(l) % 2 else l
for i in range(0, len(l), 2):
c = c + f(l[i:i + 2])
c = list(filter(lambda x: x != 0, c))
return c + ([0] * (len(l) - len(c)))
def move_right(l):
c, l = [], l + [0] if len(l) % 2 else l
for i in range(len(l), 0, -2):
c = f(l[i - 2:i]) + c
c = list(filter(lambda x: x != 0, c))
return ([0] * (len(l) - len(c))) + c
for i in a:
print(move_left(i))
Output:
[4, 2, 0, 0, 0, 0]
[8, 4, 4, 2, 0, 0]
It seems that you're using Python3.x,so you should use list(filter(lambda x: x != 0, c)) to get the list.
Here is an example for moving the elements to the right:
def move_right(matrix):
for row in matrix:
for i, number in reversed(list(enumerate(row))):
if number == row[i-1]:
row[i] = number + row[i-1]
row[i-1] = 0
row.sort(key=lambda v: v != 0)
return matrix
Then doing:
matrix = [[0,0,2,2,0,2],[8,4,2,2,0,2]]
print(move_right(matrix))
Outputs:
[[0, 0, 0, 0, 4, 2], [0, 0, 8, 4, 4, 2]]
How it works:
First we loop through the matrix. During the first iteration: row = [0, 0, 2, 2, 0, 2]
Then we check loop over the numbers in that row using the enumerate() function. We then apply reversed() to go traverse the list backwards as to not combine a previous sum with another element in a single turn.
e.g: [4,4,8] => [0, 8, 8] => [0, 0, 16]. This should actually equal [0, 0, 8]
For the current row, this will output a result as so:
i number
5 2
4 0
3 2
2 2
1 0
0 0
Then we use the index (i) to refer to the previous number in the list. e.g. At index 2. The current number is 2, and the previous number (i-1) was 2. Since these are equal the code within the 'if' statement will execute.
The current element will then be assigned to the sum of itself and the previous element. row[i] = number + row[i-1]
The previous number will become 0, at it merged with the current number. row[i-1] = 0
Once we have looped over every number, the row will be: [0, 0, 0, 4, 0, 2]. The code row.sort(key=lambda v: v != 0) will then sort so that the zeroes are pushed to the left. See here for more details.
When moving elements to the left instead of the right, this would need to be changed to row.sort(key=lambda v: v != 0, reverse=True) to push the zeros in the other direction.
I have a personal project in which I want to find out the pattern found in certain Pisano sequence. Each sequence (ex Pisano(3): 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, ...) has a repeating pattern that I want to extract. In this example, the pattern would be (0, 1, 1, 2, 0, 2, 2, 1).
So far I've worked on an algorithm that works alright except when the first number of the sequence is found inside the pattern.
def hasPattern(seq):
pBuffer = []
predict = ''
i = 0
check = True
iSeq = 0
passThrough = 0
while (check == True) and passThrough <10:
val = seq[iSeq]
if predict == val: #how to resolve the duplicates pattern values? (1, 1, 3, 1, 1, 3)
if iSeq == len(seq)-1:
check = False
if i < len(pBuffer)-1:
i += 1
else:
i = 0
else:
i = 0
iSeq = -1
passThrough += 1
pBuffer.append(val)
predict = pBuffer[i]
iSeq += 1
if iSeq == len(seq)-1:
check = False
return {'pattern': pBuffer, 'size': len(pBuffer)}
My question is: how should i approach building an algorithm for checking a repetitive pattern in any sequence of numbers (not only Pisano sequences)?
p = [0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1, 0, 1, 1, 2, 0, 2, 2, 1]
for b in range(2, len(p)/2):
iterar = True
for i in range(0,lp-b, b):
if p[i:i+b]!=p[i+b:i+b+b]:
iterar = False
break
if iterar:
print "Solution %s: %s" %(b, p[:b])
break
You can just search for the second occurrance of a 0 followed by a 1 in the sequence:
def findPattern(seq):
for i in range(2, len(seq)-1):
if seq[i] == 0 and seq[i+1] == 1:
return {'pattern': seq[:i], 'size': i}
return {'pattern': [], 'size': -1} # not found
This works for Pisano series because mod(a+b,n) = mod(mod(a,n)+mod(b,n),n), which means that you can compute each number in the Pisano series by adding to two previous numbers together and then finding the modulo n, without having to compute the numbers in the Fibonacci series modulo n. This means that once the original two numbers (0 and 1) repeat then the sequence repeats. Also, for any two numbers in the series there can only be one possible previous number, so you won't get sequences like ABCDEFGEFGEFG etc