How can I know if there are two 'L's which can see each other vertically or horizontally? This is a grid-based question. This is the code I currently have, but it doesn't seem to be functioning.
def sight(board):
lst = []
for line in board:
linelst = []
for char in line.strip():
linelst.append(char)
lst.append(linelst)
counter=-1
count=-1
for i in lst:
count+=1
counter = -1
for item in i:
counter+=1
if item == 'L':
numlstings = ['0','1','2','3','4']
for inter in range(1, len(lst)):
for inte in range(1,len(i)):
try:
if lst[count+inte][counter] == 'L' and count+inte > -1 and count+inte < len(lst) and count+inte > count:
return 'unhappy'
if lst[count-inte][counter] == 'L' and count-inte > -1 and count-inte < len(lst) and count-inte < count:
return 'unhappy'
if lst[count][counter+inter] == 'L' and counter+inter > -1 and counter+inter < len(i) and counter+inter<counter:
return 'unhappy'
if lst[count][counter-inter] == 'L' and counter-inter > -1 and counter-inter < len(i) and counter-inter>counter:
return 'unhappy'
if lst[count+inte][counter] == 'X' or lst[count+inte][counter] in numlstings:
break;
if lst[count-inte][counter] == 'X' or lst[count-inte][counter] in numlstings:
break;
if lst[count][counter+inter] == 'X' or lst[count][counter+inter] in numlstings:
break;
if lst[count][counter-inter] == 'X' or lst[count][counter-inter] in numlstings:
break;
except IndexError:
break;
return 'happy'
I want this code to return unhappy if it can see another 'L' in the same row or column, without the 'X' or the numbers intruding it. Otherwise, if it can't see an L it should return happy.
One such board is:
'......X.L.
.X..X...X.
L........L
X.....L...
....XX..X.
...LXX....
.X......L.
L.........
.......LXL
..LXL.....'.strip().split('\n')
This should return unhappy, but with my code it is returning happy.
There are also different boards which I have to test out.
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
I am new to python. I got below code, but my main function doesn't work. Can anyone help? Thank you!
The quetion is:
Given a string s, return the last substring of s in lexicographical order.
Example 1:
Input: "abab"
Output: "bab"
Explanation: The substrings are ["a", "ab", "aba", "abab", "b", "ba", "bab"]. The lexicographically maximum substring is "bab".
The IDE said;
Traceback (most recent call last):
File "F:/!!!PDF/!!!PyCharmWorkspace/LeetCode/AA1163LastSubstringInLexicographicalOrder3.py", line
1, in <module>
class Solution:
File "F:/!!!PDF/!!!PyCharmWorkspace/LeetCode/AA1163LastSubstringInLexicographicalOrder3.py", line
20, in Solution
print(lastSubstring(s))
TypeError: lastSubstring() missing 1 required positional argument: 's'
Below is my code.
class Solution:
def lastSubstring(self, s: str) -> str:
i, indexes = 0, list(range(len(s)))
while len(indexes) > 1:
new = []
mx = max([s[i + j] for j in indexes if i + j < len(s)])
for k, j in enumerate(indexes):
if k - 1 >= 0 and indexes[k - 1] + i == j:
continue
if i + j >= len(s):
break
if s[i + j] == mx:
new.append(j)
i += 1
indexes = new
return s[indexes[0]:]
if __name__ == '__main__':
s = "leetcode"
print(lastSubstring(s))
You are trying to use class function while you didn't create an instance of this class.
There are two ways to solve this issue.
First - Declare the lastSubstring as classmethod:
classmethod() methods are bound to class rather than an object. Class
methods can be called by both class and object. These methods can be
call with class or with object. Below examples illustrates above
clearly.
class Solution:
#classmethod
def lastSubstring(self, s: str) -> str:
i, indexes = 0, list(range(len(s)))
while len(indexes) > 1:
new = []
mx = max([s[i + j] for j in indexes if i + j < len(s)])
for k, j in enumerate(indexes):
if k - 1 >= 0 and indexes[k - 1] + i == j:
continue
if i + j >= len(s):
break
if s[i + j] == mx:
new.append(j)
i += 1
indexes = new
return s[indexes[0]:]
if __name__ == '__main__':
s = "leetcode"
print(Solution.lastSubstring(s))
Second - Create an instance from the Solution class first:
if __name__ == '__main__':
s = "leetcode"
sol= Solution()
print(sol.lastSubstring(s))
I am trying to calculate the avarage grade of a subject. but when i print the function i get printed None.
And i do not know how to fix it.
Ive tried returning the value instead then printing the function, but it wont work.
def karakterKonversjon(bokstav):
if bokstav == 'A':
return 6
if bokstav == 'B':
return 5
if bokstav == 'C':
return 4
if bokstav == 'D':
return 3
if bokstav == 'E':
return 2
if bokstav == 'F':
return 1
def konversjonTilBokstav(tall):
if tall == 6:
return 'A'
if tall == 5:
return 'B'
if tall == 4:
return 'C'
if tall == 3:
return 'D'
if tall == 2:
return 'E'
if tall == 1:
return 'F'
def beregnSnitt():
nummer_karakter = 0
suM = 0
for i in emner:
if emner[i] != "":
tall_karakter = eksamen.karakterKonversjon(emner[i])
suM += (tall_karakter * studiepoeng)
suM /= totalPoeng
rundetSvar = eksamen.normal_round(suM)
eksamen.konversjonTilBokstav(rundetSvar)
print(rundetSvar)
def normal_round(suM):
if (float (suM) < 5):
print(math.floor(suM))
else:
print(math.ceil(suM))
THe result i am expecting is
4
C
But i am getting
4
None
I made a few modifications to your code:
(I assume you are importing math in the eksamen file)
def karakterKonversjon(bokstav): # make this function more efficient
atof = ['A','B','C','D','E','F']
for i in range(len(atof)):
if bokstav.upper() == atof[i]:
return len(atof) - i
def konversjonTilBokstav(tall): # make this function more efficient
atof = ['A','B','C','D','E','F']
for i in range(1,7):
if tall == i:
return atof[len(atof)-i]
def beregnSnitt():
nummer_karakter = 0
suM = 0
for i in range(len(emner)): # if enmer == "enmer"(for example) you cannot reference enmer['e'] without raising an error
if emner[i] != "":
tall_karakter = eksamen.karakterKonversjon(emner[i])
suM += (tall_karakter * studiepoeng)
suM /= totalPoeng
rundetSvar = eksamen.normal_round(suM)
eksamen.konversjonTilBokstav(rundetSvar)
print(rundetSvar)
def normal_round(suM):
if (float (suM) < 5):
print(math.floor(suM))
else:
print(math.ceil(suM))
apart from the differences i made, your code should work well however i cannot test without knowing what enmer is (i assume it's a string) or what studiepoeng is.
the function konversjonTilBokstav did work fine for me. But what I have included in the code snippet should be less spaghetti code
I was solving a problem when I encountered a rather simple sub problem. Given two string S1 and S2, merge(S1,S2) denotes any string that's obtained by interspersing the two strings S1 and S2, maintaining the order of characters in both such that the resultant string is lexicographically smallest.
Example
S1 = abad
S2 = bbde
merge(S1, S2) = ababbdde
Now, i tried to solve the problem by applying a greedy technique starting from the first element of both the string and then looking for the smallest element and adding it to the result. But, soon I found out that this doesn't always lead to the optimal solution. The code looked something like below.
int n = a.size(), m = b.size();
int i =0, j=0, k=0; char array[n+m];
for(; i< n && j<n;) {
if(a[i] < b[j]) {
array[k] = a[i];
++i;
}
else {
array[k] = b[j];
++j;
}
++k;
}
while(i<n) {
array[k] = a[i];
++i;
++k;
}
while(j<m) {
array[k] = b[j];
++j;
++k;
}
for (int i = 0; i < n+m; ++i) {
cout<<array[i];
}
cout<<endl;
I thought of traversing it backwards and choosing the largest character and started adding it from behind. With the limited testing I performed this looked good.
int n = a.size(), m = b.size();
int i =n-1, j=m-1, k=n+m-1; char array[n+m];
for(; i>=0 && j>=0;) {
if(a[i] > b[j]) {
array[k] = a[i];
--i;
}
else {
array[k] = b[j];
--j;
}
--k;
}
while(i>=0) {
array[k] = a[i];
--i;
--k;
}
while(j>=0) {
array[k] = b[j];
--j;
--k;
}
for (int i = 0; i < n + m; ++i) {
cout<<array[i];
}
cout<<endl;
But, I'm unsure if this will always give the optimal solution always.
Is this solution correct in the first place and if yes can someone give me a slight proof as to why this produces the optimal solution always too.
The greedy approach works, however,
if(a[i] < b[j]) {
array[k] = a[i];
++i;
}
else {
array[k] = b[j];
++j;
}
this part is incorrect because when a[i] == b[j] you can't simply assign b[j] to array[k].
Instead, you need to compare the substring a[i:] and b[j:] when a[i] == b[j], and you can just operate on the std::string itself:
if(s1[i] < s2[j])
{
array[k] = s1[i];
++i;
}
else if (s1[i] == s2[j] && s1.substr(i) < s2.substr(j))
{
array[k] = s1[i];
++i;
}
else
{
array[k] = s2[j];
++j;
}
The time complexity would be quadratic (O(n^2)) since substr operation takes O(n).
Here's full solution based on my comment earlier.
import string
import random
global brute_force_lowest
global almost_greedy_lowest
global brute_force_calls
global almost_greedy_calls
def brute_force(p, a, b):
global brute_force_lowest
global brute_force_calls
brute_force_calls += 1
if len(a) > 0: brute_force(p + a[0], a[1:], b)
if len(b) > 0: brute_force(p + b[0], a, b[1:])
if len(a) == 0 and len(b) == 0:
if p < brute_force_lowest: brute_force_lowest = p
def almost_greedy(p, a, b):
global almost_greedy_lowest
global almost_greedy_calls
almost_greedy_calls += 1
if len(a) == 0 and len(b) == 0:
if p < almost_greedy_lowest: almost_greedy_lowest = p
elif len(b) == 0:
almost_greedy(p + a, '', '')
elif len(a) == 0:
almost_greedy(p + b, '', '')
elif a[0] < b[0]:
almost_greedy(p + a[0], a[1:], b)
elif a[0] > b[0]:
almost_greedy(p + b[0], a, b[1:])
else:
almost_greedy(p + a[0], a[1:], b)
almost_greedy(p + b[0], a, b[1:])
for j in range(10000):
a = ''.join(random.choice(string.ascii_lowercase) for _ in range(random.randint(2, 10)))
b = ''.join(random.choice(string.ascii_lowercase) for _ in range(random.randint(2, 10)))
brute_force_lowest = a + b
brute_force_calls = 0
brute_force('', a, b)
almost_greedy_calls = 0
almost_greedy_lowest = a + b
almost_greedy('', a, b)
print('%s, %s -> %s vs. %s (%.3f)' % (a, b, brute_force_lowest, almost_greedy_lowest, float(almost_greedy_calls) / brute_force_calls))
if almost_greedy_lowest != brute_force_lowest: print 'ERROR'
One interesting statistic is that this algorithm works about ten times faster then brute force algorithm on average if we limit alphabet to 'ab'.
UPDATE Some optimizations:
def prefix_length(a):
for i in range(len(a)):
if a[i] != a[0]: return i
return len(a)
def almost_greedy(p, a, b):
global almost_greedy_lowest
global almost_greedy_calls
almost_greedy_calls += 1
if p > almost_greedy_lowest: return
if len(a) == 0 and len(b) == 0:
if p < almost_greedy_lowest: almost_greedy_lowest = p
elif len(b) == 0:
almost_greedy(p + a, '', '')
elif len(a) == 0:
almost_greedy(p + b, '', '')
elif a[0] < b[0]:
almost_greedy(p + a[0], a[1:], b)
elif a[0] > b[0]:
almost_greedy(p + b[0], a, b[1:])
else:
la = prefix_length(a)
almost_greedy(p + a[0] * la, a[la:], b)
lb = prefix_length(b)
almost_greedy(p + b[0] * lb, a, b[lb:])
Greedy will solve the problem. to solve this problem you will have to visit both string for sure.
In your code you are missing at one place i.e. your first for loop if(a[i] < b[j]) it should be if(a[i] <= b[j]).
check the code here
Greedy will not give the correct solution and forking will increase the time complexity of the algorithm as you would have to continually revisit the substring that was the same in both strings. Instead, use a dequeue to store the characters that are common, and compare the next char to be chosen from either the deque, or the first string, or the second string
Look at the solution below (replace ints with char from the string, and switch the comparatror signs)
def maxNumber(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:type k: int
:rtype: List[int]
"""
d = deque()
arr = []
i, j = 0, 0
while i < len(nums1) and j < len(nums2):
if len(d) and d[0] > nums1[i] and d[0] > nums2[j]:
arr.append(d.popleft())
else:
if nums1[i] > nums2[j]:
arr.append(nums1[i])
i += 1
elif nums1[i] < nums2[j]:
arr.append(nums2[j])
j += 1
else:
arr.append(nums1[i])
d.append(nums2[j])
i += 1
j += 1
while i < len(nums1):
if len(d) and d[0] > nums1[i]:
arr.append(d.popleft())
else:
arr.append(nums1[i])
i += 1
while j < len(nums2):
if len(d) and d[0] > nums2[j]:
arr.append(d.popleft())
else:
arr.append(nums2[j])
j += 1
while len(d):
arr.append(d.popleft())
return arr