Comparing the values of 2 lists without built-ins - python-3.x

I'm trying to make and anagram checker without any built-in functions. So far, I've managed this:
def isa1(s1, s2):
a = s1.lower()
b = s2.lower()
c = list(a)
d = list(b)
l = len(s1)
counter = 0
for i in range(l):
if c[i] == d[0]:
del d[0]
counter += 1
elif c[i] == d[1]:
del d[1]
counter += 1
elif c[i] == d[2]:
del d[2]
counter += 1
elif c[i] == d[3]:
del d[3]
counter += 1
elif c[i] == d[4]:
del d[4]
counter += 1
elif c[i] == d[5]:
del d[5]
counter += 1
else:
pass
if counter == len(s1):
return True
else:
return False
I'm happy with the start, bar the assignment naming, but I cant figure out how to iterate through my second string, s2, without the for-loop being ridiculous. Plus this code will only work for a string/list 6 characters long.
Sorry if this seems simply, I'm just starting Python and programming in general
Thanks!

if you are okay with using for in side of for you can do:
def isa1(s1, s2):
a = s1.lower()
b = s2.lower()
c = list(a)
d = list(b)
l = len(s1)
counter = 0
for i in range(l):
for j in range(len(d)):
if c[i] == d[j]:
del d[j]
counter += 1
break # to continue to the next letter
if counter == len(s1):
return True
else:
return False
this solution will check against each letter in the second list, and if it finds a match it will break the inner loop going to the next letter.

Related

PYTHON: projecteuler 60

I have some trouble about project euler problem 60.
The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.
The code that I created is too slow to see the correct answer. And I don't even see that is it work correctly or not. The code is:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Aug 27 21:18:10 2022
#author: burak
"""
def is_prime(n, check_list_for_primes): #checks if value is prime
if check_list_for_primes.count(n) > 0: #checks if valu calculated before. if it were, it avoid loop.
return True
else:
if n == 1:
return False
if n == 2 or n == 3:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
exit(0)
i += 1
check_list_for_primes.append(n) # if it never calculated, stores the value to avoid loop at the beginning of function.
return True
def check_1(i, j): # checks the concanated calues if they are primes.
if is_prime(int(str(i)+str(j)), check_list_for_primes) == True and is_prime(int(str(j)+str(i)), check_list_for_primes) == True:
return True
else:
return False
def check_2(temp_list, n): # checks the final list that obtain the minimum summation.
if temp_list.count(n) == 0:
temp_list.append(n)
for i in temp_list:
for j in temp_list:
if len(temp_list) == 1:
return check_1(i, j)
elif i == j:
continue
elif len(temp_list) == 1:
return True
break
elif check_1(i, j) == False:
return False
return True
def func_(prime_list): # creates a dictionary summation of the five prime numbers in order to problem.
temp_list = []
result_dic = {}
k = 0
t = 0
for i in prime_list:
if i == 5:
continue
while k == 0:
t = k
for j in prime_list:
if i == j or j == 5:
continue
elif j < i:
continue
else:
temp_list.append(j)
if check_2(temp_list, i) == True:
continue
else:
temp_list.remove(j)
if t > 0 and len(temp_list) > 1:
t -= 1
temp_list.remove(max(temp_list))
continue
if len(temp_list) == 5:
result_dic[sum(temp_list)] = temp_list
elif len(temp_list) < 5:
k +=1
temp_list = []
return result_dic
if __name__ == "__main__":
dic_ = {}
prime_list = []
check_list_for_primes = []
for i in range(3, 9000, 1): #creates prime list between given range
if is_prime(i, check_list_for_primes) == True:
prime_list.append(i)
check_list_for_primes = prime_list.copy() #pseudo prime list to avoid calculating if the number is prime.
dic_ = func_(prime_list) #final dictionary to obtain minimum summation of five prime numbers.
x = min(list(dic_.keys()))
print(str(x) + " : " + str(dic_[x]))
I tried to type the examination of calculating order.
The main problem is at "func_" function. The for loop of "j" must be manipulated if the code not to get required list lenght. The "j" loop must be restart again after remove second element of "temp_list" and it must be start after shift to removed element of "prime_list".
Could you help me to see where I made mistakes and how can I improve calculation speed. Thanks so much.
I solved it. while loop changed and the "j" for loop determined by a list. The final code is;
def is_prime(n, check_list_for_primes): #checks if value is prime
if check_list_for_primes.count(n) > 0: #checks if valu calculated before. if it were, it avoid loop.
return True
else:
if n == 1:
return False
if n == 2 or n == 3:
return True
i = 2
while i * i <= n:
if n % i == 0:
return False
exit(0)
i += 1
check_list_for_primes.append(n) # if it never calculated, stores the value to avoid loop at the beginning of function.
return True
def check_1(i, j): # checks the concanated values if they are primes.
if is_prime(int(str(i)+str(j)), check_list_for_primes) == True and is_prime(int(str(j)+str(i)), check_list_for_primes) == True:
return True
else:
return False
def check_2(temp_list): # checks the final list that obtain the minimum summation.
for i in temp_list:
for j in temp_list:
if len(temp_list) == 1:
return check_1(i, j)
elif i == j:
continue
elif len(temp_list) == 1:
return True
break
elif check_1(i, j) == False:
return False
return True
def func_(prime_list): # creates a dictionary summation of the five prime numbers in order to problem.
prime_list.remove(5)
temp_list = []
result_dic = {}
# k = 0
copy_primes = prime_list.copy()
for i in prime_list:
for z in prime_list:
if z <= i:
copy_primes.remove(z)
else:
break
if i == max(prime_list):
break
elif i == 5:
continue
# for z in range(len(prime_list) - 1, 0, -1):
# if check_1(i,prime_list[z]) == True:
# max_prime_of_i = prime_list[z]
# break
while len(temp_list) < 5:
# if temp_list[1] == max_prime_of_i:
# break
if len(temp_list) == 1:
break
if len(copy_primes) == 0 and len(temp_list) > 1:
copy_primes = prime_list.copy()
for z in prime_list:
if z <= temp_list[1]:
copy_primes.remove(z)
else:
break
temp_list = []
for j in prime_list:
if len(copy_primes) > 0:
j = copy_primes[0]
copy_primes.remove(j)
else:
break
if temp_list.count(i) == 0:
temp_list.append(i)
continue
temp_list.append(j)
temp_list.sort()
if check_2(temp_list) == True and len(temp_list) > 1:
continue
elif check_2(temp_list) == False and len(temp_list) > 1:
temp_list.remove(j)
print(i)
print(temp_list)
if len(temp_list) < 5 and len(copy_primes) == 0:
continue
elif len(temp_list) == 5:
break
copy_primes = prime_list.copy()
if len(temp_list) == 5:
result_dic[sum(temp_list)] = temp_list
print(str(min(list(result_dic.keys()))) + " : " + str(result_dic[min(list(result_dic.keys()))]))
weight_ = 0
check_weight = 0
for p in temp_list:
weight_ = weight_ + len(str(p))
if weight_ < check_weight or check_weight == 0:
check_weight = weight_
elif check_weight < weight_ and len(temp_list) == 5:
return result_dic
temp_list = []
return result_dic
if __name__ == "__main__":
dic_ = {}
prime_list = []
check_list_for_primes = []
for i in range(3, 9000, 1): #creates prime list between given range
if is_prime(i, check_list_for_primes) == True:
prime_list.append(i)
check_list_for_primes = prime_list.copy() #pseudo prime list to avoid calculating if the number is prime.
dic_ = func_(prime_list) #final dictionary to obtain minimum summation of five prime numbers.
x = min(list(dic_.keys()))
print(str(x) + " : " + str(dic_[x]))

Python: Given 2 binary strings s and t, print minimum number of adjacent swaps to convert s to t

For example if s = "1000000111" and t = "0111000001" the output should be 11. Below is my solution but it gives a time limit exceeded error so I am looking for a faster method. The length of string is less than 10^6.
T = int(input())
for _ in range(0,T):
n = int(input())
s = input()
source = []
for letter in s:
source.append(letter)
#source[0],source[1] = source[1],source[0]
#print(source)
t = input()
target = []
for letter in t:
target.append(letter)
if source.count("1") != target.count("1") or source.count("0") != target.count("0"):
print(-1)
continue
else:
ans = 0
for i in range(0,n):
if source[i] != target[i]:
#print("".join(source),"".join(target))
if source[i] == "0":
j = i
while source[j] != "1":
j += 1
ans += j-i
source[i],source[j] = source[j],source[i]
else:
#print(source)
j = i
while source[j] != "0":
#print(j,ans)
j+=1
ans += j-i
source[i],source[j] = source[j],source[i]
print(ans)
Here's the code. The idea is that you count the location of '1's and then calculate the difference between the pairs. Time complexity O(n), space complexity O(n), but can be done O(1) with a careful indexing.
def foo(str1, str2):
if len(str1) != len(str2):
return -1
n = len(str1)
arr1 = [i for i in range(n) if str1[i] == '1']
arr2 = [i for i in range(n) if str2[i] == '1']
if len(arr1) != len(arr2):
return -1
res = 0
for i in range(len(arr1)):
res += abs(arr1[i] - arr2[i])
return res

Incrementing the for loop in python given a certain condition

The i+=1 isn't working, it should have increased the i value but it isn't
n = int(input())
for j in range(n):
a = input()
pair = 0
for i in range(len(a)-1):
print(i)
if a[i] == "x" and a[i+1] == "y":
pair += 1
print("*")
elif a[i] == "y" and a[i+1] =="x":
pair += 1
print('**')
else:
continue
i+=1
print(pair)
print("****")
print(pair)strong text
```
You are trying to modify a parameter that is implicitly set by the for loop.
This isn't C-Code, increasing the counter variable will not skip the next iteration.
The reason for that is quite simple: for itself does not increase i in every iteration, it just steps through the given iteratable. In this case the iteratable is a range, which behaves like for would increase i every iteration, but it really just takes the next value from the range.
So i+=1 doesn't have an effect on the next iteration, as it doesn't modify the next value in the range.
Your for-loop already increments i on every iteration. But if you want to increment by more than 1 when certain condition is satisfied, then you can use while loop as follows:
n = int(input())
for j in range(n):
a = input()
pair = 0
i = 0
while i < len(a)-1:
print(i)
if a[i] == "x" and a[i+1] == "y":
pair += 1
print("*")
elif a[i] == "y" and a[i+1] =="x":
pair += 1
print('**')
else:
i += 1
continue
i+=2
print(pair)
print("****")
print(pair)strong text
You could explicitely skip the next iteration when a pair is found.
Here is your code with the changes pointed at by # <---.
n = int(input())
for j in range(n):
a = input()
pair = 0
skip_next = False # <---
for i in range(len(a)-1):
if skip_next is True: # <---
skip_next = False # <---
continue # <---
print(i)
if a[i] == "x" and a[i+1] == "y":
pair += 1
print("*")
skip_next = True # <---
elif a[i] == "y" and a[i+1] =="x":
pair += 1
print('**')
skip_next = True # <---
else:
continue
print(pair)
print("****")
print(pair)

What am I doing wrong with this code for hackerrank?

I have been coding this problem for HackerRank and I ran into so many problems. The problem is called "Plus Minus" and I am doing it in Python 3. The directions are on https://www.hackerrank.com/challenges/plus-minus/problem. I tried so many things and it says that "there is no response on stdout". I guess a none-type is being returned. Here is the code.:
def plusMinus(arr):
p = 0
neg = 0
z = arr.count(0)
no = 0
for num in range(n):
if arr[num] < 0:
neg+=1
if arr[num] > 0:
p+=1
else:
no += 1
continue
return p/n
The following are the issues:
1) variable n, which represents length of the array, needs to be passed to the function plusMinus
2) No need to maintain the extra variable no, as you have already calculated the zero count. Therefore, we can eliminate the extra else condition.
3) No need to use continue statement, as there is no code after the statement.
4) The function needs to print the values instead of returning.
Have a look at the following code with proper naming of variables for easy understanding:
def plusMinus(arr, n):
positive_count = 0
negative_count = 0
zero_count = arr.count(0)
for num in range(n):
if arr[num] < 0:
negative_count += 1
if arr[num] > 0:
positive_count += 1
print(positive_count/n)
print(negative_count/n)
print(zero_count/n)
if __name__ == '__main__':
n = int(input())
arr = list(map(int, input().rstrip().split()))
plusMinus(arr, n)
The 6 decimals at the end are needed too :
Positive_Values = 0
Zeros = 0
Negative_Values = 0
n = int(input())
array = list(map(int,input().split()))
if len(array) != n:
print(f"Error, the list only has {len(array)} numbers out of {n}")
else:
for i in range(0,n):
if array[i] == 0:
Zeros +=1
elif array[i] > 0:
Positive_Values += 1
else:
Negative_Values += 1
Proportion_Positive_Values = Positive_Values / n
Proportion_Of_Zeros = Zeros / n
Proportion_Negative_Values = Negative_Values / n
print('{:.6f}'.format(Proportion_Positive_Values))
print('{:.6f}'.format(Proportion_Negative_Values))
print('{:.6f}'.format(Proportion_Of_Zeros))

updating value of argument passed in function

I am trying merge sort but the values in the list is not updating . I know arguments are passed by assignments .but how this code is not working
def mergeSort(arr):
#add code here
if len(arr) <2 :
return
mid = len(arr)//2
s1 = arr[:mid]
s2 = arr[mid:]
mergeSort(s1)
mergeSort(s2)
i= 0 ; j =0
while i+j < len(arr):
if i<len(s1) or j ==len(s2) and s1[i] <s2[j] :
arr[i+j] = s1[i]
i +=1
else :
arr[i+j] = s2[j]
j +=1
return arr
mergeSort(arr)
for ex arr =[5,4,3,2,1]
the output is same arr,
but this code is working fine
def mergeSort(arr):
#add code here
if len(arr)>1:
mid=len(arr)//2
l=arr[:mid]
r=arr[mid:]
mergeSort(l)
mergeSort(r)
i=j=k=0
while i<len(l) and j<len(r):
if l[i]<r[j]:
arr[k]=l[i]
i+=1
else:
arr[k]=r[j]
j+=1
k+=1
while i<len(l):
arr[k]=l[i]
i+=1
k+=1
while j<len(r):
arr[k]=r[j]
j+=1
k+=1
return arr
mergeSort(arr)
I don't know what i'm missing ? How the one is updating outer array and one not.

Resources