Hollow diamond in python with an asterisk outline - python

I have to build a hollow diamond like this one:
******
** **
* *
* *
** **
******
Heres what I have so far,
def hollow_diamond(w):
h=int(w/2)
while 0<h:
print('*'*h)
h=h-1
i=1
while i<(w/2+1):
print(i*'*')
i=i+1
However using the code that i have i only get half of the diamond.
***
**
*
*
**
***
Should I be using for loops instead of while to be able to complete the diamond?

You've already figured out how to print the first set of asterisks for each line; good job so far. Now, you need to figure out how many spaces to print. Let's take the first loop, where you're printing h asterisks in a grid of w lines.
You need h asterisks on the left and h more on the right; that's 2*h asterisks total. This leaves s = w - 2*h spaces in the middle.
So, for each line, you need to print ...
h asterisks
s spaces
h more asterisks
Does that move you toward a useful update of your current code?

Building a hollow diamond means, like you said, probably the following:
A line with full asterisks (0 spaces in the middle)
A line with 2 spaces in the middle
A line with 4 spaces in the middle
...
A line with l-2 spaces in the middle
A line with l-2 spaces in the middle
A line with l-4 spaces in the middle
A line with l-6 spaces in the middle
...
A line with full asterisks (l-l spaces in the middle)
n is the "step", or how many asterisks you "lose" in each iteration. l is the size of your square.
So, you algorithm is composed of two parts, the increasing spaces, and the decreasing spaces.
So, your algorithm should be something like this
for (spaces = 0; spaces < size/2 ; spaces = spaces + 1 )
for (asterisk = 0; asterisk < size/2 - spaces; asterisk = asterisk + 1)
print '*'
for (space = 0; space < spaces*2; space = space + 1)
print ' '
for (asterisk = 0; asterisk < size/2 - spaces; asterisk = asterisk + 1)
print '*'
for (spaces = size/2 - 1; spaces >= 0; spaces = spaces - 1)
# The same inner code as above
I purposedly didn't put the python code there, so you can do your homework properly ;), but once you understand the algorithm, that should be pretty easy.

I won't steal from you the joy to fix your homework but this exercise was quite fun so I'll give you another possible version to give you few ideas:
def cool_diamond(w):
r = []
for y in range(w):
s = '*' * (w - y)
r.append("{0}{1}{0}".format(s, ''.join(['-' for x in range(2 * y)]), s))
return '\n'.join(r + r[::-1])
for i in range(3, 6):
print cool_diamond(i)
print('-' * 80)
I'd strongly recommend you take your time first to fix yours! Otherwise you won't learn nothing from the exercise.
Once you've fixed yours you'll feel pretty satisfied for the effort paying off, and then... just then, you can take think whether you can improve YOUR version or refactoring.
Happy coding!
******
**--**
*----*
*----*
**--**
******
--------------------------------------------------------------------------------
********
***--***
**----**
*------*
*------*
**----**
***--***
********
--------------------------------------------------------------------------------
**********
****--****
***----***
**------**
*--------*
*--------*
**------**
***----***
****--****
**********
--------------------------------------------------------------------------------

Here, remember it is only for even numbers entered else the program will execute a number less than that. I have made a code for your requirement.
n=int(input('Enter a number'))
if n%2==0:
pass
else:
n-=1
print("Works only for even number,so decremented the number by 1")
k=n//2
print(a*n)
for i in range(1,k):
print(a*(k-i),end='')
print(b*(c),end='')
print(a*(k-i),end='')
print()
c=c+2
c=c-2
for i in range(1,k):
print(a*(i),end='')
print(b*(c),end='')
print(a*(i),end='')
print()
c-=2
print(a*n)
You can also use it as function. You can easily convert so. You can use both while and for loop.
Check out while loop.
a='*' ; b=' ';c=2
n=int(input('Enter a number'))
if n%2==0:
pass
else:
n-=1
print("Works only for even number,so decremented the number by 1")
k=n//2
print(a*n)
i=1
while i<k:
print(a*(k-i),end='')
print(b*c,end='')
print(a*(k-i),end='')
print()
c=c+2
i+=1
c-=2
i=1
while i<k:
print(a*i,end='')
print(b*c,end='')
print(a*i,end='')
print()
c-=2
i+=1
print(a*n)
Hope it helps.

Related

Analyze the time and space complexity of the following code

Problem from leetcode:
https://leetcode.com/problems/text-justification/description/
Given an array of words and a width maxWidth, format the text such that each line has exactly maxWidth characters and is fully (left and right) justified.
You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly maxWidth characters.
Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.
For the last line of text, it should be left justified and no extra space is inserted between words.
Original code:
class Solution:
def fullJustify(self, words, maxWidth):
ans, curr, word_length = [], [], 0
words.append(' ' * maxWidth)
for w in words:
if word_length + len(w) + len(curr) > maxWidth:
space = maxWidth-word_length
if w != words[-1]:
for i in range(space):
curr[i%(len(curr)-1 or 1)] += ' '
ans.append(''.join(curr))
else:
ans.append(' '.join(curr) + ' ' * (space - (len(curr) - 1)))
curr = []
word_length = 0
curr += [w]
word_length += len(w)
return ans
So there are 2 for-loops, one is inside another.
The second for-loop is determined by the space which change everytime but always smaller than 'maxWidth'. First loop has time-complexity of O(n), what's the overall time complexity?
If you call n = |words| and m = maxWidth then you'll notice that you have an outer loop that does n iterations, inside of that there are different conditions but if they happen to be true you have another loop that in the worst case scenario is executed m times.
Therefore you can say time complexity is: T(n, m) = O(n * m)

How to draw a parallelogram with characters in python?

def parallelogram(a,b):
for i in range(a,0,-1):
for j in range (i,0,-1):
print("*",end='')
for j in range(b,0,-1):
print("+",end='')
for k in range(a-i,0,-1):
print("*",end='')
ı want to write a function which can draw a parallelogram with characters in python.ı couldnt.how can i fix my code?
output must looks like this:
****++++*
***++++**
**++++***
*++++****
With ASCII art you better first analyze the problem. If we want to draw a parallellogram with height a and width w, we first need to think how the first, second, i-th line, etc will look like.
The first line of the prallellogram will contain a asterisks (*), followed by b plusses (+) followed by one asterisk (*). We can write this as:
line1 = '*' * a + '+' * b + '*'
This of course does not solves the entire problem. The second line is almost equal to the first one, except that there is one asterisk less on the left side, and one more on the right side. So:
line2 = '*' * (a-1) + '+' * b + '*' * 2
Every line will remove one asterisk on the left, and add one on the right. So that means that linei has:
linei = '*' * (a+1-i) + '+' * b + '*' * i
Since the parallellogram has a such lines, we can range i from 1 to a+1:
for i in range(1, a+1):
linei = '*' * (a+1-i) + '+' * b + '*' * i
print(linei)
We can simplify this a bit, and write it as:
def parallelogram(a,b):
for i in range(1, a+1):
print('*' * (a+1-i) + '+' * b + '*' * i)
To start with, you are printing with end='', which causes subsequent characters to be printed on the same line. But at some point in your code, you need to add a print() to print on the next line. Start there and see if you figure out where else it needs improvement.

How to format a string into a shape?

I want to be able to print a string and format it into a shape. In the code here it formats into a right triangle, but I wanna do other shapes too. The problem is I can't get the string to truncate at each line and continue on, it simply loops at the first character.
this is what it looks like
hhhhhhhhhhhhhhh
hhhhhhhhhhhhh
hhhhhhhhhhh
hhhhhhhhh
hhhhhhh
hhhhh
hhh
h
but I want it to look like this
hellowor
ldhowar
eyout
oday
?
I've been struggling to wrap my head around this concept a lot lately, I can't seem to loop functions within functions properly. I think I'm probably missing some key part of knowledge for indexes or for loops that's stopping me. But if you could show me here, I might be able to learn a bit more about it. I've tried googling this issue to no avail. I appreciate any help.
Here's my code thus far:
text = ('hello world how are you today?')
def word():
for c in text:
return c
def triangle(i, t = 0):
if i == 0:
return 0
else:
print '' * (t + 1) + word() * (i * 2 - 1)
return triangle (i - 1, t + 1)
triangle (8)
edit:
the other thing I added was this:
def triangle(i, t = 0):
if i == 0:
return 0
else:
for c in text:
print '' * (t + 1) + word() * (i * 2 - 1)
return triangle (i - 1, t + 1)
but it yields the same problem, where by it only prints the first letter from 'text'.
How do I loop through each letter?
Thanks. The basic answer is that you're making this too complicated. Start at the front of the string with your initial row; pass the remainder to a recursive call. Don't bother to take individual characters out of the string: just grab the subset you need.
Note that this has two base cases: Either size hits 0, or you run out of message before that.
def triangle(message, size):
# Size = 0: we're done; ran out of rows
if size == 0:
return
# Not enough message left: print it all
if size >= len(message):
print message
# print "size" characters and go to next line
else:
print message[:size]
triangle(message[size:], size-1)
text = "hello world how are you today?"
triangle(text, 8)
print ""
triangle(text, 7)
Output:
hello wo
rld how
are y
ou to
day?
hello w
orld h
ow ar
e yo
u t
od
a
STRING SLICES
The general form is
str[start : end : step]
This gets you the substring from str[start] through str[end-1], inclusive. If you omit any of the arguments, the defaults are
start = 0
end = -1 (through the end of the string)
step = 1
Since we rarely have regular skips through a string, the step argument is almost always defaulted to 1.

I cannot figure out how to manipulate strings in a couple different ways [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to write a script that modifies an inputted string in these patterns (but without the dashes. those are just in there to format properly):
enter a string: dinosaurs
-d
--i
---n
----o
-----s
------a
-------u
--------r
---------s
-d
--i
---n
----o
-----s
----a
---u
--r
-s
-d-------s
--i------r
---n---u
----o-a
-----s
I don't even know where to start with this one.
Use enumerate to index each letter:
inputted="dinosaurs"
In [25]: for i,c in enumerate(inputted,start=1): # set start to 1 instead of the default 0
print " "* i + c '
d
i
n
o
s
a
u
r
s
This should help you figure out the second part of your question also.
I'll split this into three sections, one for each format. First, start off with your imports and read your word from standard input.
from __future__ import print_function
import sys
import math
word = sys.argv[1]
1. Margin increasing with length of string
for i, character in enumerate(word):
print(i * " ", character, sep='')
2. Margin decreases as distance to middle of string increases
We create a function to compute the distance from the ends of the word and use it to add the correct number of spaces accordingly.
distance = lambda i: len(word) / 2 - int(math.fabs((len(word) / 2) - i))
for i, character in enumerate(word):
print(distance(i) * " ", character, sep='')
3. Word displays as a triangle with the middle of the word at the bottom.
For the last one, we have to test if the word is an odd number of characters and add an offset of one if it does. We use this offset to align the middle characters correctly. We also redefine the distance function to indicate the distance from the middle of the word instead of from the end of the word.
distance = lambda i: int(math.fabs((len(word) / 2.) - i)) - 1
if len(word) % 2 == 1:
offset = 1
else:
offset = 0
for i in range(len(word) / 2 + offset):
if i == len(word) - i - 1:
print((i - offset) * " ", word[i])
else:
print(i * " ", word[i], (2 * distance(i) + offset) * " ", word[len(word) - i - 1], sep='')
Edit: Here is the output from running the program with "dinosaurs" as the provided input.
d
i
n
o
s
a
u
r
s
d
i
n
o
s
a
u
r
s
d s
i r
n u
o a
s

Recursive function dies with Memory Error

Say we have a function that translates the morse symbols:
. -> -.
- -> ...-
If we apply this function twice, we get e.g:
. -> -. -> ...--.
Given an input string and a number of repetitions, want to know the length of the final string. (Problem 1 from the Flemish Programming Contest VPW, taken from these slides which provide a solution in Haskell).
For the given inputfile
4
. 4
.- 2
-- 2
--... 50
We expect the solution
44
16
20
34028664377246354505728
Since I don't know Haskell, this is my recursive solution in Python that I came up with:
def encode(msg, repetition, morse={'.': '-.', '-': '...-'}):
if isinstance(repetition, str):
repetition = eval(repetition)
while repetition > 0:
newmsg = ''.join(morse[c] for c in msg)
return encode(newmsg, repetition-1)
return len(msg)
def problem1(fn):
with open(fn) as f:
f.next()
for line in f:
print encode(*line.split())
which works for the first three inputs but dies with a memory error for the last input.
How would you rewrite this in a more efficient way?
Edit
Rewrite based on the comments given:
def encode(p, s, repetition):
while repetition > 0:
p,s = p + 3*s, p + s
return encode(p, s, repetition-1)
return p + s
def problem1(fn):
with open(fn) as f:
f.next()
for line in f:
msg, repetition = line.split()
print encode(msg.count('.'), msg.count('-'), int(repetition))
Comments on style and further improvements still welcome
Consider that you don't actually have to output the resulting string, only the length of it. Also consider that the order of '.' and '-' in the string do not affect the final length (e.g. ".- 3" and "-. 3" produce the same final length).
Thus, I would give up on storing the entire string and instead store the number of '.' and the number of '-' as integers.
In your starting string, count the number of dots and dashes. Then apply this:
repetitions = 4
dots = 1
dashes = 0
for i in range(repetitions):
dots, dashes = dots + 3 * dashes, dashes + dots
Think about it why this works.
Per #Hammar (I had the same idea, but he explained it better than I could have ;-):
from sympy import Matrix
t = Matrix([[1,3],[1,1]])
def encode(dots, dashes, reps):
res = matrix([dashes, dots]) * t**reps
return res[0,0] + res[0,1]
you put the count of dots to dashes, and count of dashes to dots in each iteration...
def encode(dots, dashes, repetitions):
while repetitions > 0:
dots, dashes = dots + 3 * dashes, dots + dashes
repetitions -= 1
return dots + dashes
def problem1(fn):
with open(fn) as f:
count = int(next(f))
for i in xrange(count):
line = next(f)
msg, repetition = line.strip().split()
print encode(msg.count('.'), msg.count('-'), int(repetition))

Categories