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
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:
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:
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!!!)
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:
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.