I am writing this program to find the 13 adjacent digits in this number that, when added together, have the largest sum. When I run it, however, the b value does not start at 12; it starts at some obscenely high number and I cannot figure out why. Any idea why my a and b values are not incrementing correctly?
num = "731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511125069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
a = 0
b = 12
greatest = 0
while b != len(str(num)):
num = str(num)
newNum = num[a:b]
total = 0
for num in newNum:
num = int(num)
total += num
if total > greatest:
greatest = total
a+=1
b+=1
print(b)
print(greatest)
The main issue is that you are reusing num in the inner loop, which renders the "original" num wrong after the first run.
Additionally, if you want a 13 digits run-in, you'd better start with b = 13
And furthermore, there is no need for str(num) since it is already a string, and no need to change b along the program. You can also replace the inner loop with a sum upon map.
Here is what it should look like after these changes:
num = "731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511125069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"
index = 0
run_in = 13
greatest = 0
while index + run_in < len(num):
num_slice = num[index: index + run_in]
slice_sum = sum(map(int, num_slice))
if slice_sum > greatest:
greatest = slice_sum
index += 1
print(greatest)
If you are into super functions, you can create the same effect with a list comprehension and a max closure, iterating all possible indexes (until the length of the number minus the run in):
greatest = max(sum(map(int, num[index: index + run_in])) for index in range(len(num) - run_in))
def largest(num, k):
num = str(num)
if len(num) < k: raise ValueError("Need a number with at least {} digits".format(k))
currsum = sum(int(i) for i in num[:k])
answer = currsum, 0
i = k+1
while i < len(num):
currsum -= int(num[i-k])
currsum += int(num[i])
if currsum > answer[0]: answer = currsum, i
i += 1
return answer
total, ind = largest(myNum, 13)
print("The maximum sum of digits is {}, starting at index {}".format(total, ind))
Related
I'm stuck on a range. It should be pretty simple by for some reason I can't figure it out. So i have a range of (x,y) and it should add every number within that range however once it gets to the third it should double and then continue adding them.
start = int(input())
end = int(input())
sum = 0
a = range (start,end)
for i in range (start,end):
sum = sum + i
i += 1
start = int(input())
end = int(input())
sum = 0
for i, v in enumerate(range(start,end+1)): #7+1 as it's non inclusive
sum+=v
if (i+1)%3 == 0: #every 3 it *2
sum *=2
print(sum)
and it outputs 72, as expected
Iterate over the range with step=3, and within that loop add the sum of each smaller range to the total before multiplying it by two.
total, start, end = 0, int(input()), int(input()) + 1
for i in range(start, end, 3):
total += sum(range(i, min(i+3, end)))
total *= 2
print(total)
2
7
72
We have an input integer let's say 13. We can find consistent subarray of fibonacci numbers that sums to 10 - [2,3,5]. I need to find next number that is not a sum of consistent subarray. In this case this number will be 14. I have this code, but the catch is, it can be optimized to not iterate through all of the N's from starting Left Pointer = 1 and Right Pointer = 1 but somehow "import" from previous N and i have no clue how to do it so maybe someone smarter might help.
def fib(n):
if n == 1: return 1
if n == 2: return 1
return fib(n-1) + fib(n-2)
def fibosubarr(n):
L_pointer = 1
R_pointer = 2
sumfibs = 1
while sumfibs != n:
if sumfibs > n and L_pointer < R_pointer:
sumfibs -= fib(L_pointer)
L_pointer += 1
elif sumfibs < n and L_poiner < R_pointer:
sumfibs += fib(R_pointer)
R_pointer += 1
else: return False
return True
n = int(input())
while fibosubarr(n):
n += 1
print(n)
Here's a technique called "memoizing". The fib function here keeps track of the current list and only extends it as necessary. Once it has generated a number, it doesn't need to do it again.
_fib = [1,1]
def fib(n):
while len(_fib) <= n:
_fib.append( _fib[-2]+_fib[-1] )
return _fib[n]
With your scheme, 200000 caused a noticeable delay. With this scheme, even 2 billion runs instantaneously.
To get the next subarray sum, you only need one call of the function -- provided you keep track of the least sum value that was exceeding n.
I would also use a generator for the Fibonacci numbers:
def genfib():
a = 1
b = 1
while True:
yield b
a, b = b, a + b
def fibosubarr(n):
left = genfib()
right = genfib()
sumfibs = next(right)
closest = float("inf")
while sumfibs:
if sumfibs > n:
closest = min(sumfibs, closest)
sumfibs -= next(left)
elif sumfibs < n:
sumfibs += next(right)
else:
return n
return closest
Now you can do as you did -- produce the next valid sum that is at least the input value:
n = int(input())
print(fibosubarr(n))
You could also loop to go from one such sum to the next:
n = 0
for _ in range(10): # first 10 such sums
n = fibosubarr(n+1)
print(n)
I'm playing with the Codality Demo Task. It's asking to design a function which determines the lowest missing integer greater than zero in an array.
I wrote a function that works, but Codility tests it as 88% (80% correctness). I can't think of instances where it would fail.
def solution(A):
#If there are negative values, set any negative values to zero
if any(n < 0 for n in A):
A = [(i > 0) * i for i in A]
count = 0
else: count = 1
#Get rid of repeating values
A = set(A)
#At this point, we may have only had negative #'s or the same # repeated.
#If negagive #'s, or repeated zero, then answer is 1
#If repeated 1's answer is 2
#If any other repeated #'s answer is 1
if (len(A) == 1):
if (list(A)[0] == 1):
return 2
else:
return 1
#Sort the array
A = sorted(A)
for j in range(len(A)):
#Test to see if it's greater than zero or >= to count. If so, it exists and is not the lowest integer.
#This fails if the first # is zero and the second number is NOT 1
if (A[j] <= count or A[j] == 0): #If the number is lt or equal to the count or zero then continue the count
count = count + 1
elif (j == 1 and A[j] > 1): return 1
else:
return count
return count
UPDATE:
I got this to 88% with the fixes above. It still fails with some input. I wish Codility would give the inputs that fail. Maybe it does with a full subscription. I'm just playing with the test.
UPDATE 2: Got this to 100% with Tranbi's suggestion.
def solution(A):
#Get rid of all zero and negative #'s
A = [i for i in A if i > 0]
#At this point, if there were only zero, negative, or combination of both, the answer is 1
if (len(A) == 0): return 1
count = 1
#Get rid of repeating values
A = set(A)
#At this point, we may have only had the same # repeated.
#If repeated 1's answer is 2
#If any other repeated #'s only, then answer is 1
if (len(A) == 1):
if (list(A)[0] == 1):
return 2
else:
return 1
#Sort the array
A = sorted(A)
for j in range(len(A)):
#Test to see if it's >= to count. If so, it exists and is not the lowest integer.
if (A[j] <= count): #If the number is lt or equal to the count then continue the count
count = count + 1
else:
return count
return count
Besides that bug for len=1, you also fail for example solution([0, 5]), which returns 2.
Anyway... Since you're willing to create a set, why not just make this really simple?
def solution(A):
A = set(A)
count = 1
while count in A:
count += 1
return count
I don't think this is true:
#At this point, we may have only had negative #'s or the same # repeated. If so, then the answer is 1+ the integer.
if (len(A) == 1):
return list(A)[0]+1
If A = [2] you should return 1 not 3.
Your code is quite confusing though. I think you could replace
if any(n < 0 for n in A):
A = [(i > 0) * i for i in A]
with
A = [i for i in A if i > 0]
What's the point of keeping 0 values?
I don't think this is needed:
if (len(A) == 1):
if (list(A)[0] == 1):
return 2
else:
return 1
It's already taken into account afterwards :)
Finally got a 100% score.
def solution(A):
# 1 isn't there
if 1 not in A:
return 1
# it's easier to sort
A.sort()
# positive "hole" in the array
prev=A[0]
for e in A[1:]:
if e>prev+1>0:
return prev+1
prev=e
# no positive "hole"
# 1 is in the middle
return A[-1]+1
I wrote this code to find the number with max divisors, but in the case with equal divisors like 672 and 8388608 which both of them have 24 divisors the code cannot select the biggest number and just return the first number with the more number of divisors. In that example, the code returns 672 while it is vivid that 8388608 is much bigger than 672!
please help me to modify my code.
thank you in advance.
def divisors(x):
c = 0
for i in range (1,x+1):
if x % i == 0:
c += 1
return c
m = 0
count = 0
for i in range (20):
a = int(input())
if divisors(a) > count:
m = a
count = divisors(a)
print(m,'',count)
This code will collect the maximum number of divisors in a list, resetting the list if a greater number is found, and appending to the list otherwise. If there are multiple numbers with the same number of divisors, you'll get a list of them:
def divisors(x):
c = 0
for i in range (1,x+1):
if x % i == 0:
c += 1
return c
m = []
count = 0
inputs = 767,665,999,895,907,796,561,914,719,819,555,529,672,933,882,869,801,660,879,985
for a in sorted(inputs):
d = divisors(a)
if d == count:
m.append(a)
elif d > count:
m = [a]
count = d
print(m,'',count)
Output:
[660, 672] 24
If you just want the biggest number, use max(m) in the final print instead.
My objective was to use the index of a list to do addition/subtraction with. Where by I turned the even index positive, and the odd index negative.
EX1: 1234508 Should be answered by a 0: 1-2+3-4+5-0+8 = 11, then the while loops it again and I get 1-2+1 = 0
Ex2: 12345 Should be answered by a 3: 1-2+3-5 = 3, so it shouldn't go through the loop again.
Ex3: 121 Should be answered by a 0: 1-2+1 = 0, so it shouldn't go throught he loop again.
def main():
print()
print("Program to determine if a number is evenly\ndivisible by 11")
print()
indexed = input("Enter a number: ",)
total = 0
num = 0
while num >= 10:
for item in indexed:
if num %2 == 0:
total = total + int(item)
else:
total = total - int(item)
num = num + 1
print(total)
main()
Note that this print statement above is a place holder for a if statement which is inactive on my code, but was printing as large bold print here.
Let's say you have a string st whose characters are all digits, and that you want to have the sum of these digits. You then define the following function
def sd(st):
return sum(int(d) for d in st)
that we can test in the interpreter
In [30]: sd('10101010101010101010')
Out[30]: 10
In [31]: sd('101010101010101010101')
Out[31]: 11
What you really want is to sum the odd digits and subtract the even ones, but this is equivalent to sum the odds, sum separately the evens and then take the difference, isn't it? so what you want is
step_1 = sd(odds(st)) - sd(evens(st))
How can you separate the odd digits from the even ones? Ah! no need for a function, we can use slices
step_2 = sd(st[::2]) - sd(st[1::2])
Now we want to test the slices in the interpreter
In [32]: '101010101010101010101'[::2]
Out[32]: '11111111111'
In [33]: '101010101010101010101'[1::2]
Out[33]: '0000000000'
But step_2 could be a negative number, that I don't want to manage... I'd rather use the abs builtin
step_3 = abs(sd(st[::2]) - sd(st[1::2]))
and this is exactly what you were looking for.
Eventually we can put all the above together, but we may need to iterate until the difference is less than 11 --- we'll use an infinite loop and a break statement to exit the loop when we'll have found the answer
def sd(st):
return sum(int(d) for d in st)
number = input('Give me a number: ')
trial = number
while True:
n = abs(sd(trial[::2]) - sd(trial[1::2]))
if n < 11: break
trial = str(n)
if n > 0:
...
else:
...
what exactly do you want to do with this?
evenindex = evenindex int(item)
"list" is a type, means the list type in python, so it cannot be the name of a variable. Furthermore, you have not defined this variable in your code.
I have figured out the answer to the question I asked above. As such, my answer here is in the event anyone stumbles upon my above question.
def main():
indexed = input("Enter a number: ",)
total = 0
num = 0
while num <= 10:
for item in indexed:
if num %2 == 0:
total = abs(total + int(item))
else:
total = abs(total - int(item))
num = num + 1
if total == 0:
print(indexed, "is evenly divisible by 11 \ncheck since", indexed, "modulus 11 is", int(indexed) % 11)
else:
print(indexed, "is not evenly divisible by 11 \ncheck since", indexed, "modulus 11 is", int(indexed) % 11)
input()
main()