Where is the memory allocated for p - go

package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (rot *rot13Reader) Read(p []byte) (n int, err error) {
n, err = rot.r.Read(p) //<---- where allocated the mem for p?
for i := 0; i < len(p); i++ {
if p[i] >= 'A' && p[i] <= 'Z' {
p[i] = 65 + (p[i] - 65 + 13) % 26
} else if p[i] >= 'a' && p[i] <= 'z' {
p[i] = 97 + (p[i] - 97 + 13) % 26
}
}
return
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
This is an exercise from A tour of go. The code above can run properly, but I just don't understand where allocated the mem of p.

io.Copy will call the method Read() of the io.Reader, take a look to the implementation https://golang.org/src/io/io.go?s=12490:12550#L349 and if you keep reading just a few lines below you'll find the method copyBuffer() and inside you will see these lines:
if buf == nil {
buf = make([]byte, 32*1024)
}
for {
nr, er := src.Read(buf)
// ...more stuff

Related

A Tour of Go Exercise: rot13Reader, why is the reader called twice?

import (
"io"
"os"
"strings"
"fmt"
)
type rot13Reader struct {
r io.Reader
}
func (rot13 rot13Reader) Read(b []byte) (int, error){
n,err := rot13.r.Read(b)
fmt.Printf("\n%v %v\n",n, err)
const A byte ='A'
const a byte ='a'
for i,x := range b{
if x==0 {
n=i
break
}
switch {
case A<=x && x<a:
tmp := x-A
b[i] = A+((tmp+13)%26)
case a<=x && x<a+26 :
tmp := x-a
b[i] = a+((tmp+13)%26)
}
}
return n, err
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
The code above outputs
21 <nil>
You cracked the code!
0 EOF
Lbh penpxrq gur pbqr!
I have two questions :
Why is the reader being called twice (the second call returning 0 and EOF)
Why does on the second call, b is back to the original chiper? If it reads 0 character, shouldn't it still be "You cracked the code!"?

implementing bubble sort with go

Please help me implement bubble sort.It works fine if I call it with a hardcoded slice from the main() but if I call it with dynamic input from Scan it breaks
here is my code so far:
package main
import "fmt"
func main() {
fmt.Println("Enter a maximum of 10 numbers: ")
var inputs int
fmt.Scanln(&inputs)
inputSlice := make([]int, inputs)
BubbleSort(inputSlice)
fmt.Println(inputSlice)
}
func BubbleSort(input []int) {
for i := 0; i < len(input)-1; i++ {
for j := 0; j < len(input)-i-1; j++ {
Swap(input, j)
}
}
}
func Swap(input []int, j int) {
if input[j] > input[j+1] {
input[j], input[j+1] = input[j+1], input[j]
}
}
terminal:
coder:~/project$ go run bubblesort.go
Enter a maximum of 10 numbers:
12 24 54 65 11
coder:~/project$ 4 54 65 11
bash: 4: command not found
Do a little debugging by adding print lines in between your codes and see what's actually happening, you were just reading input the wrong way from command line
After Taking Reference from this link as posted above in comments by Steffen Ullrich
View In Go Playground
package main
import "fmt"
func main() {
fmt.Println(`Enter the number of integers`)
var n int
if m, err := Scan(&n); m != 1 {
panic(err)
}
fmt.Println(`Enter the integers`)
inputSlice := make([]int, n)
ReadN(inputSlice, 0, n)
//Your Input Printing Out
fmt.Println(inputSlice)
//Calling Function
BubbleSort(inputSlice)
//Output
fmt.Println(inputSlice)
}
func BubbleSort(input []int) {
for i := 0; i < len(input)-1; i++ {
for j := 0; j < len(input)-i-1; j++ {
Swap(input, j)
}
}
}
func Swap(input []int, j int) {
if input[j] > input[j+1] {
input[j], input[j+1] = input[j+1], input[j]
}
}
//Additional Functions
func ReadN(all []int, i, n int) {
if n == 0 {
return
}
if m, err := Scan(&all[i]); m != 1 {
panic(err)
}
ReadN(all, i+1, n-1)
}
func Scan(a *int) (int, error) {
return fmt.Scan(a)
}

Lychrel Numbers in Go with the big Library

I'm trying to make a Lychrel number program in Go, but I'm running into some trouble. Using the "math/big" library, and with some extra print statements for debugging, my code looks like this:
func reverse(n *big.Int) *big.Int {
var (
m = n
r = big.NewInt(0)
z = big.NewInt(0)
one = big.NewInt(1)
ten = big.NewInt(10)
)
for {
r.Mul(r, ten)
d := z
d.Mod(m, ten)
r.Add(r, d)
m.Div(m, ten)
if m.Cmp(one) == -1 {
return r
}
}
}
func radd(num *big.Int) *big.Int {
newNum := num
rnum := reverse(num)
newNum = newNum.Add(num, rnum)
fmt.Println(num, "+", rnum, "=", newNum)
return newNum
}
func lychrel(arg int) bool {
fmt.Println("Now testing", arg)
num := big.NewInt(int64(arg))
for i := 0; i < 50; i++ {
num = radd(num)
fmt.Println(i, ":", num)
if num.Cmp(reverse(num)) == 0 {
return false
}
}
return true
}
While the analogous code without the big library works fine (save for eventual overflow errors), this version doesn't. When I do lychrel(196), for example, I get
Now testing 196
691 + 691 = 691
0 : 691
0 + 0 = 0
1 : 0
I can't figure out where it goes wrong. I hope I'm not missing something dumb, because I've spent all morning trying to get this to work.
Package big
import "math/big"
func NewInt
func NewInt(x int64) *Int
NewInt allocates and returns a new Int set to x.
func (*Int) Set
func (z *Int) Set(x *Int) *Int
Set sets z to x and returns z.
You are assigning pointers, instead of values.
m = n
newNum := num
Assign values,
m = new(big.Int).Set(n)
newNum := new(big.Int).Set(num)
For example,
package main
import (
"fmt"
"math/big"
)
func reverse(n *big.Int) *big.Int {
var (
m = new(big.Int).Set(n)
r = big.NewInt(0)
z = big.NewInt(0)
one = big.NewInt(1)
ten = big.NewInt(10)
)
for {
r.Mul(r, ten)
d := z
d.Mod(m, ten)
r.Add(r, d)
m.Div(m, ten)
if m.Cmp(one) == -1 {
return r
}
}
}
func radd(num *big.Int) *big.Int {
newNum := new(big.Int).Set(num)
rnum := reverse(num)
newNum = newNum.Add(num, rnum)
fmt.Println(num, "+", rnum, "=", newNum)
return newNum
}
func lychrel(arg int) bool {
fmt.Println("Now testing", arg)
num := big.NewInt(int64(arg))
for i := 0; i < 50; i++ {
num = radd(num)
fmt.Println(i, ":", num)
if num.Cmp(reverse(num)) == 0 {
return false
}
}
return true
}
func main() {
lychrel(196)
}
Output:
Now testing 196
196 + 691 = 887
0 : 887
. . .

Parse number string digits

I am trying to calculate the multiplication result of a few digits which are part of a long digits string. Here is my code:
package main
import (
"fmt"
"strconv"
)
func main() {
inputNum := "73167176531330624919225119"
mult := getMult(3, inputNum)
fmt.Printf("Mult = %d", mult)
}
func getMult(startIndex int, inputNum string) int {
mult := 0
for i := 0; i < 10; i++ {
digit, err := strconv.Atoi(string(inputNum[startIndex+i]))
if err != nil {
mult *= int(digit)
} else {
fmt.Printf("Error converting %s to int : %s\n", string(inputNum[startIndex+i]), err.Error())
}
}
return mult
}
The result I want to get is 6*7*1*7*6*5*3*1*3*3 = 238140
But I an getting a runtime error:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x40130e]
goroutine 1 [running]:
main.getMult(0x3, 0x534d40, 0x1a, 0x4d2701)
test.go:25 +0x17e
main.main()
test.go:10 +0x55
exit status 2
There are a couple problems...
First, you need to start mult at 1, otherwise you will just continually multiply by 0 and always get 0.
Secondly you have the logic for your err check flipped. It should be if err == nil
This seems to do what you want:
func getMult(startIndex int, inputNum string) int {
mult := 1
for i := 0; i < 10; i++ {
digit, err := strconv.Atoi(string(inputNum[startIndex+i]))
if err == nil {
mult *= int(digit)
} else {
fmt.Println(err)
}
}
return mult
}
The error you were getting was because you were trying to print err.Error() when err itself was nil (due to the logical flip of != and ==)
your code will work with fixing these two typos:
change mult := 0 to mult := 1
and change err != nil to err == nil like this:
package main
import (
"fmt"
"strconv"
)
func main() {
inputNum := "73167176531330624919225119"
mult := getMult(3, inputNum)
fmt.Printf("Mult = %d", mult)
}
func getMult(startIndex int, inputNum string) int {
mult := 1
for i := 0; i < 10; i++ {
digit, err := strconv.Atoi(string(inputNum[startIndex+i]))
if err == nil {
mult *= int(digit)
} else {
fmt.Printf("Error converting %s to int : %s\n", string(inputNum[startIndex+i]), err.Error())
}
}
return mult
}
also you may use inputNum[3:13] to get new string from index 3 with length 10,
and you may use int(v - '0') to convert one character to integer number,
then use for range like this:
package main
import "fmt"
func main() {
inputNum := "73167176531330624919225119"
mult := getMult(inputNum[3:13])
fmt.Printf("Mult = %d \n", mult) // Mult = 238140
}
func getMult(str string) int {
m := 1
for _, v := range str {
if v >= '0' && v <= '9' {
m *= int(v - '0')
} else {
fmt.Printf("Error converting %q to int\n", v)
break
}
}
return m
}
output:
Mult = 238140

Challenge of finding 3 pairs in array

The length L at the time of joining, when the length of the bar of the N (1 ≦ N ≦ 5000) is supplied from standard input, is the L by connecting three lengths among the N number of bars please write a program to find the total number of combinations of. However, and the length of the individual bars, length was pieced together (L) is a positive integer, is sufficient handle range in 32bit integer. In addition, it has all the length of the bar different things.
for example)
input:
15
5
8
4
10
3
2
output:
2 //{{2, 3, 10}, {3, 4, 8}}
example 2)
input :
35
10
13
12
17
10
4
18
3
11
5
7
output:
6 //{{4, 13, 18}, {5, 12, 18}, {5, 13, 17}, {7, 10, 18}, {7, 11, 17}, {10, 12, 13}}
and my answer is here
package main
import (
"fmt"
"sort"
)
func main() {
input_count := 0
var target int
var count int
var v int
var array []int
for read_count, _ := fmt.Scan(&v); read_count != 0; read_count, _ = fmt.Scan(&v) {
if 0 == input_count {
target = v
} else if 1 == input_count {
count = v
array = make([]int, count)
} else {
array[input_count-2] = v
}
input_count++
}
sort.Ints(array)
fmt.Println(Calculate(target, count, array))
}
func Except(pair []int, count int, array []int) []int {
except := make([]int, count-pair[2])
except_index := 0
on := false
for _, v := range array {
if on {
except[except_index] = v
except_index++
}
if v == pair[1] {
on = true
}
}
return except
}
func ListUp(target int, count int, array []int) [][]int {
max := array[count-1]
list := make([][]int, Fact(count-1))
list_index := 0
for i, h := range array {
if count > i+1 && target > h+array[i+1] {
for j, v := range array[i+1:] {
if count > i+j+1 && target <= max+h+v && target > h+v {
list[list_index] = []int{h, v, i + j + 1}
list_index++
}
}
}
}
return list
}
//func Calculate(target int, count int, array []int) [][]int {
func Calculate(target int, count int, array []int) int {
// var answers [][]int
answer_count := 0
for _, pair := range ListUp(target, count, array) {
if 3 == len(pair) {
pair_sum := pair[0] + pair[1]
if target-pair_sum >= array[0] {
for _, v := range Except(pair, count, array) {
if target == pair[0]+pair[1]+v {
// answers = append(answers, []int{pair[0], pair[1], v})
answer_count++
}
}
}
}
}
return answer_count
}
func Fact(n int) int {
if n == 0 {
return 0
}
return n + Fact(n-1)
}
Does anyone who can refactor the code?
and you should refactor it
if input
https://github.com/freddiefujiwara/horiemon-challenge-codeiq/blob/master/sample4.txt
then output
1571200
in 10 seconds
current status is here
time ./horiemon-challenge-codeiq < sample4.txt
1571200
real 6m56.584s
user 6m56.132s
sys 0m1.578s
very very slow.
Your time of almost seven minutes is very, very slow. Ten seconds is slow. One second is more reasonable, a tenth of a second is good. For example, using an O(N*N) algorithm,
package main
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
func triples(l int, b []int) int {
t := 0
sort.Ints(b)
// for i < j < k, b[i] <= b[j] <= b[k]
for i := 0; i < len(b)-2; i++ {
x := b[i]
if x > l {
break
}
lx := l - x
j, k := i+1, len(b)-1
y := b[j]
z := b[k]
for j < k {
yz := y + z
switch {
case lx > yz:
j++
y = b[j]
case lx < yz:
k--
z = b[k]
default:
// l == b[i]+b[j]+b[k]
t++
j++
k--
y = b[j]
z = b[k]
}
}
}
return t
}
func readInput() (l int, b []int, err error) {
r := bufio.NewReader(os.Stdin)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err == nil && len(line) == 0 {
err = io.EOF
}
if err != nil {
if err == io.EOF {
break
}
return 0, nil, err
}
i, err := strconv.Atoi(string(line))
if err == nil && i < 0 {
err = errors.New("Nonpositive number: " + line)
}
if err != nil {
return 0, nil, err
}
b = append(b, i)
}
if len(b) > 0 {
l = b[0]
b = b[1:]
if len(b) > 1 {
n := b[0]
b = b[1:]
if n != len(b) {
err := errors.New("Invalid number of bars: " + strconv.Itoa(len(b)))
return 0, nil, err
}
}
}
return l, b, nil
}
func main() {
l, b, err := readInput()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
t := triples(l, b)
fmt.Println(t)
}
Output:
1571200
real 0m0.164s
user 0m0.161s
sys 0m0.004s
For comparison, your program,
Output:
1571200
real 9m24.384s
user 16m14.592s
sys 0m19.129s
ive tuned
package main
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sort"
"strconv"
"strings"
)
type triple struct {
x, y, z int
}
func triples(l int, n []int, list bool) (nt int, t []triple) {
num_of_list := len(n)
for i := 0; i < num_of_list-2; i++ {
x := n[i]
if x > l {
break
}
for j := i + 1; j < num_of_list-1; j++ {
y := x + n[j]
if y > l {
break
}
pos := sort.SearchInts(n[j:], l-y)
if j < pos+j && pos+j < num_of_list && n[pos+j] == l-y {
nt++
}
}
}
return nt, t
}
func readInput() (l int, n []int, err error) {
r := bufio.NewReader(os.Stdin)
for {
line, err := r.ReadString('\n')
line = strings.TrimSpace(line)
if err == nil && len(line) == 0 {
err = io.EOF
}
if err != nil {
if err == io.EOF {
break
}
return 0, nil, err
}
i, err := strconv.Atoi(string(line))
if err == nil && i < 0 {
err = errors.New("Nonpositive number: " + line)
}
if err != nil {
return 0, nil, err
}
n = append(n, i)
}
if len(n) > 0 {
l = n[0]
n = n[1:]
}
sort.Ints(n)
for i := 1; i < len(n); i++ {
if n[i] == n[i-1] {
copy(n[i:], n[i+1:])
n = n[:len(n)-1]
}
}
return l, n, nil
}
func main() {
l, n, err := readInput()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
list := false
nt, t := triples(l, n, list)
fmt.Println(nt)
if list {
fmt.Println(t)
}
}

Resources