Home > Software design >  How to create equilateral pyramid of asterisks in asp
How to create equilateral pyramid of asterisks in asp

Time:03-01

My code prints out a right angled triangle

For i = 1 To 7

     For j = 1 to i
            response.write(" * ")
        Next
    
        for k = 0 < i to 7  
            response.write(" ")
        Next
    
    response.write("</br>")

CodePudding user response:

As the triangle will be rendered by the browser, you can use CSS for the layout, perhaps something like this:

<style>
    .triangle {
        display: flex;
        align-items: center;
        flex-direction: column;
    }

        .triangle div {
            letter-spacing: 0.72em;
        }
</style>

Then you will need this on the .aspx page:

<asp:Literal ID="aTriangle" runat="server"></asp:Literal>

Along with this in the code-behind:

Sub CreateTriangle(maxStars As Integer)
    Dim sb As New StringBuilder()
    sb.AppendLine("<div triangle"">")

    For i = 1 To maxStars
        sb.AppendLine("<div>" & New String("*"c, i) & "</div>")
    Next

    sb.AppendLine("</div>")
    aTriangle.Text = sb.ToString()

End Sub

And you call that in the Page_Load sub:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    CreateTriangle(6)

End Sub

CodePudding user response:

Ok, this is a great interview question!

And this kind of brings back the "joy" of writing code in the old days when we had a green screen, or "console" based applications.

The first problem: Output of spaces (blanks) in a browser is ignored. You can force and get around this by using a no breaking space ().

However, the text we using in a browser is NOT fixed spacing.

So, your code will produce the triangle, but the problem is fixed spacing is assumed. And if we want to space on the left side (and the right), then we have to use some convoluted code to calculate the spaces required on the left side, then the one "" then some more spaces, then the "". (and we can skip the spaces on the right side).

You get something like this:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim i, j As Integer

    Dim NumRows As Integer = TextBox1.Text

    Dim triWidth As Integer = (NumRows * 2) - 1
    Dim SpaceOnSide As Integer = 0
    Dim SpaceInMiddle As Integer = 0


    Dim Blank As String = " "
    Dim Border As String = "*"

    For i = 1 To NumRows
        ' space on left side
        SpaceOnSide = ((triWidth - ((i * 2) - 1))) / 2
        For j = 1 To SpaceOnSide
            OutPut(Blank)
        Next
        OutPut(Border)
        'SpaceInMiddle = triWidth - (SpaceOnSide * 2) - 2  ' - 1 for border
        SpaceInMiddle = (i * 2) - 1 - 2 ' - 2 for border
        For j = 1 To SpaceInMiddle
            If i = NumRows Then
                OutPut(Border)
            Else
                OutPut(Blank)
            End If
        Next
        If i > 1 Then
            OutPut(Border)
        End If

        Debug.WriteLine("")
    Next


End Sub

Sub OutPut(s As String)

    Debug.Write(s)

End Sub

and our output (to immediate window - I have under tools [x] send all output

enter image description here

However, lets change the code to put the "*" inside, and we get this:

        For j = 1 To SpaceInMiddle
            If i = NumRows Then
                OutPut(Border)
            Else
                OutPut(Border)
            End If
        Next

So we now get this:

enter image description here

The previous results also show.

Ok, but output to a console or green screen "text" is a bit of a problem. One problem is we actually need "half" spacing to put the line below if we going to make a triangle.

But, here is where HOW VERY cool the web gets.

First, we not limited to output of "*". We can output a image, or anything we want!!!

So, lets google - find a cute "ball" or "sphere" for this.

We will replace the "*" and " " (blank) with two images.

One for blanks (white square), and one for the "*"

So, I just placed these two squares in my content folder

And lets drop in a "div" for display of the "*" or now balls.

We COULD have dropped in a text box, and used a fixed "console" type font. But, this is the web.

So, lets take the above code - (convoluted - but we fix that in a minute).

And note how I used one routine called "output". I did this since we can now change that output to the browser.

So, our markup is now this:

        <div id="mydiv" runat="server">
        </div>

We just put in a "thing" or a place we want to shove our results into.

And now, we going to in place of a "*" output a picture to that div.

So, our convoluted code is now this:

    Dim Blank As String = GetFileAsPicture("w.jpg") ' white sqaure block
    Dim Border As String = GetFileAsPicture("r2.jpg") ' round ball 

    For i = 1 To NumRows
        ' space on left side
        SpaceOnSide = ((triWidth - ((i * 2) - 1))) / 2
        For j = 1 To SpaceOnSide
            OutPut(Blank)
        Next
        OutPut(Border)
        'SpaceInMiddle = triWidth - (SpaceOnSide * 2) - 2  ' - 1 for border
        SpaceInMiddle = (i * 2) - 1 - 2 ' - 2 for border
        For j = 1 To SpaceInMiddle
            If i = NumRows Then
                OutPut(Border)
            Else
                OutPut(Border)
            End If
        Next
        If i > 1 Then
            OutPut(Border)
        End If

        OutPut("<br/>")  ' start a new line
    Next

And GetFileAsPicture is this:

Function GetFileAsPicture(sFile As String) As String

    ' get a picture from our Content folder, 
    ' return as picture HTML "image" mark-up

    Return "<img src=""" & "../Content/" & sFile & """ />"

End Function

So, now when we run this, we get this:

enter image description here

Note how really it not a lot of extra work to output a "ball" in place of a "*".

However, we are STILL fixed font/image size in above. So really, that's not the triangle we want, since each ball is lined up below the above row.

but, just like using a word processor, we can DUMP ALL of our convoluted code to show in those blanks (a white image right now), and have the "div" center the content for us.

So our div WILL DO the work of adding all those extra blanks - we just output balls

our div now becomes this:

        <div id="mydiv" runat="server" style="text-align:center">
        </div>

So, our code now becomes quite simple.

   Dim Blank As String = GetFileAsPicture("W.jpg") ' white sqaure block
    Dim Border As String = GetFileAsPicture("r2.jpg") ' round ball 

    For i = 1 To NumRows

        For j = 1 To j   1
            OutPut(Border)
        Next
        OutPut("<br/>")  ' start a new line

    Next

And we now get this: (it is SAME as before - but without the center code!!!)

enter image description here

However, we not fixed font or fixed size like a green console anymore, are we?

So, we don't care about half spacing. So, our code can now just add ONE more ball per row - it will STILL center.

So, we now have this:

    Dim Blank As String = GetFileAsPicture("W.jpg") ' white sqaure block
    Dim Border As String = GetFileAsPicture("r2.jpg") ' round ball 

    For i = 1 To NumRows

        For j = 1 To i
            OutPut(Border)
        Next
        OutPut("<br/>")  ' start a new line

    Next

And now we get this:

enter image description here

So, just like using a word processor - center text, and we NOT limited to a fixed width like say a console or green screen.

So, we say please center. And the balls are fixed width (each of them), but when we say please center the context in the "div", then the browser does that for us - and that even means half spacing, or in fact as much as required.

So, we don't even have to line up the balls on top of each other (like we do with fixed text and green screen console).

So, the code now I have is thus this:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Dim i, j As Integer

    Dim NumRows As Integer = TextBox1.Text

    Dim Border As String = GetFileAsPicture("r2.jpg") ' round ball 

    For i = 1 To NumRows

        For j = 1 To i
            OutPut(Border)
        Next
        OutPut("<br/>")  ' start a new line

    Next

End Sub

Sub OutPut(s As String)

    Me.mydiv.InnerHtml &= s

End Sub

Function GetFileAsPicture(sFile As String) As String

    ' get a picture from our Content folder, 
    ' return as picture HTML "image" mark-up

    Return "<img src=""" & "../Content/" & sFile & """ />"

End Function

So, use the windows snip utility, and just grab one of my balls from above, and use that.

  • Related