Golang: int to slice conversion - indexing

Total golang (and programming) noob!
Given any six digit number, how could one output a slice where each character of that number is assigned an individual location within the slice?
For instance, a slice (let's call it s) containing all of these characters, would have s[0]=first digit, s[1]=second digit, s[2]=third digit and so on.
Any help would be greatly appreciated!

func IntToSlice(n int64, sequence []int64) []int64 {
if n != 0 {
i := n % 10
// sequence = append(sequence, i) // reverse order output
sequence = append([]int64{i}, sequence...)
return IntToSlice(n/10, sequence)
}
return sequence
}

The above answers are correct. Here comes another version of MBB's answer.
Avoiding recursion and efficient reverting may increase performance and reduce RAM consumption.
package main
import (
"fmt"
)
func reverseInt(s []int) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}
func splitToDigits(n int) []int{
var ret []int
for n !=0 {
ret = append(ret, n % 10)
n /= 10
}
reverseInt(ret)
return ret
}
func main() {
for _, n := range splitToDigits(12345) {
fmt.Println(n)
}
}
https://play.golang.org/p/M3aOUnNIbdv

This is a two step process, first converting int to string, then iterating the string or converting to a slice. Because the built in range function lets you iterate each character in a string, I recommend keeping it as a string. Something like this;
import "strconv"
str := strconv.Itoa(123456)
for i, v := range str {
fmt.Println(v) //prints each char's ASCII value on a newline
fmt.Printf("%c\n", v) // prints the character value
}

I'm confused why nobody mentioned this way:
(No need recursion)
import (
"fmt"
"strconv"
)
func main() {
n := 3456
fmt.Println(NumToArray(n))
fmt.Println(NumToArray2(n))
}
func NumToArray(num int) []int {
arr := make([]int, len(strconv.Itoa(num)))
for i := len(arr) - 1; num > 0; i-- {
arr[i] = num % 10
num = int(num / 10)
}
fmt.Println(arr)
return arr
}
// Without converting to string
func NumToArray2(num int) (arr []int) {
for num > 0 {
arr = append(arr, num%10)
num = int(num / 10)
}
// Reverse array to the rigtht order
for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 {
arr[i], arr[j] = arr[j], arr[i]
}
fmt.Println(arr)
return arr
}
P.S. Benchmarks are welcome

For this problem you can convert your int value to string and after that you can use split function which is under strings library.I hope below code will work for you!
package main
import (
"fmt"
"strings"
"strconv"
)
func main() {
num:=10101
a:=strconv.Itoa(num)
res:=strings.Split(a,"")
fmt.Println("The value of res is",res)
fmt.Printf("The type of res is %T\n",res)
fmt.Println(res[0])
}
Output: The value of res is [1 0 1 0 1]
The type of res is []string 1

Related

Kotlin decomposing numbers into powers of 2

Hi I am writing an app in kotlin and need to decompose a number into powers of 2.
I have already done this in c#, PHP and swift but kotlin works differently somehow.
having researched this I believe it is something to do with the numbers in my code going negative somewhere and that the solution lies in declaring one or more of the variable as "Long" to prevent this from happening but i have not been able to figure out how to do this.
here is my code:
var salads = StringBuilder()
var value = 127
var j=0
while (j < 256) {
var mask = 1 shl j
if(value != 0 && mask != 0) {
salads.append(mask)
salads.append(",")
}
j += 1
}
// salads = (salads.dropLast()) // removes the final ","
println("Salads = $salads")
This shoud output the following:
1,2,4,8,16,32,64
What I actually get is:
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,
Any ideas?
This works for the one input that you specified, at the very least:
fun powersOfTwo(value :Long): String {
val result = ArrayList<String>()
var i = 0
var lastMask = 0
while (lastMask < value) {
val mask = 1 shl i
if (value != 0.toLong() && mask < value) {
result.add(mask.toString())
}
lastMask = mask
i += 1
}
return result.joinToString(",")
}
Ran it in a unit test:
#Test
fun addition_isCorrect() {
val result = powersOfTwo(127)
assertEquals("1,2,4,8,16,32,64", result)
}
Test passed.
You can get a list of all powers of two that fit in Int and test each of them for whether the value contains it with the infix function and:
val value = 126
val powersOfTwo = (0 until Int.SIZE_BITS).map { n -> 1 shl n }
println(powersOfTwo.filter { p -> value and p != 0}.joinToString(","))
// prints: 2,4,8,16,32,64
See the entire code in Kotlin playground: https://pl.kotl.in/f4CZtmCyI
Hi I finally managed to get this working properly:
fun decomposeByTwo(value :Int): String {
val result = ArrayList<String>()
var value = value
var j = 0
while (j < 256) {
var mask = 1 shl j
if ((value and mask) != 0) {
value -= mask
result.add(mask.toString())
}
j += 1
}
return result.toString()
}
I hope this helps someone trying to get a handle on bitwise options!
Somehow you want to do the "bitwise AND" of "value" and "mask" to determine if the j-th bit of "value" is set. I think you just forgot that test in your kotlin implementation.

Appending a pointer to a Slice in Golang

I want to append a pointer to a slice.Is it possible..?In Partentnode.children is a slice I want to append it with X as pointer.
https://play.golang.org/p/ghWtxWGOAU
func Tree(Parentnode *Node) {
if IsvisitedNode(Parentnode.currentvalue - 1) {
m := MovesArray[Parentnode.currentvalue-1]
for j := 0; j < 8; j++ {
if m[j] != 0 {
var X *Node
X.parentnode = Parentnode
X.currentvalue = m[j]
if IsvisitedNode(m[j]) {
Parentnode.children = append(Parentnode.children, *X)
Tree(X)
}
}
}
}
}
You have a off by one error.
In main you set Y.currentvalue = 1.
Then in Tree currentvalue walks to 64.
X.currentvalue = m[j]
fmt.Printf("cv: %v\n",X.currentvalue) //walks to 64
if IsvisitedNode(m[j]) {
An in IsvisitedNode you test that index against visithistory that has 64 indexes, thus stops at index 63. -> index error
var visithistory [64]bool
func IsvisitedNode(position int) bool {
if visithistory[position] == true {
Things work if you set var visithistory [65]bool but I think you need to rethink you logic here somewhat.

In Go, scan numbers from a line using recursion

I want to scan a line of integers from stdin into a slice of integers. Each integer is separated by whitespace. Ther would be as many as N integers of user input. I'm trying not to use a for loop. For example,
1 15 16 17
So far, this is my function to perform the task,
var array []int
func read(b int) {
if b == 0 {
return
}
fmt.Scanf("%d", &array)
read(b - 1)
}
The idea is to read from the input, 1 15 16 17, and make it into a slice with value [1 15 16 17]
After compiling, I got the error,
Runtime error
For example,
package main
import "fmt"
var a []int
func read(b int) {
if b == 0 {
return
}
var i int
_, err := fmt.Scanf("%d", &i)
if err != nil {
return
}
a = append(a, i)
read(b - 1)
}
func main() {
read(4)
fmt.Println(a)
}
Input:
1 15 16 17<Enter>
Output:
[1 15 16 17]
Not recursive, but just reading integers until stdin is closed or something that can't be converted to an integer is read.
package main
import "fmt"
func main() {
var array []int
var i int
for {
_, err := fmt.Scan(&i)
if err != nil {
break
}
array = append(array, i)
fmt.Println("read number", i, "from stdin, array ", array)
}
}

Reverse int golang

How to change 12345 to 54321?
With a string, you can change the string to a rune, and reverse it, but you cannot do the same for an integer. I have searched and found no one talking about this. Examples
131415 >>> 514131
1357 >>> 7531
123a >>> ERROR
-EDIT-
I was thinking, why not create a slice and index that?
Then I realized that you can't index int
(http://play.golang.org/p/SUSg04tZsc)
MY NEW QUESTION IS
How do you index an int?
OR
How do you reverse a int?
Here is a solution that does not use indexing an int
package main
import (
"fmt"
)
func reverse_int(n int) int {
new_int := 0
for n > 0 {
remainder := n % 10
new_int *= 10
new_int += remainder
n /= 10
}
return new_int
}
func main() {
fmt.Println(reverse_int(123456))
fmt.Println(reverse_int(100))
fmt.Println(reverse_int(1001))
fmt.Println(reverse_int(131415))
fmt.Println(reverse_int(1357))
}
Result:
654321
1
1001
514131
7531
Go playground
I converted the integer to a string, reverse the string, and convert the result back to a string.
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(reverse_int(123456))
fmt.Println(reverse_int(100))
fmt.Println(reverse_int(1001))
fmt.Println(reverse_int(131415))
fmt.Println(reverse_int(1357))
}
func reverse_int(value int) int {
intString := strconv.Itoa(value)
newString := ""
for x := len(intString); x > 0; x-- {
newString += string(intString[x - 1])
}
newInt, err := strconv.Atoi(newString)
if(err != nil){
fmt.Println("Error converting string to int")
}
return newInt
}
Very similar to the first answer but this checks to make sure you don't go out of bounds on the type.
func reverse(x int) int {
rev := 0
for x != 0 {
pop := x % 10
x /= 10
if rev > math.MaxInt32/10 || (rev == math.MaxInt32 /10 && pop > 7) {
return 0
}
if rev < math.MinInt32/10 || (rev == math.MinInt32/10 && pop < -8) {
return 0
}
rev = rev * 10 + pop
}
return rev
}
Also flips negative numbers int
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}
func reverse_int(n int) int {
newInt := 0
sign := 1
if n < 0 {
sign = -1
}
n = Abs(n)
for n > 0 {
remainder := n % 10
newInt = newInt*10 + remainder
n /= 10
}
return newInt * sign
}
func main() {
fmt.Println(reverse_int(-100))
fmt.Println(reverse_int(-1001))
fmt.Println(reverse_int(131415))
fmt.Println(reverse_int(1357))
}
Similar to Fokiruna's answer but also checks for a 32bit overflow
func reverse(x int) int {
result, sign := 0, 1
if(x < 0) {
sign = -1
x = -x
}
for x > 0 {
remainder := x % 10;
result = result * 10 + remainder
x = x/10
}
var checkInt int = int(int32(result))
if checkInt != result {
return 0
}
return result * sign
}

How to write tests against user input in Go

How would I test against user input from fmt.Scan/Scanf/Scanln?
For example how could I test that the function input will accept "4 5\n" and "1 2 3 4\n" from STDIN and return n == 5 and array == [1, 2, 3, 4].
package main
import (
"fmt"
)
// input gets an array from the user.
func input() (m int, array []int) {
fmt.Print("Enter the size of the array, n, and the difference, m: ")
var n int
_, err := fmt.Scanf("%d %d", &n, &m)
if err != nil {
panic(err)
}
fmt.Print("Enter the array as a space seperated string: ")
array = make([]int, n)
for i := 0; i < n; i++ {
_, _ = fmt.Scan(&array[i])
}
return m, array
}
func main() {
m, array := input()
fmt.Println(m, array)
}
Here's a very rough draft to illustrate the principle.
program.go
package main
import (
"fmt"
"os"
)
// input gets an array from the user.
func input(in *os.File) (m int, array []int) {
if in == nil {
in = os.Stdin
}
fmt.Print("Enter the size of the array, n, and the difference, m: ")
var n int
_, err := fmt.Fscanf(in, "%d %d", &n, &m)
if err != nil {
panic(err)
}
fmt.Print("Enter the array as a space seperated string: ")
array = make([]int, n)
for i := 0; i < n; i++ {
_, _ = fmt.Fscan(in, &array[i])
}
return m, array
}
func main() {
m, array := input(nil)
fmt.Println(m, array)
}
program_test.go
package main
import (
"fmt"
"io"
"io/ioutil"
"os"
"testing"
)
func TestInput(t *testing.T) {
var (
n, m int
array []int
)
in, err := ioutil.TempFile("", "")
if err != nil {
t.Fatal(err)
}
defer in.Close()
_, err = io.WriteString(in, "4 5\n"+"1 2 3 4\n")
if err != nil {
t.Fatal(err)
}
_, err = in.Seek(0, os.SEEK_SET)
if err != nil {
t.Fatal(err)
}
n, array = input(in)
if n != 5 || fmt.Sprintf("%v", array) != fmt.Sprintf("%v", []int{1, 2, 3, 4}) {
t.Error("unexpected results:", n, m, array)
}
}
Output:
$ go test
ok command-line-arguments 0.010s
You can't. At least not so easily, such that, it would be worth the effort.