Python need help figuring inclusive - python

Full disclosure, I am in school and I missed a problem on codingbat assignment 2 weeks ago, I am hoping I can get some direction here so that I can learn for the future
my problem was
Given a string and an int n, return a string made of the first n characters of the string, followed by the first n-1 characters of the string, inclusive (i.e. 0 <= n and n <= len(str)).
d_2('ydu', 2) → 'ydy'
d_2('yoda', 3) → 'yod'
d_2('yoda', 1) → '1'
The farthest I could get was:
def d_2(string, n):
string = string[:-n:]
return string
this would return 2 right answers
if I did
def d_2(string, n):
string = string[:-n:10]
return string
it would return 3 right answers.
I am sure it is a very simple thing, but my brain just is not picking it out, any direction

You can try making a loop to construct the string a = string[:n-1] + string[:n-2] + string[:n-3] .... until n is equal to 0.
def echo_first(string, n):
a=''
while n > 0:
a += string[:n]
n -= 1
return a

You could try with Recursive Functions to call the function itself until n==1:
def echo_first(string, n):
return string[:1] if n==1 else string[:n]+echo_first(string, n-1)

Related

How do to split the 2 digit numbers in a list into single digits?

So I am doing an assignment in school where I am given a range of numbers and the result is basically to find the number of numbers that can be divided by a factor digit, f, and contain the "must-have" digit, m. So I used list comprehension in my code and I have a list that contains all the numbers in the range that can be divided by f. But I need help on how to make a list that only has the numbers that have the "must-have" digit m.
def find_winner(f, m, n):
a = [x for x in range(1, n+1) if x % f == 0]
b = list(map(int, str(a[0])))
c = [z for z in b if z == str(m)]
return len(c)
Firstly you don't need to loop over all the numbers from 0 to n if you just want the ones that are divisible by f, when you can instead loop with a step of f.
Secondly, if you want to check whether digit is contained in the string, you could use string representation.
For example:
def find_winner(f, m, n):
digit_string = str(m)
if len(digit_string) != 1:
raise ValueError('m must be a one-digit number')
valid_numbers = [x for x in range(f, n+1, f) if digit_string in str(x)]
return len(valid_numbers)
If you have not yet covered exceptions, you might want to replace the raise ... line with a print statement and something like return None.
Here is a rather simple way of doing this:
def find_solutions(numbers, factor, digit):
solutions = 0
for i in range(len(numbers)):
if (numbers[i]%factor == 0 and str(digit) in str(numbers[i])):
solutions += 1
return solutions
If you care about the solutions then you could do this:
def find_solutions(numbers, factor, digit):
solutions = []
for i in range(len(numbers)):
if (numbers[i]%factor == 0 and str(digit) in str(numbers[i])):
solutions.append(numbers[i])
return solutions
Please give some thought as to what is happening here as opposed to just copying it and feel free to reply if you have anything to say. By the way, I have tried to name your variables appropriately for clarity.

Given 2 strings, return number of positions where the two strings contain the same length 2 substring

here is my code:
def string_match(a, b):
count = 0
if len(a) < 2 or len(b) < 2:
return 0
for i in range(len(a)):
if a[i:i+2] == b[i:i+2]:
count = count + 1
return count
And here are the results:
Correct me if I am wrong but, I see that it didn't work probably because the two string lengths are the same. If I were to change the for loop statement to:
for i in range(len(a)-1):
then it would work for all cases provided. But can someone explain to me why adding the -1 makes it work? Perhaps I'm comprehending how the for loop works in this case. And can someone tell me a more optimal way to write this because this is probably really bad code. Thank you!
But can someone explain to me why adding the -1 makes it work?
Observe:
test = 'food'
i = len(test) - 1
test[i:i+2] # produces 'd'
Using len(a) as your bound means that len(a) - 1 will be used as an i value, and therefore a slice is taken at the end of a that would extend past the end. In Python, such slices succeed, but produce fewer characters.
String slicing can return strings that are shorter than requested. In your first failing example that checks "abc" against "abc", in the third iteration of the for loop, both a[i:i+2] and b[i:i+2] are equal to "c", and therefore count is incremented.
Using range(len(a)-1) ensures that your loop stops before it gets to a slice that would be just one letter long.
Since the strings may be of different lengths, you want to iterate only up to the end of the shortest one. In addition, you're accessing i+2, so you only want i to iterate up to the index before the last item (otherwise you might get a false positive at the end of the string by going off the end and getting a single-character string).
def string_match(a: str, b: str) -> int:
return len([
a[i:i+2]
for i in range(min(len(a), len(b)) - 1)
if a[i:i+2] == b[i:i+2]
])
(You could also do this counting with a sum, but this makes it easy to get the actual matches as well!)
You can use this :
def string_match(a, b):
if len(a) < 2 or len(b) < 0:
return 0
subs = [a[i:i+2] for i in range(len(a)-1)]
occurence = list(map(lambda x: x in b, subs))
return occurence.count(True)

Question about the efficiency of two codes that look similar

The followings are the question Beautiful Arrangement(LeetCode 526) and two pieces of codes to the question. code 1 and code 2 look the same to me but I don't understand why code 1 takes much more time than code 2. Can somebody help me figure out the reason? Thanks in advance!
Question:
Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is constructed by these N numbers successfully if one of the following is true for the ith position (1 <= i <= N) in this array:
The number at the ith position is divisible by i.
i is divisible by the number at the ith position.
Now given N, how many beautiful arrangements can you construct?
code 1:
def countArrangement(self, N: int) -> int:
def dfs(cur,N,seen):
if cur==N:
return 1
res = 0
for i in seen:
if (cur+1)%i==0 or i%(cur+1)==0:
res += dfs(cur+1,N,seen-{i})
return res
seen = set(range(1,N+1))
return dfs(0,N,seen)
code 2:
def countArrangement(self, N: int) -> int:
def count(i,X):
if i==1: return 1
return sum(count(i-1,X-{x}) for x in X if i%x==0 or x%i==0)
return count(N,set(range(1,N+1)))

Is there a simpler way to do string_match from CodingBat in Python?

This is the problem. http://codingbat.com/prob/p182414
To summarize, given two strings (a and b) return how many times a substring of 2, from string a is in string b. For example, string_match('xxcaazz', 'xxbaaz') → 3.
def string_match(a, b):
amount = 0
for i in range(len(a)):
if (len(a[i:i+2]) == 2) and a[i:i+2] == b[i:i+2]:
amount += 1
return amount
Not much simpler, but if you limit the range of i to len(a)-1, you don't need to check if it defines a long enough substring of a.
My approach is something like this:
def string_match(a, b):
count = 0
for i in range(len(a)-1):
if a[i:i+2]==b[i:i+2]:
count += 1
return count

Python beginner recursion

I am trying to get a simple function which takes n and prints
If n > 0:
print((n*'*')+(n*'!'), end=' ')
and trying to get the same solution but recursively. I am a beginner to recursion, and often I get the "higher level of thinking", but I am having trouble understanding the code that must follow.
My base case is that when n is 0 it prints nothing. When n is more than 1 it will print n copies of * + n copies of!
def repeat(n):
if n <= 0:
pass
else:
repeat(n-1)
print((n*'*')+(n*'!'), end=' ')
right now it prints n, and then n-1 successively until 0. I have tried breaking it up into two print statements and using more than one recursion .. but it becomes a messy pattern.
I am also not allowed to use loops. This one is driving me insane; I have come up with several solutions to it besides the easy one line statement, but none that use recursion.
It's simpler if you build and return a string and print it outside of the function, like this:
def printPattern(n):
if n <= 0:
return ''
return '*' + printPattern(n-1) + '!'
Or as a one-liner:
def printPattern(n):
return '*' + printPattern(n-1) + '!' if n > 0 else ''
Either way, this works:
print printPattern(5)
> *****!!!!!
Assume you have a solution for n - 1. Prepend * and append !.
def repeat(n):
if n > 0:
print("*", end=" ")
repeat(n - 1)
print("!", end=" ")
The following does what you appear to want.
def repeat(n):
def stars(n):
return '*'+stars(n-1)+'!' if n > 0 else ''
print stars(n)
For example, repeat(5) prints *****!!!!! and repeat(8) prints
********!!!!!!!!.
I don't actually know what you're asking... If there's a more efficient or better way of doing this? This would be quite obvious:
def repeat(n):
if n >= 0:
print((n*'*')+(n*'!'), end=' ')
return repeat(n-1)
I would use two strings here, and return a concatenated string of those two strings when n<=0 and use return instead of printing inside function:
def repeat(n, strs1="", strs2=""): # The Default value of strings is ""
if n <= 0:
return strs1 + strs2 # if n<=0 then concatenate the two strings and return them
else:
strs1 += "*" # Add * to strs1
strs2 += "!" # Add ! to strs2
return repeat(n-1, strs1, strs2) # Pass n-1, as well as the two strings to a recursive call
print(repeat(5))
print(repeat(3))
Output:
*****!!!!!
***!!!

Categories