Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 96
Good morning! Here's your coding interview problem for today.

This problem was asked by Microsoft.

Given a number in the form of a list of digits, return all possible permutations.

For example, given `[1,2,3]`, return `[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]`.

Pull request description:
Day96
Resolves #200 .

Patch:
diff --git a/README.md b/README.md
index e7a4e92..27f2276 100644
--- a/README.md
+++ b/README.md
@@ -103,3 +103,4 @@ problems from
 * [Day 91](https://github.com/vaskoz/dailycodingproblem-go/issues/192)
 * [Day 92](https://github.com/vaskoz/dailycodingproblem-go/issues/194)
 * [Day 95](https://github.com/vaskoz/dailycodingproblem-go/issues/198)
+* [Day 96](https://github.com/vaskoz/dailycodingproblem-go/issues/200)
diff --git a/day96/problem.go b/day96/problem.go
new file mode 100644
index 0000000..7a3328d
--- /dev/null
+++ b/day96/problem.go
@@ -0,0 +1,74 @@
+package day96
+
+// HeapsAlgorithmRecursive finds all the permutations recursively.
+func HeapsAlgorithmRecursive(digits []int) <-chan []int {
+	num := 1
+	for i := 2; i <= len(digits); i++ {
+		num *= i
+	}
+	copied := make([]int, len(digits))
+	copy(copied, digits)
+	perms := make(chan []int, num)
+	go generateRecursive(len(copied), copied, perms)
+	return perms
+}
+
+func generateRecursive(n int, digits []int, perms chan []int) {
+	if n == 1 {
+		copied := make([]int, len(digits))
+		copy(copied, digits)
+		perms <- copied
+		return
+	}
+	for i := 0; i < n-1; i++ {
+		generateRecursive(n-1, digits, perms)
+		if n%2 == 0 {
+			digits[i], digits[n-1] = digits[n-1], digits[i]
+		} else {
+			digits[0], digits[n-1] = digits[n-1], digits[0]
+		}
+	}
+	generateRecursive(n-1, digits, perms)
+	if n == len(digits) {
+		close(perms)
+	}
+}
+
+// HeapsAlgorithmIterative finds all the permutations iteratively.
+func HeapsAlgorithmIterative(digits []int) <-chan []int {
+	num := 1
+	for i := 2; i <= len(digits); i++ {
+		num *= i
+	}
+	copied := make([]int, len(digits))
+	copy(copied, digits)
+	perms := make(chan []int, num)
+	go generateIterative(len(copied), copied, perms)
+	return perms
+}
+
+func generateIterative(n int, digits []int, perms chan []int) {
+	c := make([]int, len(digits))
+	send := make([]int, len(digits))
+	copy(send, digits)
+	perms <- send
+	var i int
+	for i < n {
+		if c[i] < i {
+			if i%2 == 0 {
+				digits[0], digits[i] = digits[i], digits[0]
+			} else {
+				digits[c[i]], digits[i] = digits[i], digits[c[i]]
+			}
+			send = make([]int, len(digits))
+			copy(send, digits)
+			perms <- send
+			c[i]++
+			i = 0
+		} else {
+			c[i] = 0
+			i++
+		}
+	}
+	close(perms)
+}


Test patch:
diff --git a/day96/problem_test.go b/day96/problem_test.go
new file mode 100644
index 0000000..f06c462
--- /dev/null
+++ b/day96/problem_test.go
@@ -0,0 +1,65 @@
+package day96
+
+import (
+	"reflect"
+	"testing"
+)
+
+var testcases = []struct {
+	input    []int
+	expected [][]int
+}{
+	{[]int{1, 2, 3},
+		[][]int{
+			{1, 2, 3},
+			{2, 1, 3},
+			{3, 1, 2},
+			{1, 3, 2},
+			{2, 3, 1},
+			{3, 2, 1}},
+	},
+}
+
+func TestHeapsAlgorithmRecursive(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		results := HeapsAlgorithmRecursive(tc.input)
+		pos := 0
+		for result := range results {
+			if !reflect.DeepEqual(result, tc.expected[pos]) {
+				t.Errorf("Expected %v got %v", tc.expected[pos], result)
+			}
+			pos++
+		}
+	}
+}
+
+func BenchmarkHeapsAlgorithmRecursive(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			HeapsAlgorithmRecursive(tc.input)
+		}
+	}
+}
+
+func TestHeapsAlgorithmIterative(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		results := HeapsAlgorithmIterative(tc.input)
+		pos := 0
+		for result := range results {
+			if !reflect.DeepEqual(result, tc.expected[pos]) {
+				t.Errorf("Expected %v got %v", tc.expected[pos], result)
+			}
+			pos++
+		}
+	}
+}
+
+func BenchmarkHeapsAlgorithmIterative(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			HeapsAlgorithmIterative(tc.input)
+		}
+	}
+}