Skip to content

Instantly share code, notes, and snippets.

@vodolaz095
Created November 9, 2024 10:07
Show Gist options
  • Save vodolaz095/a467c4f850ff21d3a73337f98cd49d69 to your computer and use it in GitHub Desktop.
Save vodolaz095/a467c4f850ff21d3a73337f98cd49d69 to your computer and use it in GitHub Desktop.
Подсчёт шагов
package count_steps
/*
Необходимо определить userIds участников, которые прошли наибольшее количество шагов steps за все дни, не пропустив ни одного дня соревнований.
Пример
# Пример 1
# ввод
statistics = [
[{ userId: 1, steps: 1000 }, { userId: 2, steps: 1500 }],
[{ userId: 2, steps: 1000 }]
]
# вывод
champions = { userIds: [2], steps: 2500 }
# Пример 2
statistics = [
[{ userId: 1, steps: 2000 }, { userId: 2, steps: 1500 }],
[{ userId: 2, steps: 4000 }, { userId: 1, steps: 3500 }]
]
# вывод
champions = { userIds: [1, 2], steps: 5500 }
*/
type Record struct {
UserID string
StepsToday uint
}
func FindChampions(input [][]Record) (championsIDs []string, steps uint) {
type tempData struct {
UserID string
TotalSteps uint
DaysActive int
}
totalDays := len(input)
temp := make(map[string]tempData, 0)
stepsUsers := make(map[uint][]string, 0)
var maxSteps uint
var newVal tempData
for i := range input {
for j := range input[i] {
if input[i][j].StepsToday == 0 {
continue
}
usersRecord, found := temp[input[i][j].UserID]
if found {
newVal = tempData{
UserID: usersRecord.UserID,
TotalSteps: usersRecord.TotalSteps + input[i][j].StepsToday,
DaysActive: usersRecord.DaysActive + 1,
}
} else {
newVal = tempData{
UserID: input[i][j].UserID,
TotalSteps: input[i][j].StepsToday,
DaysActive: 1,
}
}
if maxSteps < newVal.TotalSteps {
maxSteps = newVal.TotalSteps
}
temp[input[i][j].UserID] = newVal
}
}
for k := range temp {
if temp[k].DaysActive != totalDays {
continue
}
users := stepsUsers[temp[k].TotalSteps]
users = append(users, temp[k].UserID)
stepsUsers[temp[k].TotalSteps] = users
}
return stepsUsers[maxSteps], maxSteps
}
package count_steps
import (
"sort"
"testing"
)
func TestFindChampions(t *testing.T) {
var out []string
var steps uint
type testCase struct {
Name string
Input [][]Record
Output []string
Steps uint
}
testCases := []testCase{
{
Name: "nil",
Input: nil,
Output: nil,
},
{
Name: "single",
Input: [][]Record{
{
{UserID: "a", StepsToday: 100},
},
},
Output: []string{"a"},
Steps: 100,
},
{
Name: "2 winners",
Input: [][]Record{
{
{UserID: "a", StepsToday: 100},
{UserID: "b", StepsToday: 101},
{UserID: "c", StepsToday: 101},
},
},
Output: []string{"b", "c"},
Steps: 101,
},
{
Name: "1 winner, 2 days",
Input: [][]Record{
{
{UserID: "a", StepsToday: 100},
{UserID: "b", StepsToday: 101},
{UserID: "c", StepsToday: 101},
},
{
{UserID: "a", StepsToday: 200},
{UserID: "b", StepsToday: 101},
{UserID: "c", StepsToday: 101},
},
},
Output: []string{"a"},
Steps: 300,
},
{
Name: "max steps, but not everyday",
Input: [][]Record{
{
{UserID: "a", StepsToday: 100},
{UserID: "b", StepsToday: 101},
{UserID: "c", StepsToday: 101},
},
{
{UserID: "a", StepsToday: 200},
{UserID: "b", StepsToday: 99},
{UserID: "c", StepsToday: 101},
},
{
{UserID: "b", StepsToday: 100},
{UserID: "c", StepsToday: 1},
},
},
Output: []string{"b"},
Steps: 300,
},
{
Name: "case1",
Input: [][]Record{
{
{UserID: "1", StepsToday: 1000},
{UserID: "2", StepsToday: 1500},
},
{
{UserID: "2", StepsToday: 1000},
},
},
Output: []string{"2"},
Steps: 2500,
},
{
Name: "case2",
Input: [][]Record{
{
{UserID: "1", StepsToday: 2000},
{UserID: "2", StepsToday: 1500},
},
{
{UserID: "2", StepsToday: 4000},
{UserID: "1", StepsToday: 3500},
},
},
Output: []string{"1", "2"},
Steps: 5500,
},
}
for i := range testCases {
out, steps = FindChampions(testCases[i].Input)
if len(out) != len(testCases[i].Output) {
t.Errorf("wrong output length for case %v %s - %v! Expected: %v. Actual: %v",
i, testCases[i].Name, testCases[i].Input, testCases[i].Output, out)
}
if steps != testCases[i].Steps {
t.Errorf("wrong steps for case %v %s - %v! Expected: %v. Actual: %v",
i, testCases[i].Name, testCases[i].Input, testCases[i].Steps, steps)
}
for j := range out {
sort.Slice(out, func(i, j int) bool {
return out[i] < out[j]
})
if out[j] != testCases[i].Output[j] {
t.Errorf("wrong output for case %v %s - %v! Expected: %v. Actual: %v. Wrong value index: %v",
i, testCases[i].Name, testCases[i].Input, testCases[i].Output, out, j)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment