Skip to content

Commit ee9acbe

Browse files
shahzodshafizodShahzod Shafizod
andauthored
Add solutions for Challenges 1-7 by shahzodshafizod (#1466)
* shahzodshafizod: challenges 1-4 * fixing os.Exit * fixing comments * removed out commented out alternative solution * fixed new method that does not exist in earlier versions * challenges 5-6 * challenge 7 * optimizing solution for challenge 7 --------- Co-authored-by: Shahzod Shafizod <shafizod@bankplanet9.com>
1 parent 87bff4d commit ee9acbe

File tree

7 files changed

+482
-0
lines changed

7 files changed

+482
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"math"
7+
)
8+
9+
var (
10+
errOverflow = errors.New("errOverflow")
11+
)
12+
13+
func main() {
14+
var a, b int
15+
// Read two integers from standard input
16+
_, err := fmt.Scanf("%d, %d", &a, &b)
17+
if err != nil {
18+
fmt.Println("Error reading input:", err)
19+
return
20+
}
21+
22+
// Call the Sum function and print the result
23+
result, err := Sum(a, b)
24+
if err != nil {
25+
fmt.Println(err)
26+
return
27+
}
28+
fmt.Println(result)
29+
}
30+
31+
// Sum returns the sum of a and b.
32+
func Sum(a int, b int) (int, error) {
33+
if a > 0 && b > math.MaxInt-a || a < 0 && b < math.MinInt-a {
34+
return 0, errOverflow
35+
}
36+
return a + b, nil
37+
}
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: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
type Employee struct {
9+
ID int
10+
Name string
11+
Age int
12+
Salary float64
13+
}
14+
15+
type Manager struct {
16+
Employees []Employee
17+
totalSalary float64
18+
mu sync.RWMutex
19+
}
20+
21+
// AddEmployee adds a new employee to the manager's list.
22+
func (m *Manager) AddEmployee(e Employee) { // O(1) or O(n)
23+
m.mu.Lock()
24+
defer m.mu.Unlock()
25+
m.Employees = append(m.Employees, e) // O(1) or O(n)
26+
m.totalSalary += e.Salary
27+
}
28+
29+
// RemoveEmployee removes an employee by ID from the manager's list.
30+
func (m *Manager) RemoveEmployee(id int) bool { // O(n)
31+
m.mu.Lock()
32+
defer m.mu.Unlock()
33+
for index := range m.Employees {
34+
if m.Employees[index].ID == id {
35+
m.totalSalary -= m.Employees[index].Salary
36+
m.Employees = append(m.Employees[:index], m.Employees[index+1:]...)
37+
return true
38+
}
39+
}
40+
return false
41+
}
42+
43+
// GetAverageSalary calculates the average salary of all employees.
44+
func (m *Manager) GetAverageSalary() float64 { // O(1)
45+
m.mu.RLock()
46+
defer m.mu.RUnlock()
47+
if len(m.Employees) == 0 {
48+
return 0
49+
}
50+
return m.totalSalary / float64(len(m.Employees))
51+
}
52+
53+
// FindEmployeeByID finds and returns an employee by their ID.
54+
func (m *Manager) FindEmployeeByID(id int) *Employee { // O(n)
55+
m.mu.RLock()
56+
defer m.mu.RUnlock()
57+
for index := range m.Employees {
58+
if m.Employees[index].ID == id {
59+
return &m.Employees[index]
60+
}
61+
}
62+
return nil
63+
}
64+
65+
func main() {
66+
manager := Manager{}
67+
manager.AddEmployee(Employee{ID: 1, Name: "Alice", Age: 30, Salary: 70000})
68+
manager.AddEmployee(Employee{ID: 2, Name: "Bob", Age: 25, Salary: 65000})
69+
manager.RemoveEmployee(1)
70+
averageSalary := manager.GetAverageSalary()
71+
employee := manager.FindEmployeeByID(2)
72+
73+
fmt.Printf("Average Salary: %f\n", averageSalary)
74+
if employee != nil {
75+
fmt.Printf("Employee found: %+v\n", *employee)
76+
}
77+
}
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+
"sync"
6+
)
7+
8+
// ConcurrentBFSQueries concurrently processes BFS queries on the provided graph.
9+
// - graph: adjacency list, e.g., graph[u] = []int{v1, v2, ...}
10+
// - queries: a list of starting nodes for BFS.
11+
// - numWorkers: how many goroutines can process BFS queries simultaneously.
12+
//
13+
// Return a map from the query (starting node) to the BFS order as a slice of nodes.
14+
// YOU MUST use concurrency (goroutines + channels) to pass the performance tests.
15+
func ConcurrentBFSQueries(graph map[int][]int, queries []int, numWorkers int) map[int][]int {
16+
if numWorkers <= 0 {
17+
return map[int][]int{}
18+
}
19+
20+
type Result struct {
21+
start int
22+
order []int
23+
}
24+
25+
jobChan := make(chan int)
26+
resultChan := make(chan Result)
27+
28+
var wg sync.WaitGroup
29+
for range numWorkers {
30+
wg.Add(1)
31+
go func() {
32+
defer wg.Done()
33+
for start := range jobChan {
34+
order := bfs(graph, start)
35+
resultChan <- Result{start, order}
36+
}
37+
}()
38+
}
39+
go func() {
40+
wg.Wait()
41+
close(resultChan)
42+
}()
43+
44+
go func() {
45+
for _, start := range queries {
46+
jobChan <- start
47+
}
48+
close(jobChan)
49+
}()
50+
51+
results := make(map[int][]int)
52+
for result := range resultChan {
53+
results[result.start] = result.order
54+
}
55+
56+
return results
57+
}
58+
59+
func bfs(graph map[int][]int, start int) []int {
60+
var neighbors []int
61+
queue := []int{start}
62+
seen := map[int]bool{start: true}
63+
for n := len(queue); n > 0; n = len(queue) {
64+
for i := range n {
65+
node := queue[i]
66+
neighbors = append(neighbors, node)
67+
for _, nei := range graph[node] {
68+
if !seen[nei] {
69+
queue = append(queue, nei)
70+
seen[nei] = true
71+
}
72+
}
73+
}
74+
queue = queue[n:]
75+
}
76+
return neighbors
77+
}
78+
79+
func main() {
80+
// You can insert optional local tests here if desired.
81+
graph := map[int][]int{
82+
0: {1, 2},
83+
1: {2, 3},
84+
2: {3},
85+
3: {4},
86+
4: {},
87+
}
88+
queries := []int{0, 1, 2}
89+
numWorkers := 2
90+
91+
results := ConcurrentBFSQueries(graph, queries, numWorkers)
92+
for start, order := range results {
93+
fmt.Printf("%d -> %v\n", start, order)
94+
}
95+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
)
7+
8+
const validToken = "secret"
9+
10+
// AuthMiddleware checks the "X-Auth-Token" header.
11+
// If it's "secret", call the next handler.
12+
// Otherwise, respond with 401 Unauthorized.
13+
func AuthMiddleware(next http.Handler) http.Handler {
14+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15+
// TODO: Implement the logic:
16+
// 1) Grab the "X-Auth-Token" header
17+
// 2) Compare against validToken
18+
// 3) If mismatch or missing, respond with 401
19+
// 4) Otherwise pass to next handler
20+
token := r.Header.Get("X-Auth-Token")
21+
if token == "" || token != validToken {
22+
http.Error(w, "", http.StatusUnauthorized)
23+
return
24+
}
25+
next.ServeHTTP(w, r)
26+
})
27+
}
28+
29+
// helloHandler returns "Hello!" on GET /hello
30+
func helloHandler(w http.ResponseWriter, r *http.Request) {
31+
fmt.Fprint(w, "Hello!")
32+
}
33+
34+
// secureHandler returns "You are authorized!" on GET /secure
35+
func secureHandler(w http.ResponseWriter, r *http.Request) {
36+
fmt.Fprint(w, "You are authorized!")
37+
}
38+
39+
// SetupServer configures the HTTP routes with the authentication middleware.
40+
func SetupServer() http.Handler {
41+
mux := http.NewServeMux()
42+
43+
// Public route: /hello (no auth required)
44+
mux.HandleFunc("/hello", helloHandler)
45+
46+
// Secure route: /secure
47+
// Wrap with AuthMiddleware
48+
secureRoute := http.HandlerFunc(secureHandler)
49+
mux.Handle("/secure", AuthMiddleware(secureRoute))
50+
51+
return mux
52+
}
53+
54+
func main() {
55+
// Optional: you can run a real server for local testing
56+
http.ListenAndServe(":8081", SetupServer())
57+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Package challenge6 contains the solution for Challenge 6.
2+
package challenge6
3+
4+
import (
5+
"strings"
6+
"unicode"
7+
)
8+
9+
// CountWordFrequency takes a string containing multiple words and returns
10+
// a map where each key is a word and the value is the number of times that
11+
// word appears in the string. The comparison is case-insensitive.
12+
//
13+
// Words are defined as sequences of letters and digits.
14+
// All words are converted to lowercase before counting.
15+
// All punctuation, spaces, and other non-alphanumeric characters are ignored.
16+
//
17+
// For example:
18+
// Input: "The quick brown fox jumps over the lazy dog."
19+
// Output: map[string]int{"the": 2, "quick": 1, "brown": 1, "fox": 1, "jumps": 1, "over": 1, "lazy": 1, "dog": 1}
20+
func CountWordFrequency(text string) map[string]int {
21+
text = strings.ToLower(strings.ReplaceAll(text, "'", ""))
22+
freq := make(map[string]int)
23+
24+
for _, word := range strings.FieldsFunc(text, func(r rune) bool {
25+
return !unicode.IsLetter(r) && !unicode.IsDigit(r)
26+
}) {
27+
freq[word]++
28+
}
29+
return freq
30+
}

0 commit comments

Comments
 (0)