How to apply a function to an input of integers in Golang - go

For example, if the input was this
1 3 4 5
all separated by a space, I want to apply the function of squaring each individual number then adding it.
I just don't know how to apply the function to each number. All I can figure is that I have to put the numbers into a slice then apply the function to each of the numbers. I have looked everywhere and can't find out how to do this.
in Python I just do it like this and I already put the values into a list called "n".
#The list is pasted from the initial puzzle
n=[10, 10, 9, 8, 10, 10, 10]
# The list is first squared
b = (list(map(lambda x:x**2,n)))
b becomes the new list where the function is done to each number.

You can do it like this if your integers are actually a string separated by spaces.
package main
import "fmt"
import "strings"
import "strconv"
func main() {
numbers := "1 3 4 5"
var n []int
for _, v := range strings.Fields(numbers) {
i, err := strconv.Atoi(v)
if err != nil {
fmt.Println(err.Error())
break
}
n = append(n, i*i)
}
fmt.Println(n)
}
https://play.golang.org/p/JcivNd29Gzg

package main
import (
"strconv"
"fmt"
"strings"
)
func main() {
stringwithnumbers := "1 2 3 4 5"
numberarray := strings.Split(stringwithnumbers, " ")
stringwithnumbers = ""
for _, number := range numberarray {
numbernew,err := strconv.Atoi(number)
if err != nil{
return
}
numbernew = numbernew * 2
stringwithnumbers += strconv.Itoa(numbernew)
stringwithnumbers += " "
}
stringwithnumbers = strings.Trim(stringwithnumbers, " ")
//You can check the result...
fmt.Print(stringwithnumbers)
}
You can check the code and your changes here:
https://play.golang.org/

Related

How to get the digits of int value in Golang

How can we get the digits of num := 658943 in Golang? I need to print each digit value from the given number (num) as integer instead of string.
package main
import "fmt"
func main() {
var (
num = 68932
digits []int
)
// do something with num, insert the result to digits
for _, val := range digits {
fmt.Println(val)
}
}
// expected output
// 6
// 8
// 9
// 3
// 2
You can use strconv
package main
import (
"fmt"
"strconv"
)
func main() {
var (
num = 68932
digits []int
)
s := strconv.Itoa(num)
for _, n := range s {
digits = append(digits, int(n-'0'))
}
for _, val := range digits {
fmt.Println(val)
}
}
https://go.dev/play/p/AHzwHPd7GJC

Infinite loop in Go

I want to have the "for loop" to loop 3 times or until the user inputs something other than an integer. Below is my code, although this runs an infinite amount of times and prints out the first value the user enters.
package main
import "fmt"
import "bufio"
import "strconv"
import "os"
import "sort"
func main(){
emptySlice := make([]int, 3) // Capacity of 3
fmt.Println(cap(emptySlice))
scanner := bufio.NewScanner(os.Stdin) // Creating scanner object
fmt.Printf("Please enter a number: ")
scanner.Scan() // Will always scan in a string regardless if its a number
for i := 0; i < cap(emptySlice); i++ { // Should this not run 3 times?
input, err := strconv.ParseInt(scanner.Text(), 10, 16)
if err != nil{
fmt.Println("Not a valid entry! Ending program")
break
}
emptySlice = append(emptySlice, int(input)) // adds input to the slice
sort.Ints(emptySlice) // sorts the slice
fmt.Println(emptySlice) // Prints the slice
}
}
I think there are a couple of minor bugs, but this version should work correctly:
package main
import "fmt"
import "bufio"
import "strconv"
import "os"
import "sort"
func main() {
emptySlice := make([]int, 3) // Capacity of 3
fmt.Println(cap(emptySlice))
scanner := bufio.NewScanner(os.Stdin) // Creating scanner object
for i := 0; i < cap(emptySlice); i++ { // Should this not run 3 times?
fmt.Printf("Please enter a number: ")
scanner.Scan() // Will always scan in a string regardless if its a number
input, err := strconv.ParseInt(scanner.Text(), 10, 16)
if err != nil {
fmt.Println("Not a valid entry! Ending program")
break
}
// emptySlice = append(emptySlice, int(input)) // adds input to the slice
emptySlice[i] = int(input)
}
sort.Ints(emptySlice) // sorts the slice
fmt.Println(emptySlice) // Prints the slice
}
I've moved the prompt into the loop, and I've replaced the append call with a direct assignment to the previously allocated slice entries. Otherwise calling append will just increase the size of the slice.
I've moved the sort and the print outside of the loop, as these seemed to be incorrectly placed too.
The program in the question starts with cap(emptySlice) == 3. Given that each complete iteration of the loop appends a new value to empty slice, we know that cap(emptySlice) >= 3 + i. It follows that the loop does not terminate.
My homework assignment is slightly different: Read up to three integers and print them in sorted order. Here's how I did it:
func main() {
var result []int
scanner := bufio.NewScanner(os.Stdin)
for i := 0; i < 3; i++ {
fmt.Printf("Please enter a number: ")
if !scanner.Scan() {
// Exit on EOF or other errors.
break
}
n, err := strconv.Atoi(scanner.Text())
if err != nil {
// Exit on bad input.
fmt.Println(err)
break
}
result = append(result, n)
}
sort.Ints(result)
fmt.Println(result)
}

How to read inputs recursively in golang

In the following code after one recursion the inputs are not read(from stdin). Output is incorrect if N is greater than 1.
X is read as 0 after one recursive call and hence the array is not read after that.
Program is supposed to print sum of squares of positive numbers in the array. P.S has to done only using recursion
package main
// Imports
import (
"fmt"
"bufio"
"os"
"strings"
"strconv"
)
// Global Variables
var N int = 0;
var X int = 0;
var err error;
var out int = 0;
var T string = "0"; // All set to 0 just in case there is no input, so we don't crash with nil values.
func main() {
// Let's grab our input.
fmt.Print("Enter N: ")
fmt.Scanln(&N)
// Make our own recursion.
loop()
}
func loop() {
if N == 0 {return}
// Grab our array length.
fmt.Scanln(&X)
tNum := make([]string, X)
// Grab our values and put them into an array.
in := bufio.NewReader(os.Stdin)
T, err = in.ReadString('\n')
tNum = strings.Fields(T)
// Parse the numbers, square, and add.
add(tNum)
// Output and reset.
fmt.Print(out)
out = 0;
N--
loop()
}
// Another loop, until X is 0.
func add(tNum []string) {
if X == 0 {return}
// Parse a string to an integer.
i, err := strconv.Atoi(tNum[X-1])
if err != nil {}
// If a number is negative, make it 0, so when we add its' square, it does nothing.
if (i < 0) {
i = 0;
}
// Add to our total!
out = out + i*i
X--
add(tNum)
}
Input:
2
4
2 4 6 8
3
1 3 9
Output:
1200
Expected output:
120
91
bufio.Reader, like the name suggests, use a buffer to store what is in the reader (os.Stdin here), which means, each time you create a bufio.Reader and read it once, there are more than what is read stored into the buffer, and thus the next time you read from the reader (os.Stdin), you do not read from where you left.
You should only have one bufio.Reader for os.Stdin. Make it global (if that is a requirement) or make it an argument. In fact, bufio package has a Scanner type that can splits spaces and new lines so you don't need to call strings.Fields.
I think you should practise doing this yourself, but here is a playground link: https://play.golang.org/p/7zBDYwqWEZ0
Here is an example that illustrates the general principles.
// Print the sum of the squares of positive numbers in the input.
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
)
func sumOfSquares(sum int, s *bufio.Scanner, err error) (int, *bufio.Scanner, error) {
if err != nil {
return sum, s, err
}
if !s.Scan() {
err = s.Err()
if err == nil {
err = io.EOF
}
return sum, s, err
}
for _, f := range strings.Fields(s.Text()) {
i, err := strconv.Atoi(f)
if err != nil || i <= 0 {
continue
}
sum += i * i
}
return sumOfSquares(sum, s, nil)
}
func main() {
sum := 0
s := bufio.NewScanner(os.Stdin)
sum, s, err := sumOfSquares(sum, s, nil)
if err != nil && err != io.EOF {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Println(sum)
}
Input:
2
4
2 4 6 8
3
1 3 9
Output:
240

Why the array resulted from the stdin in Golang convert the last item to zero?

Note: I am new to StackOverflow as well as to Programming, so if my question is not "so professional" or "well formatted", please forgive me.
I am using the following Go (Golang) code to capture some space-separated numbers (string) from terminal, then split it into a slice. Later I'm converting this slice to a slice of float64 by getting one item at a time from the strings-slice and converting it to float64 and appending it to the float64-slice.
Then I'm returning the resulting float64 slice and printing it in the main function.
The problem is when I pass some space-separated digits to the terminal, the last digit is converted to zero.
for example if I pass 1 2 3 4 5 I expect the resulting slice as [1 2 3 4 5], but it gives me the slice as [1 2 3 4 0].
I'm trying from the last 5 hours, but I'm not able to find what I'm missing or messing.
code:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
a := ReadInput()
fmt.Println(a)
}
func ReadInput() []float64 {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
textSlice := strings.Split(text, " ")
floatsSlice := make([]float64, 0)
for _, elem := range textSlice {
i, _ := strconv.ParseFloat(elem, 64)
floatsSlice = append(floatsSlice, i)
}
return floatsSlice
}
Thank You in advance!
ReadString reads until the first occurrence of delim in the input,
returning a string containing the data up to and including the
delimiter.
so, strings.Split(text, " ") not splits last \n character so:
you may use strings.Fields(text) instead of strings.Split(text, " ")
and always check for errors:
like this working sample code:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
a := ReadInput()
fmt.Println(a)
}
func ReadInput() []float64 {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println(err)
}
textSlice := strings.Fields(text)
floatsSlice := make([]float64, 0)
for _, elem := range textSlice {
i, err := strconv.ParseFloat(elem, 64)
if err != nil {
fmt.Println(err)
}
floatsSlice = append(floatsSlice, i)
}
return floatsSlice
}

How to use fmt.Sscan to parse integers into an array?

I'm trying to scan a list of integers from a string into an array (or alternatively, a slice)
package main
import "fmt"
func main() {
var nums [5]int
n, _ := fmt.Sscan("1 2 3 4 5", &nums) // doesn't work
fmt.Println(nums)
}
What do I need to pass as second argument to Sscan in order for this to work?
I know I could pass nums[0], nums[1] ... etc., but I'd prefer a single argument.
I don't think this is possible as a convenient one-liner. As Sscan takes ...interface{}, you would need to pass slice of interfaces as well, hence converting your array first:
func main() {
var nums [5]int
// Convert to interfaces
xnums := make([]interface{}, len(nums))
for n := range nums {
xnums[n] = &nums[n]
}
n, err := fmt.Sscan("1 2 3 4 5", xnums...)
if err != nil {
fmt.Printf("field %d: %s\n", n+1, err)
}
fmt.Println(nums)
}
http://play.golang.org/p/1X28J7JJwl
Obviously you could mix different types in your interface array, so it would make the scanning of more complex string easier. For simply space-limited integers, you might be better using strings.Split or bufio.Scanner along with strconv.Atoi.
To allow this to work on more than just hard-coded strings, it's probably better to use a bufio.Scanner, and an io.Reader interface to do this:
package main
import (
"bufio"
"fmt"
"io"
"strconv"
"strings"
)
func scanInts(r io.Reader) ([]int, error) {
s := bufio.NewScanner(r)
s.Split(bufio.ScanWords)
var ints []int
for s.Scan() {
i, err := strconv.Atoi(s.Text())
if err != nil {
return ints, err
}
ints = append(ints, i)
}
return ints, s.Err()
}
func main() {
input := "1 2 3 4 5"
ints, err := scanInts(strings.NewReader(input))
if err != nil {
fmt.Println(err)
}
fmt.Println(ints)
}
Produces:
[1 2 3 4 5]
Playground
Unless you're trying to use Sscann specifically you can also try this as an alternative:
split the input string by spaces
iterate the resulting array
convert each string into an int
store the resulting value into an int slice
Like this:
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
nums := make([]int, 0)
for _, s := range strings.Split("1 2 3 4 5", " ") {
i, e := strconv.Atoi(s)
if e != nil {
i = 0 // that was not a number, default to 0
}
nums = append(nums, i)
}
fmt.Println(nums)
}
http://play.golang.org/p/rCZl46Ixd4

Resources