Mr. Ric feels that alternating the schedule for paying for gasoline only disadvantages him. So Mr. Dip proposed a waytodivide the paymentschedule. For every 2n, they will change the pattern by swapping the order (complement) of the payment in the pattern 2(n−1). Here is the pattern proposed by Dip:
n | Pattern |
---|---|
0 | A |
1 | AR |
2 | ARRA |
3 | ARRARAAR |
Mr. Ric feels that alternating the schedule for paying for gasoline only disadvantages him. So Mr. Dip proposed a waytodivide the paymentschedule. For every 2n, they will change the pattern by swapping the order (complement) of the payment in the pattern 2(n−1). Here is the pattern proposed by Dip:
n | Pattern |
---|---|
0 | A |
1 | AR |
2 | ARRA |
3 | ARRARAAR |
As can be seen, the text in bold is the opposite of the non-bold part of a pattern. Mr. Ric really likes this idea. Help Mr. Ric create a program to generate this pattern. Use Functions or Procedures in solving this problem. Clue: The sequence is the addition of complements from the previous sequence as shown in the example. Prepare an array of characters with a size of 2 times the previous sequence.
Example 1
Enter character 1: A
Enter character 2: R
Enter the value of n: 2
The obtained pattern: ARRA
Example 2
Enter character 1: U
Enter character 2: W
Enter the value of n: 4
The obtained pattern: UWWUWUUWWUUWUWWU
i tried this but the ouput is a bit off
def pattern(char1, char2, n):
pattern = char1
for i in range(n):
pattern += char2 * (i + 1)
pattern += char1
return pattern
def main():
char1 = input("Enter character 1: ")
char2 = input("Enter character 2: ")
n = int(input("Enter the value of n: "))
result = pattern(char1, char2, n)
print("The obtained pattern:", result)
if __name__ == "__main__":
main()
Share
Improve this question
asked Nov 20, 2024 at 15:28
FAUZIAH ROZYFAUZIAH ROZY
191 silver badge1 bronze badge
2
|
4 Answers
Reset to default 2Recursive solution:
def pattern(c, d, n):
return pattern(c+d, d+c, n-1) if n else c
Iterative solution:
def pattern(c, d, n):
for _ in range(n):
c, d = c+d, d+c
return c
In c
I keep the current pattern and in d
I keep its complement (initially they're just the two given characters). When I add the complement to the pattern, I also add the pattern to the complement to get the complement of the longer pattern. Do it n
times, either by recursion or by loop.
Attempt This Online!
For the recursive version: When the number of additions n
is positive, we do one right away and call the function to do the remaining n-1
. Otherwise, i.e., with no more additions to do, we just return c
. The (recursive) calls for your example become:
pattern('U', 'W', 4)
pattern('UW', 'WU', 3)
pattern('UWWU', 'WUUW', 2)
pattern('UWWUWUUW', 'WUUWUWWU', 1)
pattern('UWWUWUUWWUUWUWWU', 'WUUWUWWUUWWUWUUW', 0)
Let's see how to achieve the proposed result:
def pattern( char1, char2, n ):
# first we save the base pattern
out = char1 + char2
for i in range( n ):
# in each iteration, we add to it its inverted version
out += invert( out )
return out
def invert( char ):
out = ""
for i in range( len( char )):
# only in the odd numbers we add to **out** the reversed items
if i % 2 != 0:
out += char[ i ] + char[ i - 1 ]
return out
There are a number of ways you can approach this problem but I think the way the question prompts you with:
The sequence is the addition of complements from the previous sequence as shown in the example
Is hinting that an answer based on recursion is being suggested. Note that there are already several good and correct answers here using recursion (I upvoted my fav already) but I thought you might get more out of an answer that was more explicit.
Also note, python has a default limit on how "deep" one can recurse and that most (all?) recursion can be replace by loops and a stack so there will be many ways to solve this even without recursion.
Let's take a look at the problem given n==0
.
In this case, we can write pattern()
as:
def pattern(char1, char2, n):
if n==0:
return char1
raise Exception() ## just to be explicit about only allowing n==0
now we can do:
print(pattern("A", "R", 0))
giving us A
Now let's extend that to n==1
def pattern(char1, char2, n):
if n==0:
return char1
if n==1:
return char1 + char2
raise Exception()
Now print(pattern("A", "R", 1))
gives us AR
as expected. However, recall the hint that the current answer is based on the compliment of the prior answer
For n==1
, let's get the result for n==0
and use it as part of our answer.
def pattern(char1, char2, n):
if n==0:
return char1
if n==1:
prior = pattern(char1, char2, n-1)
current = prior
return prior + current
raise Exception()
Now print(pattern("A", "R", 1))
gives us AA
(intentionally incorrect) however, we are not going to use the prior answer "as is" but rather take its compliment.
Perhaps something like (corrected):
def pattern(char1, char2, n):
if n==0:
return char1
if n==1:
prior = pattern(char1, char2, n-1)
current = char2 if prior == char1 else char1
return prior + current
raise Exception()
Now print(pattern("A", "R", 1))
gives us AR
as expected
What about n==2
? The only real difference here is that n==1
returns a string of characters rather than a single character and that when we take the compliment we will do it for each character in turn then use str.join()
to assemble a string from the complemented characters.
Perhaps like:
def pattern(char1, char2, n):
if n==0:
return char1
if n==1:
prior = pattern(char1, char2, n-1)
current = char2 if prior == char1 else char1
return prior + current
if n==2:
prior = pattern(char1, char2, n-1)
current = [char2 if c == char1 else char1 for c in prior]
return prior + "".join(current)
raise Exception()
Now print(pattern("A", "R", 2))
gives us ARRA
Now here is the trick.
First note that having solved for n==2
we have actually solved for n >= 2
and that n=1
is also a sub-case of n=2
as a string of a single character also looks like a list of length 1 in the same way that a two character string looks like list of length 2.
So, let's collapse our method around the notion that n==0
is a special case and when n > 0
things kind of look the same as far as our method is concerned.
def pattern(char1, char2, n):
if n==0:
return char1
prior = pattern(char1, char2, n-1)
current = [char2 if c == char1 else char1 for c in prior]
return prior + "".join(current)
Now we can see:
print(pattern("A", "R", 0)) --> A
print(pattern("A", "R", 1)) --> AR
print(pattern("A", "R", 2)) --> AARRA
print(pattern("A", "R", 3)) --> ARRARAAR
print(pattern("A", "R", 4)) --> ARRARAARRAARARRA
I suggest you break the problem down a bit further. Being able to decompose problems into smaller problems is key to solving any problems, and it's especially helpful for programmers.
Each step appends the inverse of the previous step to the string. So the first step is to obtain the inverse of a string.
I've used re.sub
with a lambda to accomplish the inversion by matching either the first or second character and then the lambda checks to see which one and delivers the correct replacement based on that. There are other methods of accomplishing this end goal, but invert
can be a black box. As long as it achieves its goal, the rest of our program can be written without caring how it gets there.
import re
def invert(s, a, b):
return re.sub(rf"({a}|{b})", lambda m: b if m.group(0) == a else a, s)
From there it's reasonably straightforward. Start by adding char1
to a result. Then add the result's inverse to itself on each loop.
def pattern(ch1, ch2, n):
result = ch1
for _ in range(1, n):
result += invert(result, ch1, ch2)
return result
Taking this a step further, the n
parameter is only needed to put a bound on the iteration so the function can end and return a result. But if a complementary function were creating a generator which yields the pieces we could let the pattern
function be a consumer of that generator and decide where to end the iteration.
import itertools
def pattern_pieces(ch1, ch2):
result = ch1
yield result
while True:
inv = invert(result, ch1, ch2)
yield inv
result += inv
def pattern(ch1, ch2, n):
gen = pattern_pieces(ch1, ch2)
return ''.join(itertools.slice(gen, n))
pattern()
as a recursive method since almost all answers are based on a prior answer. – JonSG Commented Nov 20, 2024 at 15:40