Advertisement
Guest User

Untitled

a guest
Oct 14th, 2019
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.55 KB | None | 0 0
  1. package main
  2.  
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "os"
  9. "strings"
  10. "sync"
  11. )
  12.  
  13. // Player struct for storing player data.
  14. type Player struct {
  15. Name string
  16. GamesPlayed int
  17. AveragePoints float64
  18. }
  19.  
  20. // Monitor for concurrent operations
  21. type Monitor struct {
  22. Players []Player
  23. mutex *sync.Mutex
  24. cond *sync.Cond
  25. currentSize int
  26. done bool
  27. }
  28.  
  29. // ResultData struct for storing results.
  30. type ResultData struct {
  31. ResultingPlayer Player
  32. Efficiency float64
  33. Rank string
  34. }
  35.  
  36. // Results array with mutual exclusion.
  37. type Results struct {
  38. results []ResultData
  39. mutex *sync.Mutex
  40. }
  41.  
  42. func readData(fileName string) []Player {
  43. file, _ := ioutil.ReadFile(fileName)
  44. data := []Player{}
  45. _ = json.Unmarshal(file, &data)
  46. return data
  47. }
  48.  
  49. func initializeMonitor(size int) Monitor {
  50. var Players = make([]Player, size)
  51. var mutex = sync.Mutex{}
  52. var cond = sync.NewCond(&mutex)
  53. var monitor = Monitor{Players, &mutex, cond, 0, false}
  54. return monitor
  55. }
  56.  
  57. func initializeResults() Results {
  58. var results = []ResultData{}
  59. var mutex = sync.Mutex{}
  60. return Results{results, &mutex}
  61. }
  62.  
  63. func (monitor *Monitor) insert(player Player) {
  64. monitor.mutex.Lock()
  65. for monitor.currentSize == len(monitor.Players) {
  66. monitor.cond.Wait()
  67. }
  68. monitor.Players[monitor.currentSize] = player
  69. monitor.currentSize++
  70. monitor.cond.Broadcast()
  71. monitor.mutex.Unlock()
  72. }
  73.  
  74. func (monitor *Monitor) remove() Player {
  75. monitor.mutex.Lock()
  76. for monitor.currentSize == 0 {
  77. if monitor.done {
  78. monitor.cond.Broadcast()
  79. monitor.mutex.Unlock()
  80. return Player{}
  81. }
  82. monitor.cond.Wait()
  83. }
  84. var player = monitor.Players[monitor.currentSize-1]
  85. monitor.Players[monitor.currentSize-1] = Player{}
  86. monitor.currentSize--
  87. monitor.cond.Broadcast()
  88. monitor.mutex.Unlock()
  89. return player
  90. }
  91.  
  92. func (results *Results) insertResult(result ResultData) {
  93. results.mutex.Lock()
  94. inserted := false
  95. for i, v := range results.results {
  96. if v.Efficiency < result.Efficiency {
  97. results.results = append(results.results, ResultData{})
  98. copy(results.results[i+1:], results.results[i:])
  99. results.results[i] = result
  100. inserted = true
  101. break
  102. }
  103. }
  104. if !inserted {
  105. results.results = append(results.results, result)
  106. }
  107. results.mutex.Unlock()
  108. }
  109.  
  110. func performOperation(monitor *Monitor, results *Results, waiter *sync.WaitGroup) {
  111. defer waiter.Done()
  112. for !monitor.done || monitor.currentSize != 0 {
  113. player := monitor.remove()
  114. if player == (Player{}) {
  115. continue
  116. }
  117. result := player.operation()
  118. if result.Efficiency >= 30 {
  119. results.insertResult(result)
  120. }
  121. }
  122. }
  123.  
  124. func (p Player) operation() ResultData {
  125. var efficiency float64 = float64(p.GamesPlayed/8) + p.AveragePoints
  126. var rank string
  127. switch {
  128. case efficiency < 10:
  129. rank = "Useless"
  130. case efficiency < 20:
  131. rank = "Role Player"
  132. case efficiency < 30:
  133. rank = "Starter"
  134. case efficiency < 40:
  135. rank = "Star"
  136. default:
  137. rank = "Superstar"
  138. }
  139. return ResultData{p, efficiency, rank}
  140. }
  141.  
  142. func saveResults(results []ResultData, fileName string) error {
  143. file, err := os.Create(fileName)
  144. if err != nil {
  145. return err
  146. }
  147. defer file.Close()
  148.  
  149. _, err = io.WriteString(file, fmt.Sprintf("| %21s | %12s | %14s | %10s | %11s |\n", "Name", "Games played", "Average points", "Efficiency", "Rank"))
  150. if err != nil {
  151. return err
  152. }
  153. _, err = io.WriteString(file, strings.Repeat("-", 84)+"\n")
  154. if err != nil {
  155. return err
  156. }
  157. for _, v := range results {
  158. _, err = io.WriteString(file, fmt.Sprintf("| %21s | %12d | %14.2f | %10.2f | %11s |\n", v.ResultingPlayer.Name, v.ResultingPlayer.GamesPlayed, v.ResultingPlayer.AveragePoints, v.Efficiency, v.Rank))
  159. if err != nil {
  160. return err
  161. }
  162. }
  163. return file.Sync()
  164. }
  165.  
  166. //const fileName string = "IFF-7-1_GrabauskasM_L1_dat_1.json"
  167. const fileName string = "IFF-7-1_GrabauskasM_L1_dat_2.json"
  168.  
  169. //const fileName string = "IFF-7-1_GrabauskasM_L1_dat_3.json"
  170. const resultFileName string = "IFF-7-1_GrabauskasM_L1_rez.txt"
  171.  
  172. func main() {
  173. data := readData(fileName)
  174. monitor := initializeMonitor(len(data) / 2)
  175. results := initializeResults()
  176. waiter := sync.WaitGroup{}
  177. waiter.Add(5)
  178. for i := 0; i < 5; i++ {
  179. go performOperation(&monitor, &results, &waiter)
  180. }
  181. for _, v := range data {
  182. monitor.insert(v)
  183. }
  184. monitor.mutex.Lock()
  185. monitor.done = true
  186. monitor.cond.Broadcast()
  187. monitor.mutex.Unlock()
  188. waiter.Wait()
  189. err := saveResults(results.results, resultFileName)
  190. if err != nil {
  191. fmt.Println("Writing went wrong.")
  192. }
  193.  
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement