user10005853
user10005853

Reputation:

Sum of squares in an array using recursion in golang

So my friend gave me this task where the sum of squares of positive numbers must be calculated using recursion.
Conditions - The input will be a string with space separated numbers
This is what I've come so far but this shows a runtime error.

Here is the full error https://ideone.com/53oOjN

package main
import(
    'fmt',
    'strings',
    'strconv'
)
var n int = 4
var sum_of_squares int = 0
func sumOfSquares(strArray []string, iterate int) int{
    number, _ := strconv.Atoi(strArray[iterate])
    if number > 0 {
        sum_of_squares += number*number
    }
    if iterate == n {
        return 0 // just to end the recursion
    }
    return sumOfSquares(strArray, iterate+1)
}
func main() {
    str := "1 2 3 4"
    strArray := strings.Fields(str)
    result := sumOfSquares(strArray, 0)
    fmt.Println(sum_of_squares, result)
}

Upvotes: 2

Views: 2352

Answers (3)

STEEL
STEEL

Reputation: 10107

I like to keep it simple. I have some few if conditions as well, but hope you like it.

func sumOfSquares(numArr []string) int {
    i, err := strconv.Atoi(numArr[0])

    rest := numArr[1:]

    //Error checking
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
        return 0
    }

    square := i * i

    // negative & last number
    if i < 0 && len(rest) == 0 {
        return square
    }

    // negative & not last number
    if i < 0 && len(rest) > 0 {
        return sumOfSquares(rest)
    }

    // last man standing
    if i >= 0 && len(rest) == 0 {
        return square
    }

    return square + sumOfSquares(rest)

}

DEMO : https://play.golang.org/p/WWYxKbvzanJ

Upvotes: 0

nilsocket
nilsocket

Reputation: 1571

package main

import (
    "fmt"
    "strconv"
    "strings"
)

var n int

func sumOfSquares(strArray []string, iterate int) int {
    number, _ := strconv.Atoi(strArray[iterate])
    if iterate == n {
        return number * number
    }
    return ((number * number) + sumOfSquares(strArray, iterate+1))
}

func main() {
    str := "1 2 3 4"
    strArray := strings.Fields(str)
    n = len(strArray) - 1
    result := sumOfSquares(strArray, 0)
    fmt.Println(result)
}

Indexing starts from 0, so decrease the length by one.

As @peterSO have pointed out, if strings contain unusual characters, it doesn't work, I didn't post the right answer for getting input because you seem to be beginner, but you can read the input, like this instead.

var inp []byte
var loc int

inp, _ = ioutil.ReadFile(fileName)
//add \n so that we don't end up running out of bounds,
//if last byte is integer.
inp = append(inp, '\n')


func scanInt() (res int) {
    if loc < len(inp) {
        for ; inp[loc] < 48 || inp[loc] > 57; loc++ {
        }
        for ; inp[loc] > 47 && inp[loc] < 58; loc++ {
            res = res<<3 + res<<1 + (int(inp[loc]) - 48)
        }
    }
    return
}

This is faster and scans integers only, and skips all other unusual characters.

Upvotes: 0

Rudziankoŭ
Rudziankoŭ

Reputation: 11251

The rule of thumb in recursion is termination condition. It should exist and it should exist in the right place.

func sumOfSquares(strArray []string, iterate int) int{
    if iterate >= len(strArray) { 
        return sum_of_squares
    }
    number, _ := strconv.Atoi(strArray[iterate]) //TODO: handle err here
    sum_of_squares += number*number

    return sumOfSquares(strArray, iterate+1)
}

Just for you information: canonical recursion should not save it's state into global fields. I would suggest using following function signature.

func sumOfSquares(strArray []string, iterate, currentSum int) int{
    //...    
    return sumOfSquares(strArray, iterate+1, sum_of_squares)
}

So that you don't need to store sum_of_squares somewhere. You will just pass it to next function invocation.

Upvotes: 1

Related Questions