Replacing one number with another in PYTHON - python

I have declared a board array which is 10*10.I am reading the elements of the board which are 0, 1, and 2. After reading my board looks somewhat like this (shorter version 4*4)
0 1 0 2
2 1 0 1
0 2 1 0
1 2 1 0
Code:
board = []
for i in xrange(0, 10)
board.append(raw_input())
now i want to change all occurences of 0 to 1. I am not able to change it..what should i do..please write the modified code..(getting error as immutable)
Thanks for the answer it got changed.I should first covert the list to string then use replace function

As I understood, you have a list and just want to replace all 0's with 1's right? If it's like that, you can try to convert that list to string and use the replace method. Like: board = str(board) and then board = board.replace('0','1'). And then convert back to list with eval built-in function. But this may be too slow for big lists .
UPDATE >> If you do not want to use strings you can also code this:
If it is a 2d list like: L = [[1, 1, 0], [0, 2, 1], [0, 0, 0]] then:
for x in L:
for y in x:
if y == 0:
x[x.index(y)] = 1
And if it is just a common list like L = [1, 0, 2, 1, 0, 1] then:
for x in L:
if x == 0:
L[L.index(x)] = 1

for i in xrange(10):
for j in xrange(10):
if board[i][j] == 0:
board[i][j] = 1
This should works. If not, please show me how you create your board table.

Related

How can I increment list items one by one and stop as soon as the sum of the list items has reached a target value?

I have a list of integers, and I want to add 1 to each integer in the list with every iteration of a while loop. More specifically, I want to perform this operation on the list's integers one by one (left to right) instead of all at once, and stop the loop as soon as the its conditional becomes False, even if that means stopping before the end of the list.
First, I tried the following:
def myfunction(someinput):
myintegerlist = [0, 0, 0]
while sum(myintegerlist) < someinput:
myintegerlist[0:] = [x+1 for x in myintegerlist[0:]]
return myintegerlist, sum(myintegerlist)
This doesn't do what I want, because it simultaneously adds 1 to all integers in the list. Thus if someinput = 4, it returns 6 as the sum and [2, 2, 2] as the list, whereas I would like it to stop at [2, 1, 1] before exceeding the input number. So I tried
while sum(myintegerlist) < someinput:
myintegerlist[indexplace] = [x+1 for x in myintegerlist[indexplace]]
indexplace += 1
This was just a guess, and throws "TypeError: 'int' object is not iterable". But I am stuck on how to get through the list items one by one and add 1 to them. Is there a good way to move incrementally through the list with each iteration? Or should I be trying something completely different?
Keep track of the index where you need to add the 1 during the while loop:
def myfunction(someinput):
myintegerlist = [0, 0, 0]
increment_index = 0 # next place to add 1
while sum(myintegerlist) < someinput:
myintegerlist[increment_index % len(myintegerlist)] += 1 # add 1 to the element, modulo length of the list to keep the index in range
increment_index += 1
return myintegerlist, sum(myintegerlist)
print(myfunction(4))
Result:
([2, 1, 1], 4)
Normally, in order to iterate over the values in a list you would just use
for value in myintegerlist:
# ...
but this doesn't allow you to directly change the value in the list.
You have to create a loop over the indices of the list.
for i in range(len(myintegerlist)):
value = myintegerlist[i]
In particular, by assigning to myintegerlist[i] you can change the values in the list.
for i in range(len(myintegerlist)):
value = myintegerlist[i]
myintegerlist[i] = new_value
Now you need one additional step, because you don't just want to iterate over each list index once, but possibly many times, until a condition is met. In order to keep the iteration going, you can use the cycle function from the itertools module.
from itertools import cycle
for i in cycle(range(len(myintegerlist))):
# i = 0, 1, 2, 0, 1, 2, 0, 1, ...
Now you can just add 1 to the value at the current list index and break the loop if the sum of the values has reached the desired amount:
for i in cycle(range(len(myintegerlist))):
if sum(myintegerlist) >= someinput:
break
myintegerlist[i] += 1
It is bad idea to start every time from 0. Too much meaningless iterations if someinput is a large number.
def get_els(sum_value: int, num_of_els: int = 3) -> tuple:
_list = [int(sum_value / num_of_els)] * num_of_els
if sum(_list) == sum_value:
return _list, sum_value
while True:
for idx in range(0, num_of_els):
_list[idx] += 1
if sum(_list) == sum_value:
return _list, sum_value
print(get_els(2))
print(get_els(4))
print(get_els(5))
print(get_els(10))
print(get_els(20))
Output:
([1, 1, 0], 2)
([2, 1, 1], 4)
([2, 2, 1], 5)
([4, 3, 3], 10)
([7, 7, 6], 20)
More over, if length of list is only 3 elements then loop is not necessary at all:
def get_els(sum_value: int) -> tuple:
_list = [int(sum_value / 3)] * 3
if sum_value % 3 == 0:
return _list, sum_value
if sum_value % 3 > 1:
_list[0] += 1
_list[1] += 1
else:
_list[0] += 1
return _list, sum_value

How to combine the result of nested loop in Python

I need help to do the combination of nested loop output from two iteration.
This is my nested while code:
iteration=0
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
And this is the result:
List of bit: [1, 0, 1, 1, 0]
End of iteration 1
List of bit: [1, 0, 0, 1, 1]
End of iteration 2
However, I would like to combine the result of the loop. Supposedly, the result may produce something like this:
Combination of bit:[1, 0, 1, 1, 0 ,1 , 0, 0, 1, 1]
Hopefully someone may help me to do this.
Thank you so much.
This code should definitely be reorganized, but here is the solution.
from itertools import chain
# list for appending results
combined = []
iteration=0
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
# append the result
combined.append(numbers)
# print the combined list
print(list(chain.from_iterable(combined)))
Output
[1, 0, 1, 1, 0 ,1 , 0, 0, 1, 1]
Simply initialize numbers outside the loop, instead of clearing it for every iteration, so that your results can keep appending to numbers.
iteration=0
numbers = []
while (iteration < 2):
count = 0
bit=5
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
Given that the code simply creates a list of 10 random binary values, the code seems extremely complex. You could get the same effect with the following:
>>> import random
>>> [random.choice([0,1]) for _ in range(10)]
[0, 0, 0, 0, 1, 0, 1, 0, 1, 1]
However, as the code stands the list of values produced each iteration is thrown away at the start of the next iteration by the line numbers = [].
Either move this before the initial while statement, or create a separate list outside the while statement and append each iteration to it.
This latter approach (with minimal changes to your code) would look like this:
iteration=0
all_numbers = [] # List to hold complete set of results
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
all_numbers.extend(numbers) # Add the iteration to the complete list
print ('Complete list', all_numbers) # Show the aggregate result
your numbers variable is being re-initialized in the outer loop.
Other answers already pointed where your error was, but really that's WAY too much code for such a simple thing. The pythonic way is a much simpler and more readable one-liner:
numbers = [random.randint(0,1) for i in range(10)]

Take 2 dimensional list from user input

CODE SNIPPET
n = int(raw_input())
a = [[0]*n]*n
for i in xrange(0,n):
s = raw_input()
for j in xrange(0,n):
a[i][j] = int(s[j])
print a
I am new to python. While taking user input from stdin, I gave the following values in stdin
3
101
010
101
But when I print, the output comes as
[[1, 0, 1], [1, 0, 1], [1, 0, 1]]
Whereas the output should be
[[1, 0, 1], [0, 1, 0], [1, 0, 1]]
Can someone please guide me what am I missing?
I am using python 2.7.
First you define matrix with full range like
a = [[0 for i in range(n] for i in range(n)]
a[i][j] = any value
I hope it's work
Change a to this :
a = [[0 for i in range(n)] for j in range(n)]
Because [[0]*n]*n will create a single instance each time, so it will take the last assigned value to all instances because they are same referring to.They're all the same exact list in memory. When you use the [[0]*n]*n syntax, what you get is a list of n many [0] objects, but they're all references to the same object. They're not distinct instances, rather, just n references to the same instance.
Try the following code. Obviously you would need to add a lot of checks.
n_rows = int(raw_input('Enter Number of rows required: '))
n_cols = int(raw_input('Enter Number of cols required: '))
rows = []
for i in range(0, n_rows):
row = int()
final_list = []
for i in xrange(0, n_rows):
s = list(raw_input('Enter the values for row no. {} (Separated by commas): '.format(i+1)))
s_list = [int(i) for i in s if i != ',']
if len(s_list) != n_cols:
raise ValueError('Number of values entered are not correct')
else:
final_list.append(s_list)
print final_list
Or you can also try the Numpy Module
Here is the problematic line:
a = [[0]*n]*n
This, counterintuitively, creates only a single instance of [0, 0, 0] and makes three references to it. That means it is overwritten by your last input each time.
You can solve it by instead writing:
a = [[0 for _ in range(n)] for _ in range(n)]

How to recursively increment a binary number (in list form) without converting to integer?

For instance, given list [1, 0, 1] the code would return [1,1,0]. Other examples:
[1,1,1] -- > [1,0,0,0]
[1,0,0,1] --> [1,0,1,0]
I'm having most trouble understanding what my base case for recursion would be and then how to implement for the (n-1) case.
def increment_helper(number):
newNum = []
if len(number) ==1:
if number[0] == 1:
carry = 1
newNum.append(0)
else:
carry = 0
newNum.append(1)
else:
return increment_helper(number-1)
return newNum
So I'm sure that there are a lot of errors in here specifically how I am calling my recursion because I am not sure how to recurse on the list while storing the number that is removed somehow. The else return statement is obviously incorrect but I am using that as a placeholder. I am unsure of what condition to use as my base case for incrementation. I think I should be using a carry variable that keeps track of whether I am carrying a one over but other than that I am stuck on how to proceed.
Ah, ha! Okay, you have some idea of what you're doing. The basic outline is
Base case: how do I know when I'm done?
You're done when you run out of digits. number should be a list of individual digits; check its length to figure out when not to recur.
Recursion case: what next?
The general concept of recursion is "do something simple, reduce the problem by a small amount, and recur with the smaller problem." Your job in this part is to do the addition for one digit. If you need to keep going (is there a carry from that digit?), then recur. Otherwise, you have all the info you need to finish.
Specific application
Your recursion step will involve calling increment_helper with one digit less: not number - 1, but number[:-1].
After you return from each recursion, you'lll then want to append the digit you just finished. For instance, if you're incrementing 1101, your first call will see that the right-hand one, incremented, has a carry. The new digit is 0, and you have to recur. Hold onto the 0 for a moment, call yourself with 110, and get the result of that call. Append your saved 0 to that, and return to your main program.
Does that get you moving?
This one is "tricky" because you have two things going at each step:
what is the current number I'm looking at? (binary question 0/1)
should it be incremented? (do we have carry?) (binary question yes/no)
This leads to 4 cases.
There is the extra "case" of did we even get a list but it isn't that interesting.
So I would describe it as follows:
if not carry:
# technically meaningless so just return the entire list immediately
return list
# we have "carry", things will change
if not list:
# assumes [] == [0]
return [1]
if list[0]:
# step on `1` (make it 0 and carry)
return [0] + increment(rest_of_list)
# step on `0` (make it 1 and no more carry)
return [1] + rest_of_list
I strongly advise to change lists to tuples and work with these.
Also note that the recursion is on the reversed list, so apply as follows:
def increment_helper(lst, carry):
if not carry:
return lst
if not lst:
return [1]
if lst[0]:
return [0] + increment_helper(lst[1:], True)
return [1] + lst[1:]
def increment(lst):
# long but really just reverse input and output
return increment_helper(lst[::-1], True)[::-1]
I used some shortcuts by returning lists immediately (short-circuiting), but you can make it more "pure" by carrying on the recursion even without carry.
Another recursive approach.
Is the current input an empty list?
If yes return [1]
If no, continue
Is the sum (value) of the last element in the list and 1 greater than 1?
If so recursively call your function on the list without the last element (number_list[:-1]) and append [0] to the result.
If no, set the last element of the list to the sum.
Return the number_list
Code:
def increment_helper(number_list):
if not number_list:
return [1]
value = number_list[-1] + 1
if value > 1:
number_list = increment_helper(number_list[:-1]) + [0]
else:
number_list[-1] = value
return number_list
Example output:
numbers = [[1, 0, 1], [1,1,1], [1,0,0,1]]
for n in numbers:
print("%r ---> %r" % (n, increment_helper(n)))
#[1, 0, 1] ---> [1, 1, 0]
#[1, 1, 1] ---> [1, 0, 0, 0]
#[1, 0, 0, 1] ---> [1, 0, 1, 0]
Try this:
def add1(listNum):
if listNum.count(0):
oneArr = [[0] * (len(listNum) - 1)] + [1]
sumArr = []
for i in range(len(listNum)):
sumArr.append(sum(listNum[i], oneArr[i]))
newArr = []
for j in range(len(sumArr) - 1):
if sumArr[len(sumArr) - 1 - j] < 2:
newArr.insert(0, sumArr[len(sumArr) - 1 - j])
else:
newArr.insert(0, 1)
sumArr[len(sumArr) - 1 - j] += 1
return sumArr
else:
return [1] + [[0] * len(listNum)]
There aren't many reasons for using recursion for a program as simple as this, which is why I have chosen to provide a non-recursive solution.
In case it interests you, I've calculated the time complexity of this function and it is O(n).
It may be best to use two functions: one to check if a simple increment of the last position would suffice and another to perform the recursion should the previous attempt fail:
vals = [[1, 0, 1], [1,1,1], [1,0,0,1]]
def update_full(d):
if all(i in [1, 0] for i in d):
return d
start = [i for i, a in enumerate(d) if a > 1]
return update_full([1]+[0 if i > 1 else i for i in d] if not start[0] else [a+1 if i == start[0] -1 else 0 if i == start[0] else a for i, a in enumerate(d)])
def increment(d):
if not d[-1]:
return d[:-1]+[1]
return update_full(d[:-1]+[2])
print(list(map(increment, vals)))
Output:
[[1, 1, 0], [1, 0, 0, 0], [1, 0, 1, 0]]
You can treat the (binary) digits recursively by traversing the number from tail to head (just like addition works).
Before performing the recursion you have to check for two special cases:
No increment at the current digit is to be performed. Then just return the unmodified digits.
A single digit remains (you're at the head of the number). Then you possibly need to append the overflow to the head.
For the remaining cases you can increment the current digit and treat all digits before the current one in a recursive manner.
def bin_incr(n, incr=True):
if not incr:
return n
if len(n) == 1:
return [1, 0] if n[0] == 1 else [1]
return (
# `n[-1] == 1` denotes an overflow to the next digit.
bin_incr(n[:-1], n[-1] == 1)
+ [(n[-1] + 1) % 2]
)
I understand you don't want to use decimal addition, but if you must use big endian bit order, converting back to decimal first is probably the most practical. Otherwise, you end up with unnecessary reverse calls or awkward negative array indices
def binary (dec): # big endian bit order
if dec < 2:
return [ dec ]
else:
return binary (dec >> 1) + [ dec & 1 ]
def decimal (bin, acc = 0):
if not bin:
return acc
else:
return decimal (bin[1:], (acc << 1) + bin[0])
def increment (bin):
# sneaky cheat
return binary (decimal (bin) + 1)
for x in range (10):
print (x, binary (x), increment (binary (x)))
# 0 [0] [1]
# 1 [1] [1, 0]
# 2 [1, 0] [1, 1]
# 3 [1, 1] [1, 0, 0]
# 4 [1, 0, 0] [1, 0, 1]
# 5 [1, 0, 1] [1, 1, 0]
# 6 [1, 1, 0] [1, 1, 1]
# 7 [1, 1, 1] [1, 0, 0, 0]
# 8 [1, 0, 0, 0] [1, 0, 0, 1]
# 9 [1, 0, 0, 1] [1, 0, 1, 0]
If however you can represent your binary numbers in little endian bit order, things change. Instead of converting back to decimal, increment can be defined directly as a beautiful recursive function
def binary (dec): # little endian bit order
if dec < 2:
return [ dec ]
else:
return [ dec & 1 ] + binary (dec >> 1)
def increment (bin):
if not bin:
return [1]
elif bin[0] == 0:
return [1] + bin[1:]
else:
return [0] + increment(bin[1:])
for x in range (10):
print (x, binary (x), increment (binary (x)))
# 0 [0] [1]
# 1 [1] [0, 1]
# 2 [0, 1] [1, 1]
# 3 [1, 1] [0, 0, 1]
# 4 [0, 0, 1] [1, 0, 1]
# 5 [1, 0, 1] [0, 1, 1]
# 6 [0, 1, 1] [1, 1, 1]
# 7 [1, 1, 1] [0, 0, 0, 1]
# 8 [0, 0, 0, 1] [1, 0, 0, 1]
# 9 [1, 0, 0, 1] [0, 1, 0, 1]
Aside: converting the little endian representation back to decimal is a little different. I provide this to show that use cases for recursion exist everywhere
def decimal (bin, power = 0):
if not bin:
return 0
else:
return (bin[0] << power) + decimal (bin[1:], power + 1)
This part of the answer gives you cake and allows you to eat it too. You get big endian bit order and a recursive increment that steps through the bits in left-to-right order – You should use either implementation above for a number of reasons, but this aims to show you that even though your problem is complex, it's still possible to think about it recursively. No reverse or arr[::-1] was misused in the making of this function.
def binary (dec): # big endian bit order
if dec < 2:
return [ dec ]
else:
return binary (dec >> 1) + [ dec & 1 ]
def increment (bin, cont = lambda b, carry: [1] + b if carry else b):
if bin == [0]:
return cont ([1], 0)
elif bin == [1]:
return cont ([0], 1)
else:
n, *rest = bin
return increment (rest, lambda b, carry:
cont ([n ^ carry] + b, n & carry))
for x in range (10):
print (x, binary (x), increment (binary (x)))
# 0 [0] [1]
# 1 [1] [1, 0]
# 2 [1, 0] [1, 1]
# 3 [1, 1] [1, 0, 0]
# 4 [1, 0, 0] [1, 0, 1]
# 5 [1, 0, 1] [1, 1, 0]
# 6 [1, 1, 0] [1, 1, 1]
# 7 [1, 1, 1] [1, 0, 0, 0]
# 8 [1, 0, 0, 0] [1, 0, 0, 1]
# 9 [1, 0, 0, 1] [1, 0, 1, 0]
We start by breaking the problem up into smaller parts; n is the first problem, and rest is the rest of the problems. But the key to thinking with continuations (like cont above) is to think big.
In this particular problem, n gets updated based on whether rest gets updated. So we immediately recur on rest and pass a continuation that will receive the result of the subproblem. Our continuation receives the answer to the subproblem b, and whether or not that subproblem results in a carry.
...
else:
n, *rest = bin
return increment (rest, lambda b, carry:
cont ([n ^ carry] + b, n & carry))
The n ^ carry and n & carry expressions determine what the answer to this subproblem is and what the next carry will be. The following truth table shows that ^ and & encodes our answer and next_carry respectively. For example, if n is 0 and carry is 1, the carry can be consumed. The answer will be [1] + the answer to the subproblem and the next carry will be 0.
n carry (answer, next_carry) n ^ carry n & carry
0 0 ([0] + b, 0) 0 0
0 1 ([1] + b, 0) 1 0
1 0 ([1] + b, 0) 1 0
1 1 ([0] + b, 1) 0 1
The base cases are simple. If the subproblem is [0], the answer is [1] and no carry of 0. If the subproblem is [1], then the answer is [0]with a carry of 1
...
if bin == [0]:
return cont ([1], 0)
elif bin == [1]:
return cont ([0], 1)
Lastly, design the default continuation – if the answer to the problem b results in a carry, simply prepend [1] to the answer, otherwise just return the answer.
cont = lambda b, carry: [1] + b if carry else b
You are asking for the increment/successor/next function that will generate a sequence of sequences. Since other have given code, I will give a general method for developing such functions.
First, develop a multiple recursion (2 or more recursive calls) for calculating, say, all sequences of the type of length N. For binary sequences (bs) in big-endian order, from N 0s to N 1s, the base case bs(0) expression is [[]], the sequence that contains the one sequence with no binary digits. The double recursion for bs(n) in terms of bs(n-1) is ([0] concatenated to all members of bs(n-1) (in order)) plus ([1] contanenated to all members of bs(n-1)).
Next, focus on the transition between the subsequences returned by adjacent recursive calls. Here there is just one: 0, 1, ..., 1 to 1, 0, ..., 0. To increment across this boundary, we need to replace 0 followed by 0 or more 1s by 1 followed by the same number of 0s. We find such breaks by scanning from the right for the first 0, as others have shown.
It turns out the every increment crosses the boundary between adjacent bs(k) calls for some value of k, which is to say, at some level of the tree of calls resulting from double recursion.
So far, that I know of, the same idea works for designing the increment function for sequences of grey codes, sequences of conbinations (n things taken k at a time), and sequences of permutations.
Note 1: the 1->0 transitions can be done 1 at a time or all at once.
Note 2: the binary bit testing and flipping is the turing machine algorithm for count + 1. Stephen Wolfram, A New Kind of Science, presents, as I remember, 3 different implementations in the TM chapter.
Note 3 (added in edit): If one switches from prepending 0 first to prepending 1 first, or from prepending to appending, or both, one gets 3 other sequence of sequences, with 3 other increment functions.
You do not need recursion in this case. Let us start with the simplest implementation:
implement a full adder which will operate on bits.
implement a ripple adder using the full adder which will operate on 2 lists of bits.
The full adder implementation is straight forrward.
def full_adder(a,b,cin):
sum_ = a^(b^cin)
cout = (a&b) | (a|b)&cin
return sum_, cout
Tests to make sure the full adder conforms to the specs:
>>> zero_one = (0,1)
>>> [full_adder(*x) for x in [(a,b,c) for a in zero_one for b in zero_one for c in zero_one]]
[(0, 0), (1, 0), (1, 0), (0, 1), (1, 0), (0, 1), (0, 1), (1, 1)]
Since the parameters of the ripple adder are lists, we need to ensure the list lengths match before the addition. This is done by padding the shorter list with leading zeros.
def ripple_adder(xs,ys):
x, y = map(len, (xs, ys))
alen = max(x, y)
ax, by = map(lambda f: f if len(f) == alen else [0]*(alen-len(f)) + f, (xs, ys))
cout = 0
res = [0]*(alen)
for i in range(alen-1, -1, -1):
a, b, cin = ax[i], by[i], cout
s, cout = full_adder(a, b, cin)
res[i] = s
if cout:
res = [1] + res
return res
Finally, we define bin_inc the binary increment function in terms of the ripple adder
def bin_inc(bin_lst):
return ripple_adder(bin_lst, [1])
>>> bin_inc([1,1,1])
[1, 0, 0, 0]
>>> bin_inc([1,0,0,1])
[1, 0, 1, 0]
Now for a solution that is simpler but requires a little insight. Consider the following
obervations for an input xs with length L and output ys
if xs is all ones, ys will have length L+1, the first element of ys will be 1 and the rest will be zeros.
if xs has a zero element, let p be the index of the last zero element in xs.
Then ys will be the list consisting of the first p elements of xs followed by a 1 followed by zeros of length L - p. That is
ys = xs[:p] + [1] + [0]*(L-p).
We can translate this to python code easily. We use python's list.index method to find the last occurence of zero by working on the reverse of the list and adjust the algorithm appropriately:
def bin_inc_2(xs):
if all(xs):
return [1] + [0]*len(xs)
p = xs[::-1].index(0)
return xs[:-p-1] + [1] + [0]*p
This works and is simpler than the ripple_adder based implementation. One minor drawback you might notice is when xs has a zero element, we traverse it to check if it is all ones, then traverse it again to find the first occurence of zero.
We can simplify the implementation and make it more pythonic atthe same time by using a try except block:
def bin_inc_3(bin_lst):
try:
p = bin_lst[::-1].index(0)
return bin_lst[:-p-1] + [1] + [0]*p
except ValueError:
return [1] + [0]*len(bin_lst)
This implementation is simple in terms of source text, and idiomatic python. Now we test it against the ripple_adder based adder to make sure it works well.
>>> z_n = (0,1)
>>> xs = [[a,b,c,d,e,f,g,h] for a in z_n for b in z_n for c in z_n for d in z_n
for e in z_n for f in z_n for g in z_n for h in z_n ]
>>> print(all(ripple_adder(x, [1]) == bin_inc_3(x) for x in xs))
True
Fantastic, it works as intended and correctly handles leading zeros as evidenced by the tests (which increments every number from 0 to 255).
There's only a need to recurse when there is a carry:
def f(n):
# Base cases
if not n:
return [1]
if n == [1]:
return [1, 0]
if n[-1] == 0:
return n[:-1] + [1]
if n[-2:] == [0, 1]:
return n[:-2] + [1, 0]
# Recurse
return f(n[:-2]) + [0, 0]
numbers = [[1, 0, 1], [1,1,1], [1,0,0,1], [1, 0, 1, 1]]
for n in numbers:
print n, f(n)

Increment array in python, like a base number system

Say I have an array like [0 0 0 0] and I want to iterate it on a base-like scale. So say I pick base 100, and assume that I want to do it in a little endian system. My output would look like:
[1 0 0 0]
[2 0 0 0]
...
[99 0 0 0]
[0 1 0 0]
My code currently is in a function 'indexArray' but I was wondering it it was possible to do this without an if statement in a much simpler way?
def indexArray(enteredArr):
enteredArr[0] += 1
for i in range(len(enteredArr)):
if enteredArr[i] > 99:
enteredArr[i] = 0
enteredArr[i + 1] += 1
return enteredArr
As usual in Python, there's an easier way if you look for it.
Your main loop could be:
for i in itertools.product(range(BASE), repeat=NDIM):
... stuff ...
For your example, BASE=100 and NDIM=4, but the same approach works for any other values.
i will be a tuple of array values counting up like (0, 0, 0, 0), (0, 0, 0, 1) ... (BASE-1, BASE-1, BASE-1, BASE-1).
num = 45
base = 3
num_base = []
remainder = num
# the remainders of the integer divisions of the number by the base are the digits of the number in the new base
# see also here: https://math.stackexchange.com/questions/111150/changing-a-number-between-arbitrary-bases
while remainder:
num_base.append(remainder % base)
remainder //= base
# join the list in reverse while changing type of digits to characters
print("".join(str(x) for x in num_base[::-1]))

Categories