update: slices exercise 26
This commit is contained in:
		| @@ -17,18 +17,23 @@ import ( | |||||||
| // EXERCISE: Limit the backing array sharing | // EXERCISE: Limit the backing array sharing | ||||||
| // | // | ||||||
| //  In this exercise: API means the api package. It's in the | //  In this exercise: API means the api package. It's in the | ||||||
| //  api folder. | //  api folder. You need to change the code in the `api/api.go` | ||||||
|  | //  to solve this exercise. | ||||||
| // | // | ||||||
| //  `Read` function of the api package returns a portion of | //  `Read` function of the api package returns a portion of | ||||||
| //  a slice. The main function [main()] below uses the | //  its `temps` slice. Below, `main()` saves it to the | ||||||
| //  Read function. | //  `received` slice. | ||||||
| // | // | ||||||
| // `main()` appends to the slice but doing so changes the | // `main()` appends to the `received` slice but doing so | ||||||
| //  backing array of the api package's temps slice as well. | //  also changes the backing array of the `temps` slice. | ||||||
| //  We don't want that. | //  We don't want that. | ||||||
| // | // | ||||||
| //  Only allow `main()` to change the part of the slice | //  Only allow `main()` to change the part of the `temps` | ||||||
| //  it receives from the Read function. | //  slice that is returned from the `Read()`. It shouldn't | ||||||
|  | //  change the rest of the `temps`. | ||||||
|  | // | ||||||
|  | //  Remember: `received` and `temps` share the same | ||||||
|  | //  backing array. | ||||||
| // | // | ||||||
| // | // | ||||||
| // NOTE | // NOTE | ||||||
| @@ -41,20 +46,20 @@ import ( | |||||||
| //                           | | | //                           | | | ||||||
| //                           v v | //                           v v | ||||||
| //   api.temps     : [5 10 3 1 3 80 90] | //   api.temps     : [5 10 3 1 3 80 90] | ||||||
| //   main.temps    : [5 10 3 1 3] | //   main.received : [5 10 3 1 3] | ||||||
| //                           ^ ^ append changes the api package's | //                           ^ ^ append changes the `temps` | ||||||
| //                               temps slice's backing array. | //                               slice's backing array. | ||||||
| // | // | ||||||
| // | // | ||||||
| // | // | ||||||
| // EXPECTED | // EXPECTED | ||||||
| // | // | ||||||
| //   The corrected api package does not allow the `main()` change | //   The corrected api package does not allow the `main()` to | ||||||
| //   the api package's temps slice's backing array. | //   change unreturned portion of the temps slice's backing array. | ||||||
| //                           |  | | //                           |  | | ||||||
| //                           v  v | //                           v  v | ||||||
| //   api.temps     : [5 10 3 25 45 80 90] | //   api.temps     : [5 10 3 25 45 80 90] | ||||||
| //   main.temps    : [5 10 3 1 3] | //   main.received : [5 10 3 1 3] | ||||||
| // | // | ||||||
| // --------------------------------------------------------- | // --------------------------------------------------------- | ||||||
|  |  | ||||||
| @@ -62,12 +67,12 @@ func main() { | |||||||
| 	// DO NOT CHANGE ANYTHING IN THIS CODE. | 	// DO NOT CHANGE ANYTHING IN THIS CODE. | ||||||
|  |  | ||||||
| 	// get the first three elements from api.temps | 	// get the first three elements from api.temps | ||||||
| 	slice := api.Read(0, 3) | 	received := api.Read(0, 3) | ||||||
|  |  | ||||||
| 	// append changes the api package's temps slice's | 	// append changes the api package's temps slice's | ||||||
| 	// backing array as well. | 	// backing array as well. | ||||||
| 	slice = append(slice, []int{1, 3}...) | 	received = append(received, []int{1, 3}...) | ||||||
|  |  | ||||||
| 	fmt.Println("api.temps     :", api.All()) | 	fmt.Println("api.temps     :", api.All()) | ||||||
| 	fmt.Println("main.slice    :", slice) | 	fmt.Println("main.received :", received) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,10 +14,10 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
| 	slice := api.Read(0, 3) | 	received := api.Read(0, 3) | ||||||
|  |  | ||||||
| 	slice = append(slice, []int{1, 3}...) | 	received = append(received, []int{1, 3}...) | ||||||
|  |  | ||||||
| 	fmt.Println("api.temps     :", api.All()) | 	fmt.Println("api.temps     :", api.All()) | ||||||
| 	fmt.Println("main.slice    :", slice) | 	fmt.Println("main.received :", received) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,50 +37,52 @@ import ( | |||||||
| //    memory usage. | //    memory usage. | ||||||
| // | // | ||||||
| //    After that, it calls `api.Read()`. `api.Read()` returns | //    After that, it calls `api.Read()`. `api.Read()` returns | ||||||
| //    a slice with 10 million of elements. But you only need | //    a slice with 10 millions of elements. But you only need | ||||||
| //    the last 10 elements of the returned slice. | //    the last 10 elements of the returned slice. | ||||||
| // | // | ||||||
| // | // | ||||||
| // WHAT YOU NEED TO DO | //  WHAT YOU NEED TO DO | ||||||
| // | // | ||||||
| //    You only need to change the code in `main()`. Please | //    You only need to change the code in `main()`. Please | ||||||
| //    do not touch the code in `api/api.go`. | //    do not touch the code in `api/api.go`. | ||||||
| // | // | ||||||
|  |  | ||||||
| // CURRENT OUTPUT |  | ||||||
| // | // | ||||||
| //   > Memory Usage: 113 KB | //  CURRENT OUTPUT | ||||||
| // | // | ||||||
| //   Last 10 elements: [...] | //    > Memory Usage: 113 KB | ||||||
| // | // | ||||||
| //   > Memory Usage: 65651 KB | //    Last 10 elements: [...] | ||||||
| // | // | ||||||
| //     + Before `api.Read()` call: It uses 113 KB of memory. | //    > Memory Usage: 65651 KB | ||||||
| // | // | ||||||
| //     + After `api.Read()` call : It uses  65 MB of memory. | //      + Before `api.Read()` call: It uses 113 KB of memory. | ||||||
| // | // | ||||||
| //     + This means that, `main()` never releases the memory. | //      + After `api.Read()` call : It uses  65 MB of memory. | ||||||
| //       This is the leak. |  | ||||||
| // | // | ||||||
| //     + Your goal is to release the unused memory. | //      + This means that, `main()` never releases the memory. | ||||||
|  | //        This is the leak. | ||||||
|  | // | ||||||
|  | //      + Your goal is to release the unused memory. Remember, | ||||||
|  | //        you only need 10 elements but in the current code | ||||||
|  | //        below you have a slice with 10 millions of elements. | ||||||
| // | // | ||||||
| // | // | ||||||
| // EXPECTED OUTPUT | //  EXPECTED OUTPUT | ||||||
| // | // | ||||||
| //   > Memory Usage: 116 KB | //    > Memory Usage: 116 KB | ||||||
| // | // | ||||||
| //   Last 10 elements: [...] | //    Last 10 elements: [...] | ||||||
| // | // | ||||||
| //   > Memory Usage: 118 KB | //    > Memory Usage: 118 KB | ||||||
| // | // | ||||||
| //     + In the expected output, `main()` releases the memory. | //      + In the expected output, `main()` releases the memory. | ||||||
| // | // | ||||||
| //       It no longer uses 65 MB of memory. Instead, it only | //        It no longer uses 65 MB of memory. Instead, it only | ||||||
| //       uses 118 KB of memory. That's why the second | //        uses 118 KB of memory. That's why the second | ||||||
| //       `api.Report()` call reports only 118 KB. | //        `api.Report()` call reports 118 KB. | ||||||
| // | // | ||||||
| // | // | ||||||
| // ADDITIONAL NOTE | //  ADDITIONAL NOTE | ||||||
| // | // | ||||||
| //    Memory leak means: Your program is using unnecessary | //    Memory leak means: Your program is using unnecessary | ||||||
| //    computer memory. It doesn't release memory that is | //    computer memory. It doesn't release memory that is | ||||||
| @@ -88,23 +90,23 @@ import ( | |||||||
| //    See this: https://en.wikipedia.org/wiki/Memory_leak | //    See this: https://en.wikipedia.org/wiki/Memory_leak | ||||||
| // | // | ||||||
| // | // | ||||||
| // HINTS | //  HINTS | ||||||
| // | // | ||||||
| //   Only read this if you get stuck. | //    Only read this if you get stuck. | ||||||
| // | // | ||||||
| //   + `millions` slice's backing array uses 65 MB of memory. | //    + `millions` slice's backing array uses 65 MB of memory. | ||||||
| // | // | ||||||
| //   + Make a new slice with 10 elements, and copy the last | //    + Make a new slice with 10 elements, and copy the last | ||||||
| //     10 elements of the `millions` slice to it. This will | //      10 elements of the `millions` slice to it. This will | ||||||
| //     create a new backing array for the new slice only | //      create a new backing array for the new slice only | ||||||
| //     with 10 elements. | //      with 10 elements. | ||||||
| // | // | ||||||
| //     Then overwrite the `millions` slice by simply | //      Then overwrite the `millions` slice by simply | ||||||
| //     assigning `last10` slice to it. | //      assigning `last10` slice to it. | ||||||
| // | // | ||||||
| //     Remember: slice = pointer to a backing array. | //      Remember: slice ~= pointer to a backing array. | ||||||
| //     If you overwrite the slice, it will lose that | //      If you overwrite the slice, it will lose that | ||||||
| //     pointer. So Go can collect the unused memory. | //      pointer. So Go can collect the unused memory. | ||||||
| // | // | ||||||
| // --------------------------------------------------------- | // --------------------------------------------------------- | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,12 +9,39 @@ import ( | |||||||
| // EXERCISE: Print daily requests | // EXERCISE: Print daily requests | ||||||
| // | // | ||||||
| //  You've got request logs of a web server. The log data | //  You've got request logs of a web server. The log data | ||||||
| //  contains 8-hourly totals per each day. Find and print | //  contains 8-hourly totals per each day. It is stored | ||||||
| //  the total requests per day, as well as the grand total. | //  in the `reqs` slice. | ||||||
|  | // | ||||||
|  | //  Find and print the total requests per day, as well as | ||||||
|  | //  the grand total. | ||||||
| // | // | ||||||
| //  See the `reqs` slice and the steps in the code below. | //  See the `reqs` slice and the steps in the code below. | ||||||
| // | // | ||||||
| // | // | ||||||
|  | // RESTRICTION | ||||||
|  | // | ||||||
|  | //   Your code should work even if you add to or remove the | ||||||
|  | //   existing elements from the `reqs` slice. | ||||||
|  | // | ||||||
|  | //   For example, after solving the exercise, try it with | ||||||
|  | //   this new data: | ||||||
|  | // | ||||||
|  | //     reqs := []int{ | ||||||
|  | // 	     500, 600, 250, | ||||||
|  | // 	     200, 400, 50, | ||||||
|  | // 	     900, 800, 600, | ||||||
|  | // 	     750, 250, 100, | ||||||
|  | // 	     150, 654, 235, | ||||||
|  | // 	     320, 534, 765, | ||||||
|  | // 	     121, 876, 285, | ||||||
|  | // 	     543, 642, | ||||||
|  | // 	     // the last element is missing (your code should be able to handle this) | ||||||
|  | // 	     // that is why you shouldn't calculate the `size` below manually. | ||||||
|  | //     } | ||||||
|  | // | ||||||
|  | //     The grand total of the new data should be 10525. | ||||||
|  | // | ||||||
|  | // | ||||||
| // EXPECTED OUTPUT | // EXPECTED OUTPUT | ||||||
| // | // | ||||||
| //   Please run `solution/main.go` to see the expected | //   Please run `solution/main.go` to see the expected | ||||||
| @@ -25,9 +52,6 @@ import ( | |||||||
| // --------------------------------------------------------- | // --------------------------------------------------------- | ||||||
|  |  | ||||||
| func main() { | func main() { | ||||||
| 	// ================================================ |  | ||||||
| 	// Don't touch this code. |  | ||||||
|  |  | ||||||
| 	// There are 3 request totals per day (8-hourly) | 	// There are 3 request totals per day (8-hourly) | ||||||
| 	const N = 3 | 	const N = 3 | ||||||
|  |  | ||||||
| @@ -39,24 +63,19 @@ func main() { | |||||||
| 		750, 250, 100, // 4th day: 1100 requests | 		750, 250, 100, // 4th day: 1100 requests | ||||||
| 		// grand total: 5400 requests | 		// grand total: 5400 requests | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
|  | 	// #1: Make a new slice with the exact size needed. | ||||||
|  |  | ||||||
| 	_ = reqs // remove this when you start | 	_ = reqs // remove this when you start | ||||||
|  |  | ||||||
| 	// ================================================ |  | ||||||
| 	// Allocate a slice efficiently with the exact size needed. |  | ||||||
| 	// |  | ||||||
| 	// Find the `size` automatically using the `reqs` slice. |  | ||||||
| 	// Do not type it manually. |  | ||||||
| 	// |  | ||||||
| 	// Change this code: |  | ||||||
| 	size := 0 // you need to find the size. | 	size := 0 // you need to find the size. | ||||||
| 	daily := make([][]int, 0, size) | 	daily := make([][]int, 0, size) | ||||||
| 	// |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
| 	// Group the `reqs` per day into the slice: `daily`. | 	// #2: Group the `reqs` per day into the slice: `daily`. | ||||||
| 	// | 	// | ||||||
| 	// So the daily will be: | 	// So the daily will be: | ||||||
| 	// [ | 	// [ | ||||||
| @@ -65,37 +84,19 @@ func main() { | |||||||
| 	//  [900, 800, 600] | 	//  [900, 800, 600] | ||||||
| 	//  [750, 250, 100] | 	//  [750, 250, 100] | ||||||
| 	// ] | 	// ] | ||||||
| 	// |  | ||||||
| 	// Change this code: | 	_ = daily // remove this when you start | ||||||
| 	// |  | ||||||
| 	// for N < len(reqs) { |  | ||||||
| 	//   append the daily requests to `daily` per 8-hour groups |  | ||||||
| 	// } |  | ||||||
| 	// ================================================ |  | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
| 	// Don't touch the following code: | 	// #3: Print the results | ||||||
|  |  | ||||||
| 	// Print the header | 	// Print a header | ||||||
| 	fmt.Printf("%-10s%-10s\n", "Day", "Requests") | 	fmt.Printf("%-10s%-10s\n", "Day", "Requests") | ||||||
| 	fmt.Println(strings.Repeat("=", 20)) | 	fmt.Println(strings.Repeat("=", 20)) | ||||||
|  |  | ||||||
| 	// Print the data per day along with the totals | 	// Loop over the daily slice and its inner slices to find | ||||||
| 	var grand int | 	// the daily totals and the grand total. | ||||||
|  | 	// ... | ||||||
| 	for i, day := range daily { |  | ||||||
| 		var sum int |  | ||||||
|  |  | ||||||
| 		for _, req := range day { |  | ||||||
| 			sum += req |  | ||||||
| 			fmt.Printf("%-10d%-10d\n", i+1, req) |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		fmt.Printf("%9s %-10d\n\n", "TOTAL:", sum) |  | ||||||
|  |  | ||||||
| 		grand += sum |  | ||||||
| 	} |  | ||||||
| 	fmt.Printf("%9s %-10d\n", "GRAND:", grand) |  | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,12 +18,25 @@ func main() { | |||||||
|  |  | ||||||
| 	// DAILY REQUESTS DATA (PER 8-HOUR) | 	// DAILY REQUESTS DATA (PER 8-HOUR) | ||||||
| 	reqs := []int{ | 	reqs := []int{ | ||||||
| 		500, 600, 250, // 1st day | 		500, 600, 250, // 1st day: 1350 requests | ||||||
| 		200, 400, 50, // 2nd day | 		200, 400, 50, // 2nd day: 650 requests | ||||||
| 		900, 800, 600, // 3rd day | 		900, 800, 600, // 3rd day: 2300 requests | ||||||
| 		750, 250, 100, // 4th day | 		750, 250, 100, // 4th day: 1100 requests | ||||||
|  | 		// grand total: 5400 requests | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// ALSO TRY IT WITH THIS DATA: | ||||||
|  | 	// reqs = []int{ | ||||||
|  | 	// 	500, 600, 250, | ||||||
|  | 	// 	200, 400, 50, | ||||||
|  | 	// 	900, 800, 600, | ||||||
|  | 	// 	750, 250, 100, | ||||||
|  | 	// 	150, 654, 235, | ||||||
|  | 	// 	320, 534, 765, | ||||||
|  | 	// 	121, 876, 285, | ||||||
|  | 	// 	543, 642, | ||||||
|  | 	// } | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
| 	// Allocate a slice efficiently with the exact size needed. | 	// Allocate a slice efficiently with the exact size needed. | ||||||
| 	// | 	// | ||||||
| @@ -54,11 +67,15 @@ func main() { | |||||||
| 		daily = append(daily, reqs[:N]) // append the daily requests | 		daily = append(daily, reqs[:N]) // append the daily requests | ||||||
| 		reqs = reqs[N:]                 // move the slice pointer for the next day | 		reqs = reqs[N:]                 // move the slice pointer for the next day | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// add the residual data | ||||||
|  | 	if len(reqs) > 0 { | ||||||
|  | 		daily = append(daily, reqs) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
|  |  | ||||||
| 	// ================================================ | 	// ================================================ | ||||||
| 	// Don't touch the following code: |  | ||||||
|  |  | ||||||
| 	// Print the header | 	// Print the header | ||||||
| 	fmt.Printf("%-10s%-10s\n", "Day", "Requests") | 	fmt.Printf("%-10s%-10s\n", "Day", "Requests") | ||||||
| 	fmt.Println(strings.Repeat("=", 20)) | 	fmt.Println(strings.Repeat("=", 20)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user