Printing the given pattern of characters using for loops? - for-loop

I'm doing an exercise on Go that asks me to print a letter like this
G
GG
GGG
GGGG
GGGGG
for 25 different lines, and adding one more letter each time.
I'm asked to solve it one time using only one for loop, and then again but with two for loops. I already solved both, but even though my code using two for loops works gives the right output, I think it's weird and not ok:
func manyG2() {
var counter string
for i := 0; i <= 24; i++ {
for x := 0; x == 0; x++ {
counter += "G"
fmt.Println(counter)
}
}
}
How other way can I write it with two for loops?

Here is the another way to do it, instead of concatenating every time to the string ...
func manyG2() {
for i := 0; i < 25; i++ {
for j := 0; j <= i; j++ { // num of Gs are equal to the row no.
fmt.Print("G")
}
fmt.Println()
}
}

Related

Why is accessing a variable so much slower than accessing len()?

I wrote this function uniq that takes in a sorted slice of ints
and returns the slice with duplicates removed:
func uniq(x []int) []int {
i := 0
for i < len(x)-1 {
if x[i] == x[i+1] {
copy(x[i:], x[i+1:])
x = x[:len(x)-1]
} else {
i++
}
}
return x
}
and uniq2, a rewrite of uniq with the same results:
func uniq2(x []int) []int {
i := 0
l := len(x)
for i < l-1 {
if x[i] == x[i+1] {
copy(x[i:], x[i+1:])
l--
} else {
i++
}
}
return x[:l]
}
The only difference between the two functions
is that in uniq2, instead of slicing x
and directly accessing len(x) each time,
I save len(x) to a variable l
and decrement it whenever I shift the slice.
I thought that uniq2 would be slightly faster than uniq
because len(x) would no longer be called iteration,
but in reality, it is inexplicably much slower.
With this test that generates a random sorted slice
and calls uniq/uniq2 on it 1000 times,
which I run on Linux:
func main() {
rand.Seed(time.Now().Unix())
for i := 0; i < 1000; i++ {
_ = uniq(genSlice())
//_ = uniq2(genSlice())
}
}
func genSlice() []int {
x := make([]int, 0, 1000)
for num := 1; num <= 10; num++ {
amount := rand.Intn(1000)
for i := 0; i < amount; i++ {
x = append(x, num)
}
}
return x
}
$ go build uniq.go
$ time ./uniq
uniq usually takes 5--6 seconds to finish.
while uniq2 is more than two times slower,
taking between 12--15 seconds.
Why is uniq2, where I save the slice length to a variable,
so much slower than uniq, where I directly call len?
Shouldn't it slightly faster?
You expect roughly the same execution time because you think they do roughly the same thing.
The only difference between the two functions is that in uniq2, instead of slicing x and directly accessing len(x) each time, I save len(x) to a variable l and decrement it whenever I shift the slice.
This is wrong.
The first version does:
copy(x[i:], x[i+1:])
x = x[:len(x)-1]
And second does:
copy(x[i:], x[i+1:])
l--
The first difference is that the first assigns (copies) a slice header which is a reflect.SliceHeader value, being 3 integer (24 bytes on 64-bit architecture), while l-- does a simple decrement, it's much faster.
But the main difference does not stem from this. The main difference is that since the first version changes the x slice (the header, the length included), you end up copying less and less elements, while the second version does not change x and always copies to the end of the slice. x[i+1:] is equivalent to x[x+1:len(x)].
To demonstrate, imagine you pass a slice with length=10 and having all equal elements. The first version will copy 9 elements first, then 8, then 7 etc. The second version will copy 9 elements first, then 9 again, then 9 again etc.
Let's modify your functions to count the number of copied elements:
func uniq(x []int) []int {
count := 0
i := 0
for i < len(x)-1 {
if x[i] == x[i+1] {
count += copy(x[i:], x[i+1:])
x = x[:len(x)-1]
} else {
i++
}
}
fmt.Println("uniq copied", count, "elements")
return x
}
func uniq2(x []int) []int {
count := 0
i := 0
l := len(x)
for i < l-1 {
if x[i] == x[i+1] {
count += copy(x[i:], x[i+1:])
l--
} else {
i++
}
}
fmt.Println("uniq2 copied", count, "elements")
return x[:l]
}
Testing it:
uniq(make([]int, 1000))
uniq2(make([]int, 1000))
Output is:
uniq copied 499500 elements
uniq2 copied 998001 elements
uniq2() copies twice as many elements!
If we test it with a random slice:
uniq(genSlice())
uniq2(genSlice())
Output is:
uniq copied 7956671 elements
uniq2 copied 11900262 elements
Again, uniq2() copies roughly 1.5 times more elements! (But this greatly depends on the random numbers.)
Try the examples on the Go Playground.
The "fix" is to modify uniq2() to copy until l:
copy(x[i:], x[i+1:l])
l--
With this "appropriate" change, performance is roughly the same.

Out of bounds when appending in Go slice

In some cases when i == len(SliceA) i get a slice out of bounds error.
//filterIntersection removes points from two slices that have common points.
func filterIntersection(sliceA, sliceB *[]ds.Coord) {
for i, a := range *sliceA {
for j, b := range *sliceB {
if a == b {
(*sliceA) = append((*sliceA)[:i], (*sliceA)[i+1:]...) <--- error here
(*sliceB) = append((*sliceB)[:j], (*sliceB)[j+1:]...)
}
}
}
}
Well if i == len(SliceA), then sliceA[i+1] is out of bounds! It is not "in some cases" but in every case, and the same will happen for SliceB.
Consider breaking out of your loop if i == len(SliceA) or j == len(SliceB).
Another solution would be to use a "regular" for loop: for i := 0; i < len(SliceA); i++

hackerrank Circular Array Rotation Go Runtime Error

I did solved a hackerrank problem which is "Circular Array Rotation" using Go
when i run the code it gives me a correct response and when i try to submit the code all the test passes except one and it says Runtime Error
I tried the failing test localy and it passes
my code is
package main
import "fmt"
func CircularArrayRotation() {
var n, k, q int
fmt.Scanf("%d%d%d", &n, &k, &q)
a := make([]int, n)
for i := range a {
fmt.Scanf("%d", &a[i])
}
var i int
for t:=0; t<q; t++ {
fmt.Scanf("%d", &i)
j := (i - k)
if j<0 {
j+=n
}
fmt.Println(a[j])
}
}
func main() {
//Enter your code here. Read input from STDIN. Print output to STDOUT
CircularArrayRotation()
}
For those that want more information you can look here: https://www.hackerrank.com/challenges/circular-array-rotation/problem
The Input for his failing case is this and the Expected Output is this
Your run time error is this:
panic: runtime error: index out of range
goroutine 1 [running]: main.CircularArrayRotation() solution.go:22
+0x349 main.main() solution.go:29 +0x20
So your issue is on line 22, where your index is out of range: fmt.Println(a[j])
This happens because your code currently cannot handle multiple rotations, so in your code you end up executing the following:
fmt.Println(a[-99477])
This happens when i is 8 and k is 100000
Imagine you had this input:
n = 3
k = 10
q = 1
i = 2
When you perform i - k we get -8, we then try to add n which gives us -5 (-8 + 3), then we try to access an index that does not exist. a[-5]
If you wish to fix this issue you can do the below (inside spoiler in case you want to work this out yourself):
put this above your i - k
k = k % n
The reason this fixes your code is:
It works out how many rotations are left after we've fully looped x times. That way we don't have to worry about multiple rotations.
--
As a side note for this challenge there's some interesting stuff you can do with slices for rotating an array using some of the stuff covered here: https://tour.golang.org/moretypes/10
Most of your code is correct, however it fails because you only check if j < 0 once. After adding n to it is still negative, so it fails.
Running your code and printing the values when it fails gives:
n: 515, k:100000, q:500, j:-99477
The fix is simple, change your if to a for. This will keep adding n until your index is postive again.
Fixed:
package main
import "fmt"
func CircularArrayRotation() {
var n, k, q int
fmt.Scanf("%d%d%d", &n, &k, &q)
a := make([]int, n)
for i := range a {
fmt.Scanf("%d", &a[i])
}
var i int
for t := 0; t < q; t++ {
fmt.Scanf("%d", &i)
j := i - k
for j < 0 {
j += n
}
fmt.Println(a[j])
}
}
func main() {
//Enter your code here. Read input from STDIN. Print output to STDOUT
CircularArrayRotation()
}

For loop of two variables in Go

The following for loop in Go isn't allowed,
for i := 0, j := 1; i < 10; i++, j++ {...}
What's the correct equivalent of the for-loop of two variables below?
for (int i = 0, j = 1; i < 10; i ++ , j ++) {...}
You don't have a comma operator to join multiple statements, but you do have multiple assignment, so this works:
package main
import (
"fmt"
)
func main() {
for i, j := 0, 1; i < 10; i, j = i+1, j+1 {
fmt.Println("Hello, playground")
}
}
Although above Answer is accepted, and it fully satisfy the need. But I would like to contribute some further explanation to it.
Golang Does not support many things which could be done in simple terms. For loop is a most common example of this. The beauty of Go's For loop is that it merges many modern style of looping into one keyword.
Similarly Golang do with Multiple Variable declaration and assignment. According to above mentioned problem, We could solve multi-variable for loop with this simple tool which Golang provides us. If you want to look into further explanation, this question provide further details and way of declaring multiple variables in one statement.
Coming back to for loop, If we want to declare variable of same datatype we can declare them with this
var a,b,c string
but we use short hand in for loop so we can do this for initializing them with same value
i,j := 0,1
Different Datatypes and Different Values
and if we want to declare different type of variables and want to assign different values we can do this by separating variables names and after := different values by comma as well. for example
c,i,f,b := 'c',23423,21.3,false
Usage of Assignment Operator
Later on, we can assign values to multiple variables with the same approach.
x,y := 10.3, 2
x,y = x+10, y+1
Mixing Struct and Normal types in single statement
Even we can use struct types or pointers the same way. Here is a function to iterate Linked list which is defined as a struct
func (this *MyLinkedList) Get(index int) int {
for i,list := 0,this; list != nil; i,list = i+1,list.Next{
if(i==index){
return list.Val
}
}
return -1
}
This list is defined as
type MyLinkedList struct {
Val int
Next *MyLinkedList
}
Answering to Original Problem
Coming to the origin Question, Simply it could be done
for i, j := 0, 1; i < 10; i, j = i+1, j+1 {
fmt.Println("i,j",i,j)
}
Suppose you want to loop using two different starting index, you can do this way.
This is the example to check if string is palindrome or not.
name := "naman"
for i<len(name) && j>=0{
if string(name[i]) == string(name[j]){
i++
j--
continue
}
return false
}
return true
This way you can have different stopping conditions and conditions will not bloat in one line.
As pointed by Mr. Abdul, for iterate among two variable you can use the following construct:
var step int = 4
for row := 0; row < rowMax; row++ {
for col := 0; col < colMax; col++ {
for rIndex, cIndex := row, col; rIndex <= row+step && cIndex <= col; rIndex, cIndex = rIndex+1, cIndex+1 {
}
}
}

Index suddenly out of range in Go

I am trying to implement an algorithm to find all primes below a certain limit. However, when the limit reaches 46350 i suddenly get an out of range error message:
panic: runtime error: index out of range
goroutine 1 [running]:
main.main()
/tmpfs/gosandbox-433...fd004/prog.go:16 +0x1a8
Any help to point me to what is wrong here is appreciated (and were does this magic number 46350 come from?).
To reproduce drop the following code into googles sandbox and uncomment limit++ (or use this link):
package main
func main() {
limit := 46349
//limit++
sieved_numbers := make([]bool, limit)
var j = 0
var i = 2
for ; i < limit; i++ {
if !sieved_numbers[i] {
for j = i * i; j < limit;j += i {
sieved_numbers[j] = true
}
}
}
}
Because when i == 46349, j = i * i overflows and you're left with a negative number. The loop condition is still true, but it's outside the boundaries of the array, so you get a panic.
Add a fmt.Println(i, j) as the first statement in your nested loop, and run it on your local machine (it'll time out on the sandbox) and you'll see it happen.
i*i = 2148229801 when i==46349. A signed 32 bit integer can only reach ~2^31 (32 bits - 1 bit for the sign) before it becomes negative. Specifically, your variable would have taken on the value of (2^32)/2 - (46349^2) which is -746153.
If you'd like to perform this computation, try using an unsigned int or an int64.
package main
// import "fmt"
func main() {
var limit uint
limit = 46349
limit++
sieved_numbers := make([]bool, limit)
var j uint = 0
var i uint = 2
for ; i < limit; i++ {
if !sieved_numbers[i] {
for j = i * i; j < limit; j += i {
sieved_numbers[j] = true
}
}
}
}
Try it on the playground
i * i produces a number which is greater than the maxiumum size of a 32 bit signed integer.
You should use a larger data type for j.
Read about integers on Wikipedia

Resources