Repository: vaskoz/dailycodingproblem-go (go)

Issue:
Day 265
Good morning! Here's your coding interview problem for today.

This problem was asked by Atlassian.

MegaCorp wants to give bonuses to its employees based on how many lines of codes they have written. They would like to give the smallest positive amount to each worker consistent with the constraint that if a developer has written more lines of code than their neighbor, they should receive more money.

Given an array representing a line of seats of employees at MegaCorp, determine how much each one should get paid.

For example, given `[10, 40, 200, 1000, 60, 30]`, you should return `[1, 2, 3, 4, 2, 1]`.

Pull request description:
Day265
Resolves #541.

Patch:
diff --git a/README.md b/README.md
index 462f3a6..f20815b 100644
--- a/README.md
+++ b/README.md
@@ -276,6 +276,7 @@ problems from
 * [Day 262](https://github.com/vaskoz/dailycodingproblem-go/issues/538)
 * [Day 263](https://github.com/vaskoz/dailycodingproblem-go/issues/539)
 * [Day 264](https://github.com/vaskoz/dailycodingproblem-go/issues/540)
+* [Day 265](https://github.com/vaskoz/dailycodingproblem-go/issues/541)
 * [Day 266](https://github.com/vaskoz/dailycodingproblem-go/issues/542)
 * [Day 267](https://github.com/vaskoz/dailycodingproblem-go/issues/543)
 * [Day 268](https://github.com/vaskoz/dailycodingproblem-go/issues/544)
diff --git a/day265/problem.go b/day265/problem.go
new file mode 100644
index 0000000..69e7a63
--- /dev/null
+++ b/day265/problem.go
@@ -0,0 +1,53 @@
+package day265
+
+// Bonuses determines how much bonus to give based on lines of code.
+func Bonuses(loc []int) []int {
+	if len(loc) == 0 {
+		return nil
+	} else if len(loc) == 1 {
+		return []int{1}
+	}
+	bonuses := make([]int, 0, len(loc))
+	segs := segments(loc)
+	for _, seg := range segs {
+		asc, run := seg.ascending, seg.run
+		segBonuses := make([]int, run)
+		for i := range segBonuses {
+			segBonuses[i] = i
+		}
+		if !asc {
+			for i := 0; i < len(segBonuses)/2; i++ {
+				segBonuses[i], segBonuses[len(segBonuses)-1-i] = segBonuses[len(segBonuses)-1-i], segBonuses[i]
+			}
+		}
+		bonuses = append(bonuses, segBonuses...)
+	}
+	for i, x := range bonuses {
+		bonuses[i] = x + 1
+	}
+	return bonuses
+}
+
+type segment struct {
+	ascending bool
+	run       int
+}
+
+func segments(loc []int) []segment {
+	asc := loc[1] > loc[0]
+	prev := loc[0]
+	var start int
+	var segs []segment
+
+	slice := loc[1:]
+	for i, num := range slice {
+		if (asc && num < prev) || (!asc && num > prev) {
+			segs = append(segs, segment{asc, i - start + 1})
+			start = i + 1
+			asc = !asc
+		}
+		prev = num
+	}
+	segs = append(segs, segment{asc, len(loc) - start})
+	return segs
+}


Test patch:
diff --git a/day265/problem_test.go b/day265/problem_test.go
new file mode 100644
index 0000000..1bef339
--- /dev/null
+++ b/day265/problem_test.go
@@ -0,0 +1,35 @@
+package day265
+
+import (
+	"reflect"
+	"testing"
+)
+
+// nolint
+var testcases = []struct {
+	locs    []int
+	bonuses []int
+}{
+	{[]int{10, 40, 200, 1000, 60, 30}, []int{1, 2, 3, 4, 2, 1}},
+	{[]int{}, nil},
+	{nil, nil},
+	{[]int{1000}, []int{1}},
+	{[]int{10, 40, 200, 1000, 900, 800, 30}, []int{1, 2, 3, 4, 3, 2, 1}},
+}
+
+func TestBonuses(t *testing.T) {
+	t.Parallel()
+	for _, tc := range testcases {
+		if bonuses := Bonuses(tc.locs); !reflect.DeepEqual(bonuses, tc.bonuses) {
+			t.Errorf("Expected %v, got %v", tc.bonuses, bonuses)
+		}
+	}
+}
+
+func BenchmarkBonuses(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tc := range testcases {
+			Bonuses(tc.locs)
+		}
+	}
+}