Skip to content

Commit 8d56ab9

Browse files
author
Shahzod Shafizod
committed
shahzodshafizod: challenges 1-4
1 parent a7ac764 commit 8d56ab9

File tree

8 files changed

+856
-0
lines changed

8 files changed

+856
-0
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"math"
7+
"os"
8+
)
9+
10+
var (
11+
errOverflow = errors.New("errOverflow")
12+
)
13+
14+
func main() {
15+
var a, b int
16+
// Read two integers from standard input
17+
_, err := fmt.Scanf("%d, %d", &a, &b)
18+
if err != nil {
19+
fmt.Println("Error reading input:", err)
20+
os.Exit(1)
21+
}
22+
23+
// Call the Sum function and print the result
24+
result, err := Sum(a, b)
25+
if err != nil {
26+
fmt.Println(err)
27+
os.Exit(1)
28+
}
29+
fmt.Println(result)
30+
}
31+
32+
// Sum returns the sum of a and b.
33+
func Sum(a int, b int) (int, error) {
34+
if a > 0 && b > math.MaxInt-a || a < 0 && b < math.MinInt-a {
35+
return 0, errOverflow
36+
}
37+
return a + b, nil
38+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"math"
7+
"os/exec"
8+
"strings"
9+
"testing"
10+
)
11+
12+
// go test -v challenge-1/submissions/shahzodshafizod/solution-template_test.go
13+
func TestSum(t *testing.T) {
14+
tests := []struct {
15+
name string
16+
input string
17+
expected string
18+
}{
19+
{"Positive numbers", "2, 3", "5"},
20+
{"Zero values", "0, 0", "0"},
21+
{"Negative numbers", "-2, -3", "-5"},
22+
{"Mixed signs", "-5, 10", "5"},
23+
{"Large numbers", "1000000000, 1000000000", "2000000000"},
24+
{"Overflow case", fmt.Sprintf("%d, %d", math.MaxInt, math.MaxInt), "errOverflow"},
25+
{"Overflow case", fmt.Sprintf("%d, %d", math.MinInt, math.MinInt), "errOverflow"},
26+
}
27+
28+
for _, tt := range tests {
29+
t.Run(tt.name, func(t *testing.T) {
30+
cmd := exec.Command("go", "run", "solution-template.go")
31+
stdin := strings.NewReader(tt.input)
32+
var stdout, stderr bytes.Buffer
33+
cmd.Stdin = stdin
34+
cmd.Stdout = &stdout
35+
cmd.Stderr = &stderr
36+
37+
err := cmd.Run()
38+
if err != nil {
39+
t.Fatalf("Error running the program: %v\nStderr: %s", err, stderr.String())
40+
}
41+
42+
output := strings.TrimSpace(stdout.String())
43+
if output != tt.expected {
44+
t.Errorf("For input '%s', expected output '%s', got '%s'", tt.input, tt.expected, output)
45+
}
46+
})
47+
}
48+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
"slices"
8+
)
9+
10+
func main() {
11+
// Read input from standard input
12+
scanner := bufio.NewScanner(os.Stdin)
13+
if scanner.Scan() {
14+
input := scanner.Text()
15+
16+
// Call the ReverseString function
17+
output := ReverseString(input)
18+
19+
// Print the result
20+
fmt.Println(output)
21+
}
22+
}
23+
24+
// ReverseString returns the reversed string of s.
25+
func ReverseString(s string) string {
26+
sr := []rune(s)
27+
slices.Reverse(sr)
28+
return string(sr)
29+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"os/exec"
6+
"strings"
7+
"testing"
8+
)
9+
10+
// go test -v challenge-2/submissions/shahzodshafizod/solution-template_test.go
11+
func TestReverseString(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
input string
15+
expected string
16+
}{
17+
{"Simple word", "hello", "olleh"},
18+
{"Sentence with spaces", "Go is fun!", "!nuf si oG"},
19+
{"Empty string", "", ""},
20+
{"Palindrome", "madam", "madam"},
21+
{"Special characters", "12345!@#$%", "%$#@!54321"},
22+
{"Mixed case", "GoLang", "gnaLoG"},
23+
}
24+
25+
for _, tt := range tests {
26+
t.Run(tt.name, func(t *testing.T) {
27+
cmd := exec.Command("go", "run", "solution-template.go")
28+
stdin := strings.NewReader(tt.input)
29+
var stdout, stderr bytes.Buffer
30+
cmd.Stdin = stdin
31+
cmd.Stdout = &stdout
32+
cmd.Stderr = &stderr
33+
34+
err := cmd.Run()
35+
if err != nil {
36+
t.Fatalf("Error running the program: %v\nStderr: %s", err, stderr.String())
37+
}
38+
39+
output := strings.TrimSpace(stdout.String())
40+
if output != tt.expected {
41+
t.Errorf("For input '%s', expected output '%s', got '%s'", tt.input, tt.expected, output)
42+
}
43+
})
44+
}
45+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"sort"
6+
"sync"
7+
)
8+
9+
type Employee struct {
10+
ID int
11+
Name string
12+
Age int
13+
Salary float64
14+
}
15+
16+
type Manager struct {
17+
Employees []Employee
18+
totalSalary float64
19+
mu sync.RWMutex
20+
}
21+
22+
// AddEmployee adds a new employee to the manager's list.
23+
func (m *Manager) AddEmployee(e Employee) { // Time: O(n)
24+
m.mu.Lock()
25+
defer m.mu.Unlock()
26+
// sort.Slice(m.Employees, func(i, j int) bool {
27+
// return m.Employees[i].ID < m.Employees[j].ID
28+
// })
29+
idx := m.search(e.ID)
30+
if idx == -1 {
31+
idx = len(m.Employees)
32+
}
33+
m.Employees = append(m.Employees, Employee{})
34+
copy(m.Employees[idx+1:], m.Employees[idx:])
35+
m.Employees[idx] = e
36+
m.totalSalary += e.Salary
37+
}
38+
39+
// RemoveEmployee removes an employee by ID from the manager's list.
40+
func (m *Manager) RemoveEmployee(id int) bool { // Time: O(n)
41+
m.mu.Lock()
42+
defer m.mu.Unlock()
43+
index := m.search(id) // O(log n)
44+
if index != -1 {
45+
m.totalSalary -= m.Employees[index].Salary
46+
m.Employees = append(m.Employees[:index], m.Employees[index+1:]...) // O(n)
47+
return true
48+
}
49+
return false
50+
}
51+
52+
// GetAverageSalary calculates the average salary of all employees.
53+
func (m *Manager) GetAverageSalary() float64 { // Time: O(1)
54+
m.mu.RLock()
55+
defer m.mu.RUnlock()
56+
if n := len(m.Employees); n > 0 {
57+
return m.totalSalary / float64(n)
58+
}
59+
return 0
60+
}
61+
62+
// FindEmployeeByID finds and returns an employee by their ID.
63+
func (m *Manager) FindEmployeeByID(id int) *Employee { // Time: O(log n)
64+
m.mu.RLock()
65+
defer m.mu.RUnlock()
66+
index := m.search(id)
67+
if index != -1 {
68+
return &m.Employees[index]
69+
}
70+
return nil
71+
}
72+
73+
func (m *Manager) search(id int) int { // Time: O(log n)
74+
index := sort.Search(len(m.Employees), func(i int) bool {
75+
return m.Employees[i].ID >= id
76+
}) // sort.Search returns an index where a new item could be inserted, so we do not receive -1 or an error
77+
if index < len(m.Employees) && m.Employees[index].ID == id {
78+
return index
79+
}
80+
return -1
81+
}
82+
83+
func main() {
84+
manager := Manager{}
85+
manager.AddEmployee(Employee{ID: 1, Name: "Alice", Age: 30, Salary: 70000})
86+
manager.AddEmployee(Employee{ID: 2, Name: "Bob", Age: 25, Salary: 65000})
87+
manager.RemoveEmployee(1)
88+
averageSalary := manager.GetAverageSalary()
89+
employee := manager.FindEmployeeByID(2)
90+
91+
fmt.Printf("Average Salary: %f\n", averageSalary)
92+
if employee != nil {
93+
fmt.Printf("Employee found: %+v\n", *employee)
94+
}
95+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
)
6+
7+
// go test -C challenge-3 -v -count 1 ./submissions/shahzodshafizod/
8+
func TestAddEmployee(t *testing.T) {
9+
manager := Manager{}
10+
11+
manager.AddEmployee(Employee{ID: 1, Name: "Alice", Age: 30, Salary: 70000})
12+
manager.AddEmployee(Employee{ID: 2, Name: "Bob", Age: 25, Salary: 65000})
13+
14+
if len(manager.Employees) != 2 {
15+
t.Errorf("Expected 2 employees, got %d", len(manager.Employees))
16+
}
17+
18+
// Edge Case: Add an Employee with an Existing ID
19+
manager.AddEmployee(Employee{ID: 1, Name: "Derek", Age: 40, Salary: 80000})
20+
if len(manager.Employees) != 3 {
21+
t.Errorf("Expected 3 employees despite duplicate ID, got %d", len(manager.Employees))
22+
}
23+
}
24+
25+
func TestRemoveEmployee(t *testing.T) {
26+
manager := Manager{}
27+
28+
manager.AddEmployee(Employee{ID: 1, Name: "Alice", Age: 30, Salary: 70000})
29+
manager.AddEmployee(Employee{ID: 2, Name: "Bob", Age: 25, Salary: 65000})
30+
31+
manager.RemoveEmployee(1)
32+
if len(manager.Employees) != 1 {
33+
t.Errorf("Expected 1 employee after removing ID 1, got %d", len(manager.Employees))
34+
}
35+
36+
// Remove Non-Existing Employee
37+
manager.RemoveEmployee(999)
38+
if len(manager.Employees) != 1 {
39+
t.Errorf("Expected 1 employee after attempting to remove non-existing ID, got %d", len(manager.Employees))
40+
}
41+
}
42+
43+
func TestGetAverageSalary(t *testing.T) {
44+
manager := Manager{}
45+
46+
manager.AddEmployee(Employee{ID: 2, Name: "Bob", Age: 25, Salary: 65000})
47+
manager.AddEmployee(Employee{ID: 3, Name: "Charlie", Age: 35, Salary: 75000})
48+
49+
var expectedAverage float64
50+
expectedAverage = (65000 + 75000) / 2
51+
if avg := manager.GetAverageSalary(); avg != expectedAverage {
52+
t.Errorf("Expected average salary %f, got %f", expectedAverage, avg)
53+
}
54+
55+
// Edge Case: GetAverageSalary with No Employees
56+
manager.Employees = []Employee{}
57+
58+
expectedAverage = 0
59+
60+
if avg := manager.GetAverageSalary(); avg != expectedAverage {
61+
t.Errorf("Expected average salary %f with no employees, got %f", expectedAverage, avg)
62+
}
63+
}
64+
65+
func TestFindEmployeeByID(t *testing.T) {
66+
manager := Manager{}
67+
68+
manager.AddEmployee(Employee{ID: 2, Name: "Bob", Age: 25, Salary: 65000})
69+
manager.AddEmployee(Employee{ID: 3, Name: "Charlie", Age: 35, Salary: 75000})
70+
71+
employee := manager.FindEmployeeByID(2)
72+
if employee == nil || employee.Name != "Bob" {
73+
t.Errorf("Expected to find Bob, got %+v", employee)
74+
}
75+
76+
employee = manager.FindEmployeeByID(999)
77+
if employee != nil {
78+
t.Errorf("Expected no employee, got %+v", employee)
79+
}
80+
}
81+
82+
func TestFindEmployeeAfterRemoval(t *testing.T) {
83+
manager := Manager{}
84+
85+
manager.AddEmployee(Employee{ID: 4, Name: "David", Age: 45, Salary: 100000})
86+
manager.AddEmployee(Employee{ID: 5, Name: "Eva", Age: 29, Salary: 95000})
87+
88+
employee := manager.FindEmployeeByID(4)
89+
if employee == nil || employee.Name != "David" {
90+
t.Errorf("Expected to find David, got %+v", employee)
91+
}
92+
93+
// Edge Case: Test FindEmployeeByID After Removal
94+
manager.RemoveEmployee(4)
95+
employee = manager.FindEmployeeByID(4)
96+
if employee != nil {
97+
t.Errorf("Expected no employee, got %+v", employee)
98+
}
99+
}

0 commit comments

Comments
 (0)