3

i've been stuck on a question for some time now:

I'm looking to create a python function that consumes a string and a positive integer. The function will print the string n times, for n lines. I cannot use loops, i must only use recursion

e.g.

>>> repeat("hello", 3)
hellohellohello
hellohellohello
hellohellohello

whenever i try to make a function that does this, the function decreases the length of the string, progressively:

e.g.

>>> repeat("hello", 3)
hellohellohello
hellohello
hello

here's what my code looks like:

def repeat(a, n):
    if n == 0:
        print(a*n)
    else:
        print(a*n)
        repeat(a, n-1)

What is wrong with this attempt? How can I fix it?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Andrew Louis
  • 303
  • 1
  • 2
  • 15
  • So, you are confused what the `n-1` is doing? – OneCricketeer Oct 12 '16 at 21:05
  • yes, i want to keep the number of times the string is printed in one line as a fixed sort of parameter, but i want the function to repeat the line n times. – Andrew Louis Oct 12 '16 at 21:06
  • Hint: you can modify the first argument to `repeat` the same way you modify the second. Instead of passing `n` on the recursive call, you pass `n-1`. So instead of passing `a`, maybe pass something else? – Riaz Oct 12 '16 at 21:09

5 Answers5

7

One liner

def repeat(a,n):
    print((((a*n)+'\n')*n)[:-1])

Let's split this up

  1. a*n repeats string n times, which is what you want in one line
  2. +'\n' adds a new line to the string so that you can go to the next line
  3. *n because you need to repeat it n times
  4. the [:-1] is to remove the last \n as print puts a new-line by default.
gokul_uf
  • 740
  • 1
  • 8
  • 21
5

Try this

def f(string, n, c=0):
    if c < n:
        print(string * n)
        f(string, n, c=c + 1)

f('abc', 3)
zyxue
  • 7,904
  • 5
  • 48
  • 74
4

So you just need extra argument that will tell you how many times you already ran that function, and it should have default value, because in first place function must take two arguments(str and positive number).

def repeat(a, n, already_ran=0):
    if n == 0:
        print(a*(n+already_ran))
    else:
        print(a*(n+already_ran))
        repeat(a, n-1, already_ran+1)
repeat('help', 3)

Output

helphelphelp
helphelphelp
helphelphelp
helphelphelp
vishes_shell
  • 22,409
  • 6
  • 71
  • 81
2

You were really close.

def repeat(a, n):
    def rep(a, c):
        if c > 0:
            print(a)
            rep(a, c - 1)
    return rep(a * n, n)
print(repeat('ala', 2))
alaala
alaala

A function with closure would do the job.

Nf4r
  • 1,390
  • 1
  • 7
  • 9
  • super close, i'm looking to print (a*n) n times – Andrew Louis Oct 12 '16 at 21:09
  • No idea why this is upvoted when it literally does the same thing as the OP's method. – Sam Oct 12 '16 at 21:11
  • Usually, it's better to avoid nested function unless you have a very strong argument for it. It's also harder to test. In this case, I can see the motivation, an advantage of this solution over a 3-argument function is that it eliminates the possibility of mistakenly passing 3 arguments. You can make `rep` a bit cleaner by changing the condition to `if c > 0`, then you don't need to write a single-line return statement – zyxue Oct 12 '16 at 22:50
  • @zyxue yes, it might be better idea to change the statement as you said. Edited. – Nf4r Oct 13 '16 at 20:15
2

You should (optionally) pass a 3rd parameter that handles the decrementing of how many lines are left:

def repeat(string, times, lines_left=None):
    print(string * times)

    if(lines_left is None):
        lines_left = times
    lines_left = lines_left - 1

    if(lines_left > 0):
        repeat(string, times, lines_left)
Sam
  • 20,096
  • 2
  • 45
  • 71