Python- Reading two n-spaced sequences as a list, subtracting the lists and printing the greatest difference.[CodeChef] - python-3.x

I was working with a problem on CodeChef and I am stuck with one of the sub task being incorrect.
Problem statement:
https://www.codechef.com/AUG19B/problems/MSNSADM1
You are given two sequences. For each valid i, player i scored
Ai
goals and committed
Bi
fouls. For each goal, the player that scored it gets
20
points, and for each foul,
10
points are deducted from the player that committed it. However, if the resulting number of points of some player is negative, this player will be considered to have
0
points instead.
You need to calculate the total number of points gained by each player and tell Alex the maximum of these values.
Input:
The first line of the input contains a single integer
T
denoting the number of test cases. The description of
T
test cases follows.
The first line of each test case contains a single integer
N
.
The second line contains
N
space-separated integers (for no. of goals).
The third line contains
N
space-separated integers (for no. of fouls).
Output:
For each test case, print a single line containing one integer ― the maximum number of points.
Constraints:
1≤T≤100
1≤N≤150
0≤Ai≤50
for each valid
i
0≤Bi≤50
for each valid
i
My approach to this was to create 2 lists and multiply each element of first by 20, second by 10 and then create a list c, which has the difference of each elements.
try:
t= int(input())
while(t != 0):
t -= 1
n = int(input())
a_i = list(map(int, input().split()))
b_i = list(map(int, input().split()))
a = [i * 20 for i in a_i]
b = [i * 10 for i in b_i]
for i in range(0 , len(a)):
if a[i] < 0:
a[i] = 0
for i in range(0 , len(b)):
if b[i] < 0:
b[i] = 0
c = [i - j for i, j in zip(a, b)]
print(max(c))
except:
pass
All the tasks seems to be showing correct answer except one. I can't seem to understand what I am doing wrong here.

With the given indentation you are only printing the last testcase.
You create lots of list's in between that are not needed but take time to create/instantiate etc.
You loop over your data twice to eleminate the negative values - also not needed.
Use generators instead:
try:
for _ in range(int(input())):
n = int(input())
a_i = map(int, input().split()) # dont list(...) this
b_i = map(int, input().split()) # dont list(...) this
# get the max - negatives are irrelevant, they are removed when printing
m = max(goals * 20 - fouls*10 for goals, fouls in zip(a_i,b_i))
# if _all values_ are negative, print 0 else print the max value
# you need to print _each_ testcase, not only the last as your code does
print(max( (m,0) ))
except:
pass

t= int(input())
while(t != 0):
t -= 1
n = int(input())
a_i = list(map(int, input().split()))
b_i = list(map(int, input().split()))
c=[]
a = [i * 20 for i in a_i]
b = [i * 10 for i in b_i]
c =list(map(int.__sub__, a, b))
for line in c:
if line < 0:
line = 0
print(max(c))enter code here

Related

Having an issue relating to finding an Armstrong number from a list in Python [duplicate]

n=int(input("Enter a Number: "))
x=0
y=0
z=0
while(n>0):
x=n%10
y=x**3
z=z+y
n=n//10
print (z)
#The z here is the same value which I enter, yet it doesn't work.
#If I enter 407 as n, z becomes (4^3)+(0^3)+(7^3) which is 407
if (z==n):
#But even when 407==407, it just wont print the bottom statement
print ("The number is Armstrong")
else:
print ("The number isn't Armstrong")
#it prints that it isn't an Armstrong number
After the while loop, n already became 4//10 which is 0, so it'll never equal z which is 407.
You will want to keep a copy of the original input for comparison.
As a general advice, use a debugger or at least print() your objects to see where the assignments went wrong.
Without using any built-in method
Armstrong number is 371 because 3**3 + 7**3 + 1**3 = 371. according this rule 123 is not Armstrong number because 1**3 + 2**3 + 3**3 is not equal to 123
def count_digit(n):
count = 0
while n > 0:
count += 1
n //= 10
return count
def is_armstrong(n):
given = n
result = 0
digit = count_digit(n)
while n > 0:
reminder = n % 10
result += reminder ** digit
n //= 10
return given == result
is_armstrong(371)
>> True
is_armstrong(123)
>> False
You can take in your initial number as a string so we can more easily convert it to a list. We can then map to create that list of ints. After we can use list comprehension to raise all int in that list to the power that is the len of our list. If the sum of this list equals our input, then we have an Armstrong number.
n = input('Enter a number: ')
nums = list(map(int, n))
raised = [i**len(nums) for i in nums]
if sum(raised) == int(n):
print('The number is Armstrong')
else:
print('The number is not Armstrong')
Expanded list comprehension:
raised = []
for i in nums:
i = i**len(nums)
raised.append(i)
print(raised)
Alternate for map:
nums = []
for i in n:
i = int(i)
nums.append(int(i))
I corrected your code:
n = int(input("Enter a Number: "))
x = 0
y = 0
z = 0
num = n
while n > 0:
x = n % 10
y = x**len(str(num))
z = z+y
n = n//10
print(z)
if (z == num):
print ("The number is Armstrong")
else:
print ("The number isn't Armstrong")
But you can still do it in many ways better. Look at the code of vash_the_stampede and ggorlen.
Or:
def isArmstrong(n):
print(f"{n} is {'' if int(n) == sum(int(i)**len(n) for i in n) else 'not '}an Armstrong number")
isArmstrong(input("Please enter a number: "))
Definition: a number n is an Armstrong number if the sum of each digit in n taken to the power of the total digits in n is equal to n.
It's important to keep track of the original number n, because it'll be needed to compare against the result of z (your variable representing the sum). Since you're mutating n in your while loop, there's no grounds for comparison against your original input, so if (z==n): isn't working like you expect. Save n in another variable, say, original, before reducing it to 0.
Additionally, your code has arbitrarily chosen 3 as the number of digits in the number. For your function to work correctly for any number, you'll need a way to count its digits. One way is to convert the number to a string and take the length.
I strongly recommend using descriptive variable names which reduces the chance of confusing yourself and others. It's only apparent that z represents your sum and x your remainder by virtue of reading through the code. If the code was any longer or more complex, it could be a nightmare to make sense of.
Lastly, Python is not a particularly flexible language from a style standpoint. I recommend adhering to the style guide as best as possible to keep your code readable.
Here's a working example:
def armstrong(n):
total = 0
original = n
digits = len(str(n))
while n > 0:
total += (n % 10) ** digits
n //= 10
return total == original
if __name__ == "__main__":
while 1:
print(armstrong(int(input("Enter a Number: "))))
Output:
Enter a Number: 407
True
Enter a Number: 1234
False
Enter a Number: 23
False
Enter a Number: 8
True
Enter a Number: 371
True
Try it!
total=0
def Armstrong(n):
m=list(n)
global total
for i in m:
total+=pow(int(i),len(n))
if total==int(n):
print ("it is Armstrong number")
else:
print("it is not Armstrong number")
Armstrong(input("enter your number"))
print(total)

Why is my python function not working properly when I call it recursively?

I'm doing a question from a previous Waterloo ccc competition (https://cemc.uwaterloo.ca/contests/computing/2020/ccc/juniorEF.pdf problem J5)
and my code isn't working the way I expected
Here's the sample input I'm using:
3
4
3 10 8 14
1 11 12 12
6 2 3 9
Here's my code so far
y_size = int(input())
x_size = int(input())
mat = []
"ok".split()
for i in range(y_size):
row = input().split()
mat.append(row)
pos_list = [[0, 0]]
current_num = int(mat[0][0])
a = 0
def canEscape():
global a
global mat
global pos_list
global current_num
end = y_size * x_size
if y_size -1 * x_size -1 == current_num:
return True
for i in range(y_size):
print("______")
for j in range(x_size):
v = (i + 1) * (j + 1)
print(v)
print(current_num)
if v == current_num:
print("ok")
if v == end:
print("ok")
a += 1
current_num = mat[i][j]
pos_list.append([i, j])
canEscape()
pos_list.pop(-1)
a -= 1
current_num = mat[pos_list[a][0]][pos_list[a][1]]
canEscape()
The problem I'm having is that I expect if v == current_num: to be true when I call it again. Both current_num and v are equal to 8 but the code seems to carry on with the for-in loop and break, without entering the if statement. I've made the output print v followed by current_num for every iteration of the for loop to try and figure out the problem but it seems that both variables == 8 so I really don't know what I did wrong. Did I make a silly mistake or did I structure my whole program wrong?
I'm having trouble following what your program is doing at all. This problem involves integer factoring, and I do not see where you're factoring integers. You definitely are not understanding that aspect of the problem.
When you calculate what cells you can go to you look at the value of your current cell. Lets say it is 6. 6 has the factors 1, 2, 3, and 6 because all of those numbers can be multiplied by another number to equal 6. So, you can go to the cells (1, 6), (6, 1), (2, 3), and (3, 2), because those are the pairs of numbers that can be multiplied together to equal 6.
Also, you never convert the lines of input into integers. When you append to the matrix, you are appending a list of strings that happen to be numbers. You must convert those into integers.
Anyways, this program will solve the problem. I copy and pasted the factoring algorithm from other threads:
n_rows = int(input())
n_cols = int(input())
mat = []
for i in range(n_rows):
mat.append(list(map(lambda x: int(x), input().split()))) # Convert input strings to integers.
def reduce(f, l):
# This is just needed for the factoring function
# It's not relevant to the problem
r = None
for e in l:
if r is None:
r = e
else:
r = f(r, e)
return r
def factors(n):
# An efficient function for calculating factors.
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
def get_pairs(items):
for i in range(len(items) // 2):
yield (items[i],items[len(items) - 1 - i]) # use yield to save memory
if(len(items) % 2 != 0): # This is for square numbers.
n = items[len(items) // 2]
yield (n,n)
checked_numbers = set()
def isPath(r=1, c=1):
# check if the testing row or column is to large.
if r > n_rows or c > n_cols:
return False
y = r - 1
x = c - 1
n = mat[y][x]
# If we've already checked a number with a certain value we dont need to check it again.
if n in checked_numbers:
return False
checked_numbers.add(n)
# Check if we've reached the exit.
if(r == n_rows and c == n_cols):
return True
# Calculate the factors of the number, and then find all valid pairs with those factors.
pairs = get_pairs(sorted(list(factors(n))))
# Remember to check each pair with both combinations of every pair of factors.
# If any of the pairs lead to the exit then we return true.
return any([isPath(pair[0], pair[1]) or isPath(pair[1], pair[0]) for pair in pairs])
if isPath():
print("yes");
else:
print("no");
This works and it is fast. However, it if you are limited on memory and/or have a large data input size your program could easily run out of memory. I think it is likely that this will happen with some of the testing inputs but I'm not sure.. It is surely possible to write this program in a way that would use a fraction of the memory, perhaps by converting the factors function to a function that uses iterators, as well as converting the get_pairs function to somehow iterate as well.
I would imagine that this solution solves most of the testing inputs they have but will not solve the ones towards the end, because they will be very large and it will run out of memory.

Printing first combination among various combinations

So I have a question:
Given an even number (greater than 2), return two prime numbers whose sum will be equal to given number. There are several combinations possible. Print only first such pair
This is for additional reference:
*Input: The first line contains T, the number of test cases. The following T lines consist of a number each, for which we'll find two prime numbers.
Note: The number would always be an even number.
Output: For every test case print two prime numbers space separated, such that the smaller number appears first. Answer for each test case must be in a new line.
Constraints: 1 ≤ T ≤ 70
2 < N ≤ 10000
Example:
Input:
5, 74, 1024, 66, 8, 9990
Output: 3 71, 3 1021, 5 61, 3 5, 17 9973
Here is what I tried:
import math
def prime(n):
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
T = int(input("No of inputs: ")) #T is the no of test cases
input_num = []
for i in range(0,T):
input_num.append(input())
lst2= []
if T in range(1,71):
for i in input_num:
if (i in range(3,1000)) and (i % 2 == 0):
for j in range(0,i):
if prime(j) == True:
lst2.append(j)
for x in lst2:
for y in lst2:
if x + y == j:
print(x,end = ' ')
print(y)
This is only taking inputs but not returning outputs.
Also my code is currently intended for all the combinations but what I want is only the first pair and I am not able to do that
I found a more elegant solution to this problem here. Java, C, C++ etc versions of solution is also present there. I am going to give the python3 solution.
# Python 3 program to find a prime number
# pair whose sum is equal to given number
# Python 3 program to print super primes
# less than or equal to n.
# Generate all prime numbers less than n.
def SieveOfEratosthenes(n, isPrime):
# Initialize all entries of boolean
# array as True. A value in isPrime[i]
# will finally be False if i is Not a
# prime, else True bool isPrime[n+1]
isPrime[0] = isPrime[1] = False
for i in range(2, n+1):
isPrime[i] = True
p = 2
while(p*p <= n):
# If isPrime[p] is not changed,
# then it is a prime
if (isPrime[p] == True):
# Update all multiples of p
i = p*p
while(i <= n):
isPrime[i] = False
i += p
p += 1
# Prints a prime pair with given sum
def findPrimePair(n):
# Generating primes using Sieve
isPrime = [0] * (n+1)
SieveOfEratosthenes(n, isPrime)
# Traversing all numbers to find
# first pair
for i in range(0, n):
if (isPrime[i] and isPrime[n - i]):
print(i,(n - i))
return
# Driven program
n = 74
findPrimePair(n)

minimum steps by 1 or 2 but divisible by given number

I am working on a python program where I want to find the minimum number of steps needed to reach a top floor such that the count of steps should be divisible by given number say m
Here is my program taken from here:
# A program to count the number of ways to reach n'th stair
# Recurssive program to find n'th fibonacci number
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
# returns no. of ways to reach s'th stair
def countWays(s):
return fib(s + 1)
# Driver program
s = 10
print("Number of ways = ", countWays(s) )
Here I am getting the total number of ways, but I want to filter them by those divisible by a given number say m, how to do this?
Example:
1) s = 10 and m = 2, output should be 6, as the steps are {2,2,2,2,1,1}
2) s = 3 and m = 5 output should be -1 as the possible steps are {1,1,1}, {2,1}, {1,2}
--> here none of them (means 3 steps, 2 steps, 2 steps) are divible by 5.
s = 10
m = 2
if s % m == 0:
print(s)
outputs: 10
Using % is a modulo operation. This provides a "remainder" after division. So if your item has no remainder, it is divisible by the selected number.
# A program to count the number of ways to reach n'th stair
# Recursive function used by countWays
def countWaysUtil(n,m):
res = [0 for x in range(n)] # Creates list res witth all elements 0
res[0],res[1] = 1,1
for i in range(2,n):
j = 1
while j<=m and j<=i:
res[i] = res[i] + res[i-j]
j = j + 1
return res[n-1]
# Returns number of ways to reach s'th stair
def countWays(s,m):
return countWaysUtil(s+1, m)
# Driver Program
s,m = 4,2
print "Number of ways =",countWays(s,m)
# Contributed by Harshit Agrawal
You can use this:
# A program to count the number of ways to reach n'th stair
# Recurssive program to find n'th fibonacci number
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)
# returns no. of ways to reach s'th stair
def countWays(s, m):
# Add in a division by m, which you pass to the function
# Cast it as an int to return a whole # and not decimal
return int(fib(s + 1) / m)
# Driver program
s = 10
# Set this to whatever
m = 3
print("Number of ways = ", countWays(s, m) )

Unable to assign result of map() to 2-D list

The below code is for taking a set of rows of students' marks in array, and need find the row with maximum marks.
Below is incomplete code, as need to search for the maximum sum row still; but stuck at the incomplete code due to error.
It gives below error in py3.codeskulptor.org/, while in Pythontutor, the program terminates at the same line number.
Line #17: IndexError: list assignment index out of range
# Input number of tests
t = int(input("Input number of tests"))
# Input size of rows (of students)
n = int(input("Input size of rows"))#.strip().split())
print (t,n)
arr = [[[] for i in range(t)] for i in range(n)]
total = [[] for i in range (n)]
for i in range(0,t):
# Input score of each student in row
sum =0
for j in range(n):
arr[i][j] = map(int, input("Input score").strip().split())#[:n]
#the above line causes compilation error
# Find sum of all scores row-wise
for m in arr[i][j]:
sum += m
total[i] = sum1
# Find the max. of total
for j in range(t):
y = max(total[j])
Please also suggest a crisper approach to program the above problem.
P.S. I found the above code to be nearly wrong, but kicked me in correct direction.
Have the modified code below with a question that arose during debugging that concerns the :
max() giving precedence to [] over an integer value
This behaviour of max() was detected when incorrectly stated line #13 as :
total = [[[] for i in range (l)] for i in range (n)]
The correct working code is below, with output :
# Input number of tests
t = int(input("Input number of tests"))
# Input number of rows (of students)
n = int(input("Input number of rows"))#.strip().split())
# Input limit on number of students in a row (of students)
l = int(input("Input max. number of studentsin any row"))#.strip().split())
print ('t :',t,'n :',n, 'l :', l)
arr = [[[[] for i in range(l)] for i in range(n)] for i in range(t)]
total = [[[] for i in range (n)] for i in range (t)]
# run input of tests
for i in range(t):
# Input score of each student in the i-th row, out of n
sum =0
for j in range(n):
#for k in range(l):
print("jkl:","i:",i,"j:",j)
arr[i][j] = map(int, input("Input score").strip().split())[:l]
for i in range(t):
for j in range(n):
# Find sum of all scores row-wise
sum = 0
for m in arr[i][j]:
#sum[i][j][] += m
print ('m :', m)
sum += m
#total[i][j] = sum[i][j][]
total[i][j] = sum
for i in range(t):
print("Test no. ", i)
for j in range(n):
#for m in arr[i][j]:
print (arr[i][j])
#print (m)
print("=========")
for i in range(t):
for j in range(n):
print(i,"-",j, total[i][j])
print("::::::")
print("=========")
# Find the max. of total
for i in range(t):
print([m for m in total[i]])
y = max([m for m in total[i]])
print ('i:',i,',', 'max total:',y)
Request reason for the precedence shown by max(), and if possible link the answer with some reference to underlying implementation in CPython.
arr = [[[] for i in range(t)] for i in range(n)]
Considering the above construction of arr, you have swapped t and n in the nested loops:
for i in range(t):
# …
for j in range(n):
arr[i][j] = …
The first index into arr (corresponding to the outer loop) must be a number between 0 and n–1.
The second index into arr (corresponding to the inner loop) must be a number between 0 and t–1.
You are making a mistake between t and n
i should be in range(n)
and j should be in range(t)

Resources