From 312fbbf5a41fe76e847eabccda02bbb52113b3a9 Mon Sep 17 00:00:00 2001 From: Inanc Gumus Date: Thu, 22 Aug 2019 21:21:26 +0300 Subject: [PATCH] update: slices exercise 26 --- .../main.go | 37 +++++---- .../solution/main.go | 6 +- .../exercises/24-fix-the-memory-leak/main.go | 68 ++++++++-------- .../exercises/26-print-daily-requests/main.go | 79 ++++++++++--------- .../26-print-daily-requests/solution/main.go | 29 +++++-- 5 files changed, 122 insertions(+), 97 deletions(-) diff --git a/16-slices/exercises/23-limit-the-backing-array-sharing/main.go b/16-slices/exercises/23-limit-the-backing-array-sharing/main.go index 55dcd36..ee91af5 100644 --- a/16-slices/exercises/23-limit-the-backing-array-sharing/main.go +++ b/16-slices/exercises/23-limit-the-backing-array-sharing/main.go @@ -17,18 +17,23 @@ import ( // EXERCISE: Limit the backing array sharing // // 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 -// a slice. The main function [main()] below uses the -// Read function. +// its `temps` slice. Below, `main()` saves it to the +// `received` slice. // -// `main()` appends to the slice but doing so changes the -// backing array of the api package's temps slice as well. +// `main()` appends to the `received` slice but doing so +// also changes the backing array of the `temps` slice. // We don't want that. // -// Only allow `main()` to change the part of the slice -// it receives from the Read function. +// Only allow `main()` to change the part of the `temps` +// 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 @@ -41,20 +46,20 @@ import ( // | | // v v // api.temps : [5 10 3 1 3 80 90] -// main.temps : [5 10 3 1 3] -// ^ ^ append changes the api package's -// temps slice's backing array. +// main.received : [5 10 3 1 3] +// ^ ^ append changes the `temps` +// slice's backing array. // // // // EXPECTED // -// The corrected api package does not allow the `main()` change -// the api package's temps slice's backing array. +// The corrected api package does not allow the `main()` to +// change unreturned portion of the temps slice's backing array. // | | // v v // 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. // 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 // backing array as well. - slice = append(slice, []int{1, 3}...) + received = append(received, []int{1, 3}...) fmt.Println("api.temps :", api.All()) - fmt.Println("main.slice :", slice) + fmt.Println("main.received :", received) } diff --git a/16-slices/exercises/23-limit-the-backing-array-sharing/solution/main.go b/16-slices/exercises/23-limit-the-backing-array-sharing/solution/main.go index b268b54..7e3141c 100644 --- a/16-slices/exercises/23-limit-the-backing-array-sharing/solution/main.go +++ b/16-slices/exercises/23-limit-the-backing-array-sharing/solution/main.go @@ -14,10 +14,10 @@ import ( ) 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("main.slice :", slice) + fmt.Println("main.received :", received) } diff --git a/16-slices/exercises/24-fix-the-memory-leak/main.go b/16-slices/exercises/24-fix-the-memory-leak/main.go index 87624fe..aaf365d 100644 --- a/16-slices/exercises/24-fix-the-memory-leak/main.go +++ b/16-slices/exercises/24-fix-the-memory-leak/main.go @@ -37,50 +37,52 @@ import ( // memory usage. // // 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. // // -// WHAT YOU NEED TO DO +// WHAT YOU NEED TO DO // // You only need to change the code in `main()`. Please // 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. -// This is the leak. +// + After `api.Read()` call : It uses 65 MB of memory. // -// + 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 -// uses 118 KB of memory. That's why the second -// `api.Report()` call reports only 118 KB. +// It no longer uses 65 MB of memory. Instead, it only +// uses 118 KB of memory. That's why the second +// `api.Report()` call reports 118 KB. // // -// ADDITIONAL NOTE +// ADDITIONAL NOTE // // Memory leak means: Your program is using unnecessary // computer memory. It doesn't release memory that is @@ -88,23 +90,23 @@ import ( // 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 -// 10 elements of the `millions` slice to it. This will -// create a new backing array for the new slice only -// with 10 elements. +// + Make a new slice with 10 elements, and copy the last +// 10 elements of the `millions` slice to it. This will +// create a new backing array for the new slice only +// with 10 elements. // -// Then overwrite the `millions` slice by simply -// assigning `last10` slice to it. +// Then overwrite the `millions` slice by simply +// assigning `last10` slice to it. // -// Remember: slice = pointer to a backing array. -// If you overwrite the slice, it will lose that -// pointer. So Go can collect the unused memory. +// Remember: slice ~= pointer to a backing array. +// If you overwrite the slice, it will lose that +// pointer. So Go can collect the unused memory. // // --------------------------------------------------------- diff --git a/16-slices/exercises/26-print-daily-requests/main.go b/16-slices/exercises/26-print-daily-requests/main.go index 7f6b981..d165141 100644 --- a/16-slices/exercises/26-print-daily-requests/main.go +++ b/16-slices/exercises/26-print-daily-requests/main.go @@ -9,12 +9,39 @@ import ( // EXERCISE: Print daily requests // // You've got request logs of a web server. The log data -// contains 8-hourly totals per each day. Find and print -// the total requests per day, as well as the grand total. +// contains 8-hourly totals per each day. It is stored +// 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. // // +// 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 // // Please run `solution/main.go` to see the expected @@ -25,9 +52,6 @@ import ( // --------------------------------------------------------- func main() { - // ================================================ - // Don't touch this code. - // There are 3 request totals per day (8-hourly) const N = 3 @@ -39,24 +63,19 @@ func main() { 750, 250, 100, // 4th day: 1100 requests // grand total: 5400 requests } + // ================================================ + // #1: Make a new slice with the exact size needed. _ = 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. 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: // [ @@ -65,37 +84,19 @@ func main() { // [900, 800, 600] // [750, 250, 100] // ] - // - // Change this code: - // - // for N < len(reqs) { - // append the daily requests to `daily` per 8-hour groups - // } - // ================================================ + + _ = daily // remove this when you start // ================================================ - // Don't touch the following code: + // #3: Print the results - // Print the header + // Print a header fmt.Printf("%-10s%-10s\n", "Day", "Requests") fmt.Println(strings.Repeat("=", 20)) - // Print the data per day along with the totals - var grand int - - 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) + // Loop over the daily slice and its inner slices to find + // the daily totals and the grand total. + // ... // ================================================ } diff --git a/16-slices/exercises/26-print-daily-requests/solution/main.go b/16-slices/exercises/26-print-daily-requests/solution/main.go index f09e39f..1070185 100644 --- a/16-slices/exercises/26-print-daily-requests/solution/main.go +++ b/16-slices/exercises/26-print-daily-requests/solution/main.go @@ -18,12 +18,25 @@ func main() { // DAILY REQUESTS DATA (PER 8-HOUR) reqs := []int{ - 500, 600, 250, // 1st day - 200, 400, 50, // 2nd day - 900, 800, 600, // 3rd day - 750, 250, 100, // 4th day + 500, 600, 250, // 1st day: 1350 requests + 200, 400, 50, // 2nd day: 650 requests + 900, 800, 600, // 3rd day: 2300 requests + 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. // @@ -54,11 +67,15 @@ func main() { daily = append(daily, reqs[:N]) // append the daily requests 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 fmt.Printf("%-10s%-10s\n", "Day", "Requests") fmt.Println(strings.Repeat("=", 20))