Robben
Robben

Reputation: 261

Bow tie shape function

I am trying to code a function which prints out a bow tie like shape of numbers in the range of two through nine. Anything that is not within the range of two through nine should not print out.

For example,

 >>> numberBowTie(5)

 1        1
 22      22
 333    333
 4444  4444
 5555555555
 5555555555
 4444  4444
 333    333
 22      22
 1        1

Most of the practice problems, I have attempted, I did without any problems but I am having difficulty coding this particular problem. I thought about just hard coding eight different printouts but that was too sloppy. The spacing has to be figured mathematically.

The closes practice problem I did that resembles this problem is

def arrowHead(n): 
   for x in range(n+1): 
      print ((' '*n)+(' *'*x))
      n = n - 1 

but it didn't help me.

Upvotes: 3

Views: 925

Answers (2)

Chris Martin
Chris Martin

Reputation: 30736

print('\n'.join(map(lambda i: (' '*2*(9-i)).join([str(i)*i]*2),
                    range(0, 10) + list(reversed(range(10))))))

If you like terseness :)

Edit - Here's another one. The idea is to first build just one quadrant of the image, and then reflect it to build the rest.

def bowtie(n):

    quadrant = [str(i)*i + " "*(n-i) for i in range(1, n+1)]

    def mirror2(xs):
        mirror = lambda xs: list(xs) + list(reversed(xs))
        return mirror([''.join(mirror(x)) for x in xs])

    return '\n'.join(mirror2(quadrant))

Additional musings here.

Upvotes: 1

Nir Alfasi
Nir Alfasi

Reputation: 53525

def numberBowTie(num):
    for i in range(num):

        # the idea is to iterate on i and when it's '1' to print only one time '1' 
        # then 2*num - 2 spaces and then to print one time '1' again.
        # now do the same with i=2 only print '2' twice, 2*num - 4 spaces and then '2' twice again
        # or in general:
        #
        # 1) str(i)*i == print a string of the number i -> i times
        # 2) ' '* (2 * (num - i)) == print one space (2 * (num - i)) times
        # 3) do the same as in 1)
        #
        print str(i)*i + ' '* (2 * (num - i)) + str(i)*i 

    for i in range(num):
        # in the second loop we do the exact same calculation only in reverse order
        print str(num-i)*(num-i) + ' '* (2 * i) + str(num-i)*(num-i)


numberBowTie(9)

OUTPUT

1                1
22              22
333            333
4444          4444
55555        55555
666666      666666
7777777    7777777
88888888  88888888
999999999999999999
999999999999999999
88888888  88888888
7777777    7777777
666666      666666
55555        55555
4444          4444
333            333
22              22
1                1

For ssm (in one loop):

def numberBowTie(num):
    part1 = ''
    part2 = ''
    for i in range(num+1):
        part1 = part1 + str(i)*i + ' '* (2 * (num - i)) + str(i)*i +'\n'
        part2 = part2 + str(num-i)*(num-i) + ' '* (2 * i) + str(num-i)*(num-i) + '\n'
    print part1 + part2

Upvotes: 3

Related Questions