''int' object is not subscriptable?
I'm doing an algorithm challenge on www.edabit.com, where you have a list of dice rolls, and:
if the number is 6, the next number on the list is amplified by a factor of 2
if the number is 1, the next number on the list is 0
this is my code:
def rolls(lst):
out = 0
iterate = 0
if lst[iterate] == 1:
out+=lst[iterate]
lst[iterate+1] = 0
iterate+=1
rolls(lst[iterate])
elif lst[iterate] == 6:
out+=lst[iterate]
lst[iterate+1] = lst[iterate+1]*2
iterate+=1
rolls(lst[iterate])
else:
out+=lst[iterate]
iterate+=1
The console gives me "TypeError: 'int' object is not subscriptable"
Any ideas? Also any other errors you spot would be useful.
I tried on other IDE's, but it gives the same output.
for a series like "1, 6, 2, 3, 2, 4, 5, 6, 2" I expect 27
Solution 1:[1]
As stated in the comments, for this kind of problem I wouldn't use recursion. A loop will be enough:
l = [1, 6, 2, 3, 2, 4, 5, 6, 2]
from itertools import accumulate
print(sum(accumulate([0] + l, lambda a, b: b*{1:0, 6:2}.get(a, 1))))
Prints:
27
Solution 2:[2]
If you have to use recursion for this problem, then you will need to pass two arguments first lst and second iterate. Note that lst[iterate] is a single element which you are passing to the function when calling it recursively.
Thus modify the function to take two arguments lst and iterate. And initially pass arguments as full list for lst and a 0 for iterate. rolls(lst, 0) should be your initial function call.
I suppose you want out variable to contain sum of all entries in lst when you visit them, so that also needs to be passed as an argument, making your initial call rolls(lst, 0, 0). I have edited the function to return the sum calculated in out accordingly.
def rolls(lst, iterate, out):
if iterate == len(lst):
return out
if lst[iterate] == 1:
out += lst[iterate]
if iterate + 1 < len(lst): #In order to avoid index out of bounds exception
lst[iterate + 1] = 0
rolls(lst, iterate + 1, out)
elif lst[iterate] == 6:
out += lst[iterate]
if iterate + 1 < len(lst): #In order to avoid index out of bounds exception
lst[iterate + 1] = lst[iterate + 1] * 2
rolls(lst, iterate + 1, out)
else:
out += lst[iterate]
rolls(lst, iterate+1, out)
Solution 3:[3]
Instead of looking to the next item, you can look at the previous item:
from itertools import islice
def rolls(lst):
if not lst:
return 0
total = prev = lst[0]
for x in islice(lst, 1, None):
if prev == 1:
x = 0
elif prev == 6:
x *= 2
prev = x
total += x
return total
For example:
>>> rolls([1, 6, 2, 3, 2, 4, 5, 6, 2])
27
>>> rolls([])
0
>>> rolls([1])
1
>>> rolls([2])
2
>>> rolls([3])
3
>>> rolls([4])
4
>>> rolls([6,1])
8
>>> rolls([6,2])
10
>>> rolls([6,1,5])
13
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Andrej Kesely |
Solution 2 | Prajyot Naik |
Solution 3 |