Recursively search word in a matrix of characters - python

I'm trying to write a program for a homework using recursion to search for a word in a matrix (2x2 or more), it can be going from left to right or from up to down (no other directions), for example if I am searching for ab , in the matrix [['a','b'],['c','d']], the program should return in what direction the word is written (across), the starting index(0), ending index(2), and the index of the row or column(0).
My problem is that I have the idea of the recursion but, I can't implement it. I tried to break the problem down into more little proplems, like searching for the word in a given row, I started by thinking of the smallest case which is 2x2 matrix, at the first row and column, I need to search one to the right and one to the bottom of the first char, and check if they are equal to my given string, then give my recursion function a smaller problem with the index+1. However I can't think of what to make my function return at the base case of the recursion, been trying to solve it and think of ways to do it for two days, and I can't code what I think about or draw.
Note that I can't use any loops, I would really appreciate it if somone could push me in the right direction, any help would be pretty much appreciated, thanks in advance.
Edit: more examples: for input of matrix : [['a','b','c'],['d','e','f'],['g','h','i']] the outputs are:
with the string ab : across,0,0,2
with the string be : down,1,0,2
with the string ghi: across,2,0,3

I assume that the word we are looking for could be found starting from any place but we can move up to down or left to right only.
In that case, you should have a function that takes the start index and a direction and then the function keeps moving in the given direction starting from the given index and keeps moving until it doesn't find a mismatch, and it just returns true or false based on the match of the given string.
Now you need to call this function for each and every index of the matrix along with two directions up to down and left to right, and at any index, if you get the output of the function as true then you have found your answer.
This is a very basic idea to work, next it depends on you how you want to optimize the things in this method only.
Update:
To avoid using the loops.
The other way I can think of is that the function which we have defined now takes the row, column, and the string to find. So at each call, you will first check if the character at the given row and column matches the first character of the given string if so then it calls the two more functions, one in the right direction and the other in the down direction, along with the string with the first character removed.
Now to check all the columns of the matrix, you will anyway call the function in down and right direction with the exact same string.
The base case will be that if you reach the end of the string then you have found the answer and you will return True, otherwise False.
One more thing to notice here is that if any of the 4 function calls gives you a True response then the current row/column will also return True.
Cheers!

Related

*Python* Non-Recursive Functions and Strings [duplicate]

This question already has answers here:
How to get the size of a string in Python?
(6 answers)
Closed 1 year ago.
we have just begun our unit on recursion, and I had a question regarding non-recursive functions and strings
I understand that strings are inherently recursive, as each character within a string has its own positive or negative index value, but I am a little unclear on how to create this function.
EDIT: Please disregard above text
What I meant to say:
I understand that a sequence is recursive in nature, that a string is a character followed by another string, just as a list is an element followed by another list.
Imagine we had a function called:
def flipside(s)
And when we input a string into our s parameter of the function, for example, the string:
'homework'
It takes the first half of the string (s) and moves it to the back while taking the second half of the string moving it the front, effectively generating the output:
'workhome'
I guess what I am having an issue with, is regarding string operations. If I do not know the length of s because it can take on any value due to it being a parameter, how do I create a non-recursive program to take 1//2 of s and move that half of the string to the back while simultaneously pushing the second half forward.
I have only gone so far as to set my base case:
def flipside(s):
if s == (''):
return 0
else:
fliprest =
return fliprest
Thank you, I would appreciate any information on the thought process behind your logic, or any feedback regarding any bad habits that I may be developing with how I have started off my code.
You can use slicing
def flipside(s):
return s[len(s)//2:] + s[:len(s)//2]
>>> flipside('homework')
'workhome'

what is output of following code? if it is empty string then please explain why?

I declare a string variable and want to access some characters with the help of slicing operators but it showing empty str as output.
please explain why it is showing empty.
I tried to print with different end index it works for all others but fails when end index becomes 0.
s='0123456789'
print(s[2:-1:-1])
In Python slicing, -1 means "the last element". So for a 10-character string, it's equivalent to 9. And then since your step is -1, you are slicing in the wrong way, so the result becomes empty.
If you want '210', you can go with s[2::-1], although it's a bit inconvenient when your end is a variable. There are multiple workarounds, though, like s[0:3][::-1].
See:
>>> s='0123456789'
>>> print(s[2:-1:-1])
>>> print(s[-1:2:-1])
9876543
The reason that the first statement isn't printing anything is because the start is already less than the end - if you were to continue to step -1, you would go out of the bounds of the array. Keep in mind that s[-1] resolves to s[len(s) - 1].
Or, in other words, if I told you to start at the second index of the array and go frontwards until you hit the last index of the array, it wouldn't make sense. After all, if you go frontwards, you're going towards the front of the array, not the back.
Meanwhile, if I switch those commands around - "start at the last index, and go frontwards until you hit the second index" - that makes perfect sense.
First argument means start_index, second means end_index (empty means until end iteration), third is step.
Your expected output: 210
s='0123456789'
print(s[2::-1])
output:
210

How to change numbers in a number

I'm currently trying to learn python.
Suppose there was a a number n = 12345.
How would one go about changing every digit starting from the first spot and iterating it between (1-9) and every other spot after (0-9).
I'm sadly currently learning python so I apologize for all the syntax error that might follow.
Here's my last few attempts/idea for skeleton of the code.
define the function
turn n into string
start with a for loop that for i in n range(0,9) for i[1]
else range(10)
Basically how does one fix a number while changing the others?
Please don't give solution just hints I enjoy the thinking process.
For example if n =29 the program could check
19,39,49,59,69,79,89,99
and
21,22,23,24,25,26,27,28
Although you are new, the process seems far easy than you think.
You want to make that change to every digit of the number (let's say n=7382). But you cannot iterate over numbers (not even changing specific digits of it as you want to): only over iterables (like lists). A string is an iterable. If you get the way to do a int-str conversion, you could iterate over every number and then print the new number.
But how do you change only the digit you are iterating to? Again, the way is repeating the conversion (saving it into a var before the loop would make great DRY) and getting a substring that gets all numbers except the one you are. There are two ways of doing this:
You search for that specific value and get its index (bad).
You enumerate the loop (good).
Why 2 is good? Because you have the real position of the actual number being change (think that doing an index in 75487 with 7 as the actual one changing would not work well when you get to the last one). Search for a way to iterate over items in a loop to get its actual index.
The easiest way to get a substring in Python is slicing. You slice two times: one to get all numbers before the actual one, and other to get all after it. Then you just join those two str with the actual variable number and you did it.
I hope I didn't put it easy for you, but is hard for a simple task as that.

String slices/substrings/ranges in Python

I'm newbie in Python and I would like to know something that I found very curious.
Let's say I have this:
s = "hello"
Then:
s[1:4] prints "ell" which makes sense...
and then s[3:-1] prints 'l' only that does makes sense too..
But!
s[-1:3] which is same range but backwards returns an empty string ''... and s[1:10] or s[1:-20] is not throwing an error at all.. which.. from my point of view, it should produce an error right? A typical out-of-bounds error.. :S
My conclusion is that the range are always from left to right, I would like to confirm with the community if this is as I'm saying or not.
Thanks!
s[-1:3] returns the empty string because there is nothing in that range. It is requesting the range from the last character, to the third character, moving to the right, but the last character is already past the third character.
Ranges are by default left to right.
There are extended slices which can reverse the step, or change it's size. So s[-1:3:-1] will give you just 'o'. The last -1 in that slice is telling you that the slice should move from right to left.
Slices won't throw errors if you request a range that isn't in the string, they just return an empty string for those positions.
Ranges are "clamped" to the extent of the string... i.e.
s[:10]
will return the first 10 characters, or less if the string is not long enough.
A negative index means starting counting from the end, so s[-3:] takes the last three characters (or less if the string is shorter).
You can have range backward but you need to use an explicit step, like
s[10:5:-1]
You can also simply get the reverse of a string with
s[::-1]
or the string composed by taking all chars in even position with
s[::2]

Variable Length Needle in Haystack (Python)

I have a function designed to find errors in an application's search capabilities, which generates a variable-length search string from the non-control UTF-8 possibilities. Running pytest iterations on this function, the random UTF-8 strings, submitted for search, generate debug errors roughly once per 500 searches.
As I can grab each of the strings that caused an error, I want to determine what is the minimal sub-series of the characters in those strings which truly provoke the error. In other words, (inside of a pytest loop):
def fumble_towards_ecstasy(string_that_breaks):
# iterate over both length and content of the string
nugget = # minimum series of characters that break the search
return nugget
Should I slice the string in half and whittle down each side and re-submit until it fails, choose random characters from its (len() - 1) and then back up if an error doesn't happen? Brute force combinatorial? What's the best way to step through this?
Thanks.
Splitting the string in half will fail if there is a two character sequence that causes the failure, and that sequence lies exactly in the middle. Each half succeeds, but the combined string fails.
Here's one algorithm that will find a local minimum:
Try removing each character in turn.
If removing the character still causes failure, keep the new shorter string and repeat the algorithm on this new string.
If removing the character no longer causes failure, put it back and try removing the next character. Keep going until there are no more characters left to try. When you reach the end of the string you know that removing any one character causes the search to succeed.
I'd use a "whittle from both sides" approach. Splitting the string will always run the risk of breaking up the substring that was causing the error. My approach would be:
Pop as many characters off the left of the string as you can while still ensuring that the string causes an error.
Do the same to the right side.
You're left with - in theory - the minimal substring that causes the error.
Hope that helps!
First of all it's worth noting that the solution is possibly not unique, i.e. it may be the case that there are two or more broken substrings.
An alternate suggestion (to the good answers by both Xavier and Mark) is to run a recursive approach. Repeat the sampling with the limited subset of strings that caused the error. Once another error is found, repeat until a minimal substring is reached. This approach is robust enough to handle a more complex use case, where the error can exist in two non-adjacent entries. I don't think that is the case here, but it's nice to have a general purpopse method.

Categories

Resources