Lazy Sorting HackerRank Python - python-3.x

I am new to coding and so the following code I wrote may be incorrect or sub-optimal. However, the problem I have is that I do not understand the input and thus cannot get the code to run (I only tested it with custom inputs).
The essence of the problem is that you have some sequence of numbers and you want to arrange the sequence monotonically (nondecreasing or nonincreasing). You do this by a random shuffle. How many shuffles does it take for you to get to the monotonic sequence via a random shuffle? You can find the problem here and here is my code below:
#!/bin/python3 ------ The following import is given in the prompt
import os
import sys
# Complete the solve function below. Here is my code below
def solve(P):
P.sort()
correct = P
count = []
i = 0
# Here I am trying to calculate the number of ways to get the desired monotonic sequence
# I count the number of repeated numbers in the sequence as separate items in a list
for j in range(i,len(correct)):
if correct[i] != correct[j] or i == len(correct) - 1:
count.append(j-i)
i = j
j = len(correct)
else:
j = j + 1
summ = 0
for k in range(len(count)):
summ = summ + count[k]
if summ == len(correct):
i = len(correct)
poss = [1]*len(count)
for k in range(len(count)):
for l in range(1,count[k]+1):
poss[k] = poss[k]*l
possible = 1
for x in poss:
possible = possible * x
# This is calculating the number of different permutations of n distinct elements
total = 1
n = len(correct)
for i in range(1,n+1):
total = total * i
# Calculating the probability to the 6th decimal place
probability = float(possible / total)
expected = round(1/probability, 6)
print(expected)
# The following code is given in the prompt to input the test cases
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
P_count = int(input())
P = list(map(int, input().rstrip().split()))
result = solve(P)
fptr.write(str(result) + '\n')
fptr.close()
In my code, I just assumed that P is the sequence of numbers you receive from the input.

Related

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.

Convert a number to binary in Python

Given a non-negative integer n, write a function to_binary/ToBinary which returns that number in a binary format.
This is my code but some tests don't pass.
I appreciate it if you help me fix my code:
def to_binary(n):
string = ""
if n > 2:
string = string + str(n % 2)
x = n // 2
while x >= 2:
i = x % 2
string = string + str(i)
x = x // 2
string = string + str(1)
l = len(string)
string[l::-1]
return int(string)
else:
if n == 1:
return 1
if n == 2:
return 10
Few points to note.
Changing the concatenation logic will generate the string in reverse. You won't have to reverse it in the end.
In [10]: s = ''
In [11]: for i in range(5):
...: s = s + str(i)
...:
In [12]: s
Out[12]: '01234'
In [13]: s = ''
In [14]: for i in range(5):
...: s = str(i) + s # add the existing string after i
...:
In [15]: s
Out[15]: '43210'
You don't require a different logic for numbers less than 2. You shouldn't have to hardcode anything unless you're using recursion. In which case, hardcoding is simply the base case.
You are not reversing the string at all.
s[::-1]
This does not reverse a string in-place. Strings in python are immutable. What you can do is,
s = s[::-1]
Not providing the limits in a slice syntax is the same as providing start and end values (0 and length). You don't have to explicitly write s[len(s)::-1].
Your logic is almost correct. Just remove everything and keep the while loop and the code will work.
def to_bin(x):
if x == 0:
return '0'
b = ''
while x > 0:
b = str(x%2) + b
x //= 2
return b
There are of course several ways to do this without writing code just by using the builtin features of python.
You could try the implementing the mathematical method of converting bases into Python. Every number can be expressed as the sum of the powers of a base. For binary, base 2, this would be N*2**n + ... + A*2**3 + B*2**2 + C*2**1 + D*2**0. The hardest part is finding N, but from there we can use divmod to solve for the other variables.
def get_highest_power(num, base=2):
n = 0
while True:
if base**(n+1) >= num:
break
n += 1
return n
def solve_for_coefficients(num, power, base=2):
coefficients = []
for p in range(power, -1, -1):
coef, num = divmod(num, base**p)
coefficients.append(coef)
return coefficients
leading_power = get_highest_power(1000)
coefficients = solve_for_coefficients(1000, leading_power)
In order to get the base conversion, just use something like int(''.join([str(i) for i in coefficients])). This method works for all bases less than 10, since bases after ten require letters (but then again, you could use look at the items in coefficients to get the letters).
If you just want to solve the problem "number to binary string", you could use simple python:
def to_binary(n):
return "{:b}".format(n)
Simply use bin() instead.
def to_binary(n):
return(bin(n)[2:])
to_binary(6)
'110'

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) )

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

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

always got the same output with random.choice in a function

I tried using for-loop to exec my function but its always the same result.
import random
def main(arr):
result = random.choice(arr)
...some code...
return len(result)
for i in range(100):
main(arr)
I could only get diff result from stop/run the terminal. Anyone know why?
my question is the same as this one. random.choice always same
import random
results = []
with open('kargerMinCut.txt') as inputfile:
for line in inputfile:
results.append(line.strip().split('\t'))
def contract(arr):
while len(arr) > 2:
# Generate random number in list of lists
# ranList = random.choice(arr)
ranList = arr[np.random.choice(len(arr))]
ranNum = random.choice(ranList[1:])
# retrieve the index of the random number
listIndex = arr.index(ranList)
for i in range(0, len(arr)):
if arr[i][0] == ranNum:
targetList = i
break
target = ranList[0]
for i in range(0, len(arr)):
if i == listIndex:
arr[i].pop(0)
arr[i] = [x for x in arr[i] if x != ranNum]
elif i == targetList:
arr[i] = [x for x in arr[i] if x != target]
else:
for index, item in enumerate(arr[i]):
if item == target:
arr[i][index] = ranNum
arr[targetList] += arr[listIndex]
del arr[listIndex]
return len(arr[0])-1
the arr would be like this
array = [[1,2,3,4],[2,1,3,4],[3,1,2,4],[4,1,2,3]]
I don't know what you do inside your function but I've got the normal result. And in the question what you linked to the person just used seed. This is kinda pseudorandom that gives you all the time the same random output. Here is the link to deep your knowledge about pseudorandom
import random
arr = [1,2,3,4,5]
def main(arr):
result = random.choice(arr)
print(result)
for i in range(100):
main(arr)
The result is as it has to be:
1
3
5
3
4
3
1
4
4
3
2

Resources