Generate all the strings of length n drawn from 0 ... k-1 - algorithm

This problem is from the book Data Structure and Algorithms Made Easy by Narasimha Karumanchi chapter Recursion and Backtracking. The algorithm which is given in the book is as follows:
Let us assume we keep current k-ary string in an array A[0...n-1]. Call function k-string(n, k)
void k-string(int n, int k) {
// process all k-ary strings of length m
if(n < 1)
printf("%s", A); // Assume array A is a global variable
else {
for(int j=0; j<k; j++){
A[n-1] = j;
k-string(n-1, k);
}
}
}
I couldn't understand the algorithm. Like why did they assigned an integer j to a string element?

package main
import "fmt"
func printResult(A []int, n int) {
var i int
for ; i < n; i++ {
// Function to print the output
fmt.Print(A[i])
}
fmt.Printf("\n")
}
// Function to generate all k-ary strings
func generateK_aryStrings(n int, A []int, i int, k int) {
if i == n {
printResult(A, n)
return
}
for j := 0; j < k; j++ {
// assign j at ith position and try for all other permutations for remaining positions
A[i] = j
generateK_aryStrings(n, A, i+1, k)
}
}
func main() {
var n int = 4
A := make([]int, n)
// Print all binary strings
generateK_aryStrings(n, A, 0, 3)
return
}

Related

Golang assignment

We want to calculate a sum of squares of some integers, excepting negatives
The first line of the input will be an integer N (1 <= N <= 100)
Each of the following N test cases consists of one line containing an integer X (0 < X <= 100), followed by X integers (Yn, -100 <= Yn <= 100) space-separated on the next line
For each test case, calculate the sum of squares of the integers excepting negatives, and print the calculated sum to the output. No blank line between test cases
(Take input from standard input, and output to standard output)
Do not use the for statement
Use only standard libraries
Write it in the Go programming language
Sample input
2
4
3 -1 1 14
5
9 6 -53 32 16
Sample Output
206
1397
So I am new to Golang , and I managed to solve this using for statements.
How can I abide by the given and not use for? using only standard libraries?
Any pointers would be greatly appreciated
package main
import "fmt"
func main() {
var N int
fmt.Scan(&N)
for a := 0; a < N; a++ {
var X int
var res int = 0
fmt.Scan(&X)
for b := 0; b < X; b++ {
var Y int
fmt.Scan(&Y)
if Y > 0 {
res = res + Y*Y
}
}
fmt.Println(res)
}
}
// I used fmt to read data from console. Sum of squares is found out only if the number is positive. Then computed sum is displayed to the screen
I got the same output expected, but not using the required method
This is how I did it in Java
import java.util.Scanner;
public class SumSquares {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt(), m, num;
int i = 0;
while (i < n) {
int j = 0, sum = 0;
m = in.nextInt();
while (j < m) {
num = in.nextInt();
if (num > 0) {
sum += num*num;
}
j++;
}
System.out.println(sum);
i++;
}
}
}
Go does not have the while, until, or foreach loop constructs you may be familiar with from other languages. In Go, the for and range statements replace them all:
// Three expressions, i.e. the usual
for i := 0; i < n; i++ {
}
// Single expression; same as while(condition) in other languages
for condition {
}
// No expressions; endless loop, i.e. same as while(true) or for(;;)
for {
}
// for with range; foreach and similar in other languages. Works with slices, maps, and channels.
for i, x := range []T{} {
}
If you are not allowed to use Go's single loop construct, you are left with either recursion or the goto statement:
package main
import (
"fmt"
)
func main() {
var N int
fmt.Scan(&N)
fmt.Println(f(N, 0))
}
func f(n, sum int) int {
if n == 0 {
return sum
}
var Y int
fmt.Scan(&Y)
if Y > 0 {
sum += Y * Y
}
return f(n-1, sum)
}
With goto:
package main
import (
"fmt"
)
func main() {
var N, Y, sum int
fmt.Scan(&N)
again:
fmt.Scan(&Y)
if Y > 0 {
sum += Y * Y
}
N--
if N > 0 {
goto again
}
fmt.Println(sum)
}

Writing next Permutation in Go using closure, what is wrong with my code

I have written a function "iterPermutation" which uses closure. I want to return array and boolean from the closure which I could not do. So tried only array but it still gives an error
cannot use func literal (type func() []int) as type []int in return
argument
I want to use iterPermutation like
a := []int{0,1,2,3,4}
nextPermutation, exists := iterPermutation(a)
for exists {
nextPermutation()
}
func iterPermutation(a []int) []int {
return func() []int {
i := len(a) - 2
for i >= 0 && a[i+1] <= a[i] {
i--
}
if i < 0 {
return a
}
j := len(a) - 1
for j >= 0 && a[j] <= a[i] {
j--
}
a[i], a[j] = a[j], a[i]
for k, l := i, len(a)-1; k < l; k, l = k+1, l-1 {
a[k], a[l] = a[l], a[k]
}
return a
}
}
Golang spec for Return statements described:
The return value or values may be explicitly listed in the "return"
statement. Each expression must be single-valued and assignable to the
corresponding element of the function's result type.
The function called for permutation should contains two values in return one for the array and another for the boolean. Since you are assigning two variables from the function return:
a := []int{0,1,2,3,4}
nextPermutation, exists := iterPermutation(a) // it should return two values one for nextPermutation which is an array and other is exists which might be a boolean value.
for exists {
nextPermutation()
}
For below error:
"cannot use func literal (type func() []int) as type []int in return
argument"
you are returning func() literal enclosed inside the closure function of permutation along with boolean value, so change the return type as:
package main
func main(){
a := []int{0,1,2,3,4}
nextPermutation, _ := iterPermutation(a)
nextPermutation()
}
func iterPermutation(a []int) ((func() []int), bool) { // return both values
return func() []int {
i := len(a) - 2
for i >= 0 && a[i+1] <= a[i] {
i--
}
if i < 0 {
return a
}
j := len(a) - 1
for j >= 0 && a[j] <= a[i] {
j--
}
a[i], a[j] = a[j], a[i]
for k, l := i, len(a)-1; k < l; k, l = k+1, l-1 {
a[k], a[l] = a[l], a[k]
}
return a
}, true // add boolean value to return from the function.
}
Working answer on Playground
I'm going to ignore the "permutation" logic inside your closure and focus on couple of concepts that you need to be aware of so it would work like you've planned to with your code. Correct me if I'm wrong, but you want to get array of item from your closure until exists is false, right?
First of all, to have nextPermutation, exists := iterPermutation(a) compile properly, iterPermutation needs to return two values like so:
func iterPermutation(a []int) (func() []int, bool) {
exists := true
return func() []int {
//rest of your code
if i < 0 {
exists = false
return a
}
//rest of your code
}, exists
}
Next problem you face is the fact that, with the above approach, you will have with the exists value. Since you are returning a value for exists, any change to exists will not be propagated beyond the scope of iterPermutation. You can fix this problem by returning a pointer. This is one way of implementing it:
a := []int{0,1,2,3,4}
nextPermutation, check := iterPermutation(a)
while check.Exists {
nextPermutation()
}
type Check struct {
Exists bool
}
func iterPermutation(a []int) (func() []int, *Check) {
check:= &Check{
Exists: true,
}
return func() []int {
i := len(a) - 2
for i >= 0 && a[i+1] <= a[i] {
i--
}
if i < 0 {
check.Exists = false //this is put here as an example
return a
}
j := len(a) - 1
for j >= 0 && a[j] <= a[i] {
j--
}
a[i], a[j] = a[j], a[i]
for k, l := i, len(a)-1; k < l; k, l = k+1, l-1 {
a[k], a[l] = a[l], a[k]
}
return a
}, check
}
When you return a pointer of Check type, any change to it in the iterPermutation or in your closure is visible outside of these as well, since you are accessing a memory reference.

Variable declared and not used in a loop

Got confusion with a function
package main
import "fmt"
func dominantIndex(nums []int) int {
var max, max2 = -12423421, -12423421
var i, j = -1, -1
for k, num := range nums {
if num > max {
max, max2 = num, max
i, j = k, i
} else if num > max2 {
max2 = num
j = k
}
}
if max >= max2*2 {
return i
}
return -1
}
func main() {
var a = []int{3, 6, 100, 1, 0 }
fmt.Print(dominantIndex(a))
}
I have to insert a nonsense statement in the loop such as j = j. Otherwise, it raises ./hello.go:7:6: j declared and not used. Wonder if there is any fix.
You assign a value to j, but you don't use j. That is the problem. You could as well leave j out, without changing the functionality of the code.

Hoare's partitioning scheme golang

Quicksort with Hoare's partitioning
// Hoare's partitioning scheme
func PartitionHoare(arr []int, low, high int) int {
length := len(arr)
if length == 0 {
panic("Array size is 0")
}
pivot := arr[low]
i := low - 1
j := high + 1
for {
for {
j--
if arr[j] > pivot {
break
}
}
for {
i++
if arr[i] < pivot {
break
}
}
if i < j {
Swap(&arr, i, j)
} else {
return j
}
}
}
// Sort
func SortHoare(arr []int, low, high int) {
if low < high {
p := PartitionHoare(arr, low, high)
SortHoare(arr, low, p)
SortHoare(arr, p+1, high)
}
}
// Swap i <--> j
func Swap(arr *[]int, i, j int) {
(*arr)[i], (*arr)[j] = (*arr)[j], (*arr)[i]
}
Trying to implement Quicksort using Hoare's partitioning but can't figure out what am I doing wrong. It is stuck in an infinite loop, always runs out of memory
fatal error: runtime: out of memory
You should use non strict inequalities while looking for position of i and j to do the swap. So instead of
if arr[j] > pivot {
break
}
you should have
if arr[j] >= pivot {
break
}
And the same for i. Instead of
if arr[i] < pivot {
break
}
use
if arr[i] <= pivot {
break
}
Also I'm not sure if it's intentional or not, but currently your algorithm sorts in descending order. If you want to sort in ascending order swap the comparitions between i and j. So:
if arr[j] <= pivot {
break
}
and
if arr[i] >= pivot {
break
}

How to find out diagonal difference in go programming?

My code:
package main
import "fmt"
func main() {
var n int
fmt.Scan(&n)
s := make([][]int, n)
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
fmt.Scanf("%d %d", &s[i][j])
}
}
s1 := 0
s2 := 0
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if i == j {
s1 += s[i][j]
}
if i+j == n-1 {
s2 += s[i][j]
}
}
fmt.Println(s1 - s2)
}
}
Output:
panic: runtime error: index out of range
I tried but get panic. I want to know proper solution to this problem.
This line:
s := make([][]int, n)
Creates a slice of slices, a slice whose elements are of type []int. It creates a slice with n elements, but the elements of the outer slice are initialized with the zero value of the element type, and zero value of type []int is nil (just like for any slice type).
You get index out of range panic because any element of the outer slice s has zero length (because they are not initialized to a non-nil slice), so s[i][j] panics for any j value.
If you want to assign elements to the "inner" slices, you also have to initialize them:
for i := 0; i < n; i++ {
s[i] = make([]int, n) // YOU ARE MISSING THIS LINE
for j := 0; j < n; j++ {
fmt.Scanf("%d %d", &s[i][j])
}
}

Resources