Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 177
Good morning! Here's your coding interview problem for today.

This problem was asked by Airbnb.

Given a linked list and a positive integer `k`, rotate the list to the right by `k` places.

For example, given the linked list `7 -> 7 -> 3 -> 5` and `k = 2`, it should become `3 -> 5 -> 7 -> 7`.

Given the linked list `1 -> 2 -> 3 -> 4 -> 5` and `k = 3`, it should become `4 -> 5 -> 1 -> 2 -> 3`.

Pull request description:
Day177
Resolves #365.

Patch:
diff --git a/README.md b/README.md
index 1f804ba..a28119e 100644
--- a/README.md
+++ b/README.md
@@ -185,3 +185,4 @@ problems from
 * [Day 171](https://github.com/vaskoz/dailycodingproblem-go/issues/356)
 * [Day 172](https://github.com/vaskoz/dailycodingproblem-go/issues/358)
 * [Day 173](https://github.com/vaskoz/dailycodingproblem-go/issues/360)
+* [Day 177](https://github.com/vaskoz/dailycodingproblem-go/issues/365)
diff --git a/day177/problem.go b/day177/problem.go
new file mode 100644
index 0000000..8114d9b
--- /dev/null
+++ b/day177/problem.go
@@ -0,0 +1,33 @@
+package day177
+
+// LL is a singly linked list.
+type LL struct {
+	Value interface{}
+	Next  *LL
+}
+
+// RotateRightLL rotates the linked list to the right
+// by k elements.
+// Runs in O(N) time and O(1) extra space.
+func RotateRightLL(head *LL, k int) *LL {
+	if head == nil {
+		return nil
+	}
+	size := 1
+	var end *LL
+	for end = head; end.Next != nil; end = end.Next {
+		size++
+	}
+	if k%size == 0 {
+		return head
+	}
+	k = k % size
+	curr := head
+	for i := 0; i < k-1; i++ {
+		curr = curr.Next
+	}
+	newHead := curr.Next
+	curr.Next = nil
+	end.Next = head
+	return newHead
+}


Test patch:
diff --git a/day177/problem_test.go b/day177/problem_test.go
new file mode 100644
index 0000000..9860f50
--- /dev/null
+++ b/day177/problem_test.go
@@ -0,0 +1,51 @@
+package day177
+
+import "testing"
+
+var testcases = []struct {
+	input    *LL
+	k        int
+	expected *LL
+}{
+	{&LL{7, &LL{7, &LL{3, &LL{5, nil}}}}, 2, &LL{3, &LL{5, &LL{7, &LL{7, nil}}}}},
+	{&LL{1, &LL{2, &LL{3, &LL{4, &LL{5, nil}}}}}, 3, &LL{4, &LL{5, &LL{1, &LL{2, &LL{3, nil}}}}}},
+	{nil, 10, nil},
+	{&LL{5, nil}, 10000, &LL{5, nil}},
+	{&LL{1, &LL{2, &LL{3, &LL{4, &LL{5, nil}}}}}, 503, &LL{4, &LL{5, &LL{1, &LL{2, &LL{3, nil}}}}}},
+}
+
+func TestRotateRightLL(t *testing.T) {
+	t.Parallel()
+	for tcid, tc := range testcases {
+		copied := cloneLL(tc.input)
+		if result := RotateRightLL(copied, tc.k); !equal(tc.expected, result) {
+			t.Errorf("TCID%d doesn't match expected", tcid)
+		}
+	}
+}
+
+func BenchmarkRotateRightLL(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			copied := cloneLL(tc.input)
+			RotateRightLL(copied, tc.k)
+		}
+	}
+}
+
+func cloneLL(a *LL) *LL {
+	head := &LL{}
+	for ptr := head; a != nil; ptr, a = ptr.Next, a.Next {
+		ptr.Next = &LL{a.Value, nil}
+	}
+	return head.Next
+}
+
+func equal(a, b *LL) bool {
+	for ; a != nil && b != nil; a, b = a.Next, b.Next {
+		if a.Value != b.Value {
+			return false
+		}
+	}
+	return a == nil && b == nil
+}