add: slice adv. ops. exercises
This commit is contained in:
		
							
								
								
									
										143
									
								
								16-slices/exercises/22-adv-ops-practice/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								16-slices/exercises/22-adv-ops-practice/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,143 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	s "github.com/inancgumus/prettyslice" | ||||
| ) | ||||
|  | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: Practice advanced slice operations | ||||
| // | ||||
| //  This exercise's intention is warm you up and reinforce | ||||
| //  your memory for the advanced slice operations. | ||||
| // | ||||
| //  Please follow the directions in the following code. | ||||
| // | ||||
| //  To see the expected output, please run: | ||||
| // | ||||
| //    go run solution/main.go | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
|  | ||||
| func main() { | ||||
| 	// | ||||
| 	// Use the prettyslice package for printing the slices, | ||||
| 	// or do it with your own Printf that matches the output | ||||
| 	// of the prettyslice package. | ||||
| 	// | ||||
|  | ||||
| 	// This allows you to see the backing array of the slices. | ||||
| 	s.PrintBacking = true | ||||
| 	// Shows 10 slice elements per line | ||||
| 	s.MaxPerLine = 10 | ||||
| 	// Prints 60 character per line | ||||
| 	s.Width = 60 | ||||
|  | ||||
| 	// ######################################################## | ||||
| 	// | ||||
| 	// #1: Create a string slice with a length and capacity | ||||
| 	//     of 5. Call the slice: `names` and print it. | ||||
| 	// | ||||
|  | ||||
| 	// ... | ||||
| 	// s.Show("1st step", names) | ||||
|  | ||||
| 	// ######################################################## | ||||
| 	// | ||||
| 	// #2: Append the following names to the names slice: | ||||
| 	// | ||||
| 	//     "einstein", "tesla", "aristo" | ||||
| 	// | ||||
| 	//     Print the names slice. | ||||
| 	// | ||||
| 	//     Observe how the slice and its backing array change. | ||||
| 	// | ||||
|  | ||||
| 	// ... | ||||
| 	// s.Show("2nd step", names) | ||||
|  | ||||
| 	// ######################################################## | ||||
| 	// | ||||
| 	// #3: Fix the append problem by reinitializing the | ||||
| 	//     names slice below (currently the previous code | ||||
| 	//     appends after 5 elements). | ||||
| 	// | ||||
| 	//     Append the new elements to the head of the names | ||||
| 	//     slice instead. | ||||
| 	// | ||||
| 	//     Print the names slice. | ||||
| 	// | ||||
| 	// HINT: | ||||
| 	// | ||||
| 	//    The problem is in the `make` function. | ||||
| 	// | ||||
|  | ||||
| 	// ... | ||||
| 	// s.Show("3rd step", names) | ||||
|  | ||||
| 	// ######################################################## | ||||
| 	// | ||||
| 	// #4: Copy elements from an array to the `names` slice. | ||||
| 	// | ||||
| 	//     Currently, `cap(names)` is 5. So, copy only | ||||
| 	//     the first two elements of the following array | ||||
| 	//     to the last two elements of the `names` slice. | ||||
| 	// | ||||
| 	//     Print the names slice (do not forget extending it). | ||||
| 	//     You should print 5 elements. | ||||
| 	// | ||||
| 	//     Observe how the backing array stays the same. | ||||
| 	// | ||||
|  | ||||
| 	// Array (uncomment): | ||||
| 	// moreNames := [...]string{"plato", "khayyam", "ptolemy"} | ||||
|  | ||||
| 	// ... | ||||
|  | ||||
| 	// s.Show("4th step", names) | ||||
|  | ||||
| 	// ######################################################## | ||||
| 	// | ||||
| 	// #5: Clone the `names` slice to the `clone` slice. | ||||
| 	// | ||||
| 	//     But only clone (copy) the last 3 elements of the | ||||
| 	//     `names` slice. | ||||
| 	// | ||||
| 	//     Then, append the first two elements of the `names` | ||||
| 	//     slice to the `clone` slice. | ||||
| 	// | ||||
| 	//     Ensure that after appending no new backing array | ||||
| 	//     allocations occur for the `clone` slice. | ||||
| 	// | ||||
| 	//     Print the clone slice before and after the append. | ||||
| 	// | ||||
|  | ||||
| 	// ... | ||||
| 	// s.Show("5th step (before append)", clone) | ||||
|  | ||||
| 	// ... | ||||
| 	// s.Show("5th step (after append)", clone) | ||||
|  | ||||
| 	// ######################################################## | ||||
| 	// | ||||
| 	// #6: Slice the `clone` slice between 2nd and 4th | ||||
| 	//     elements. | ||||
| 	// | ||||
| 	//     Put the sliced slice into a variable named: | ||||
| 	//     `sliced`. | ||||
| 	// | ||||
| 	//     Append "hypatia" to the `sliced` slice. | ||||
| 	// | ||||
| 	//     Ensure that new backing array allocation "happens". | ||||
| 	// | ||||
| 	//       Change the 3rd element of the `clone` slice | ||||
| 	//       to "elder". | ||||
| 	// | ||||
| 	//       Doing so should not change any elements of | ||||
| 	//       the `sliced` slice. | ||||
| 	// | ||||
| 	//     Print the `clone` and `sliced` slices. | ||||
| 	// | ||||
|  | ||||
| 	// ... | ||||
| 	// s.Show("6th step", clone, sliced) | ||||
| } | ||||
							
								
								
									
										71
									
								
								16-slices/exercises/22-adv-ops-practice/solution/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								16-slices/exercises/22-adv-ops-practice/solution/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	s "github.com/inancgumus/prettyslice" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	s.PrintBacking = true | ||||
| 	s.MaxPerLine = 10 | ||||
| 	s.Width = 60 | ||||
|  | ||||
| 	// | ||||
| 	// #1 | ||||
| 	// | ||||
|  | ||||
| 	names := make([]string, 5) | ||||
| 	s.Show("1st step", names) | ||||
|  | ||||
| 	// | ||||
| 	// #2 | ||||
| 	// | ||||
|  | ||||
| 	names = append(names, "einstein", "tesla", "aristo") | ||||
| 	s.Show("2nd step", names) | ||||
|  | ||||
| 	// | ||||
| 	// #3 | ||||
| 	// | ||||
| 	names = make([]string, 0, 5) | ||||
| 	names = append(names, "einstein", "tesla", "aristo") | ||||
| 	s.Show("3rd step", names) | ||||
|  | ||||
| 	// | ||||
| 	// #4 | ||||
| 	// | ||||
|  | ||||
| 	moreNames := [...]string{"plato", "khayyam", "ptolemy"} | ||||
| 	copy(names[3:5], moreNames[:2]) | ||||
| 	names = names[:cap(names)] | ||||
|  | ||||
| 	s.Show("4th step", names) | ||||
|  | ||||
| 	// | ||||
| 	// #5 | ||||
| 	// | ||||
|  | ||||
| 	clone := make([]string, 3, 5) | ||||
| 	copy(clone, names[len(names)-3:]) | ||||
| 	s.Show("5th step (before append)", clone) | ||||
|  | ||||
| 	clone = append(clone, names[:2]...) | ||||
| 	s.Show("5th step (after append)", clone) | ||||
|  | ||||
| 	// | ||||
| 	// #6 | ||||
| 	// | ||||
|  | ||||
| 	sliced := clone[1:4:4] | ||||
| 	sliced = append(sliced, "hypatia") | ||||
|  | ||||
| 	clone[2] = "elder" | ||||
|  | ||||
| 	s.Show("6th step", clone, sliced) | ||||
| } | ||||
| @@ -10,7 +10,7 @@ package main | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/inancgumus/learngo/16-slices/exercises/19-limit-the-backing-array-sharing/api" | ||||
| 	"github.com/inancgumus/learngo/16-slices/exercises/23-limit-the-backing-array-sharing/api" | ||||
| ) | ||||
| 
 | ||||
| // --------------------------------------------------------- | ||||
| @@ -10,12 +10,11 @@ package main | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/inancgumus/learngo/16-slices/exercises/19-limit-the-backing-array-sharing/solution/api" | ||||
| 	"github.com/inancgumus/learngo/16-slices/exercises/23-limit-the-backing-array-sharing/solution/api" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	temps := api.Read(0, 3) | ||||
| 
 | ||||
| 	temps = append(temps, []int{1, 3}...) | ||||
| 
 | ||||
| 	fmt.Println("API's readings:", api.All()) | ||||
							
								
								
									
										24
									
								
								16-slices/exercises/24-fix-the-memory-leak/api/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								16-slices/exercises/24-fix-the-memory-leak/api/api.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"runtime" | ||||
| ) | ||||
|  | ||||
| // DO NOT TOUCH THE FOLLOWING CODE | ||||
| // THIS IS THE API | ||||
| // YOU CANNOT CONTROL IT! :) | ||||
|  | ||||
| // Read returns a huge slice (allocates ~65 MB of memory) | ||||
| func Read() []int { | ||||
| 	return rand.Perm(2 << 22) | ||||
| } | ||||
|  | ||||
| // Report cleans the memory and prints the current memory usage | ||||
| func Report() { | ||||
| 	var m runtime.MemStats | ||||
| 	runtime.GC() | ||||
| 	runtime.ReadMemStats(&m) | ||||
| 	fmt.Printf(" > Memory Usage: %v KB\n", m.Alloc/1024) | ||||
| } | ||||
							
								
								
									
										67
									
								
								16-slices/exercises/24-fix-the-memory-leak/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								16-slices/exercises/24-fix-the-memory-leak/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
|  | ||||
| 	"github.com/inancgumus/learngo/16-slices/exercises/24-fix-the-memory-leak/api" | ||||
| ) | ||||
|  | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: Fix the memory leak | ||||
| // | ||||
| //  You're receiving millions of temperature data points from | ||||
| //  an API, but you only need the last 10 data points. | ||||
| // | ||||
| //  Currently, there is a memory leak in your program. | ||||
| //  Find the leak and fix it. | ||||
| // | ||||
| // | ||||
| // EXPECTED OUTPUT | ||||
| // | ||||
| //   > Memory Usage: 116 KB | ||||
| //   > Memory Usage: 118 KB | ||||
| // | ||||
| // | ||||
| // EXPECTED OUTPUT EXPLANATION | ||||
| // | ||||
| //   Your output will be different. Your goal is to reduce the | ||||
| //   difference between the two measurements of the memory usage. | ||||
| // | ||||
| //   For the expected output above: | ||||
| // | ||||
| //     118 KB - 116 KB = Only 2 KB so that's OK. | ||||
| // | ||||
| //   However, in the current program, because of the memory leak, | ||||
| //   the difference is huge: about ~60 MB. Run the program and, | ||||
| //   see yourself. | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
|  | ||||
| func main() { | ||||
| 	// reports the initial memory usage | ||||
| 	api.Report() | ||||
|  | ||||
| 	// reads 65 MB of temperature data into the memory! | ||||
| 	temps := api.Read() | ||||
|  | ||||
| 	// ----------------------------------------------------- | ||||
| 	// ✪ ONLY ADD YOUR CODE INSIDE THIS BOX ✪ | ||||
| 	// | ||||
|  | ||||
| 	// | ||||
| 	// ✪ ONLY ADD YOUR CODE INSIDE THIS BOX ✪ | ||||
| 	// ----------------------------------------------------- | ||||
|  | ||||
| 	// fix the problem so that the memory usage stays low | ||||
| 	// dont touch this code | ||||
| 	api.Report() | ||||
| 	fmt.Fprintln(ioutil.Discard, temps[0]) | ||||
| } | ||||
| @@ -0,0 +1,24 @@ | ||||
| package api | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"runtime" | ||||
| ) | ||||
|  | ||||
| // DO NOT TOUCH THE FOLLOWING CODE | ||||
| // THIS IS THE API | ||||
| // YOU CANNOT CONTROL IT! :) | ||||
|  | ||||
| // Read returns a huge slice (allocates ~65 MB of memory) | ||||
| func Read() []int { | ||||
| 	return rand.Perm(2 << 22) | ||||
| } | ||||
|  | ||||
| // Report cleans the memory and prints the current memory usage | ||||
| func Report() { | ||||
| 	var m runtime.MemStats | ||||
| 	runtime.GC() | ||||
| 	runtime.ReadMemStats(&m) | ||||
| 	fmt.Printf(" > Memory Usage: %v KB\n", m.Alloc/1024) | ||||
| } | ||||
							
								
								
									
										45
									
								
								16-slices/exercises/24-fix-the-memory-leak/solution/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								16-slices/exercises/24-fix-the-memory-leak/solution/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
|  | ||||
| 	"github.com/inancgumus/learngo/16-slices/exercises/24-fix-the-memory-leak/solution/api" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	// reports the initial memory usage | ||||
| 	api.Report() | ||||
|  | ||||
| 	// reads 65 MB of temperature data into the memory! | ||||
| 	temps := api.Read() | ||||
|  | ||||
| 	// | ||||
| 	// SOLUTION #1: | ||||
| 	// | ||||
|  | ||||
| 	// clone the last 10 elements of the returned temperatures | ||||
| 	// into a new slice | ||||
| 	need := make([]int, 10) | ||||
| 	copy(need, temps[len(temps)-10:]) | ||||
| 	// make the temp slice lose reference to its backing array | ||||
| 	// so that it can be cleaned from the memory | ||||
| 	temps = need | ||||
|  | ||||
| 	// | ||||
| 	// SOLUTION #2: | ||||
| 	// | ||||
|  | ||||
| 	// The code below does the same thing like the code above but in one line. | ||||
| 	// temps = append([]int(nil), temps[len(temps)-10:]...) | ||||
|  | ||||
| 	api.Report() | ||||
| 	fmt.Fprintln(ioutil.Discard, temps[0]) | ||||
| } | ||||
							
								
								
									
										119
									
								
								16-slices/exercises/25-add-lines/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								16-slices/exercises/25-add-lines/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	s "github.com/inancgumus/prettyslice" | ||||
| ) | ||||
|  | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: Add newlines to the lyric sentences | ||||
| // | ||||
| //  You have a slice of lyrics data of Beatles' awesome | ||||
| //  song: Yesterday. Your goal is adding newlines after | ||||
| //  each sentence of the lyric. | ||||
| // | ||||
| //  Your goal is creating a new slice, then copying | ||||
| //  each sentence of the lyric to the new buffer, then | ||||
| //  after each sentence adding a newline character. | ||||
| // | ||||
| //  You cannot guess how many times you will get across | ||||
| //  something like this. Believe me, learning this will | ||||
| //  make you a better Gopher. | ||||
| // | ||||
| // | ||||
| // RESTRICTIONS | ||||
| // | ||||
| //  . For warming-up, in this exercise, never use the `append()` func. | ||||
| // | ||||
| //  	. Instead, only use the `copy()` func. | ||||
| // | ||||
| //  . You cannot use slicing for printing the sentences. | ||||
| // | ||||
| //    . Instead, use slicing to fill the new buffer, then print it. | ||||
| // | ||||
| // | ||||
| // STEPS | ||||
| // | ||||
| //  . Follow the instructions inside the code. | ||||
| // | ||||
| // | ||||
| // EXPECTED OUTPUT | ||||
| // | ||||
| //  yesterday all my troubles seemed so far away | ||||
| //  now it looks as though they are here to stay | ||||
| //  oh i believe in yesterday | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
|  | ||||
| func main() { | ||||
| 	// | ||||
| 	// YOU DON'T NEED TO TOUCH THIS | ||||
| 	// | ||||
| 	// This inits some options for the prettyslice package. | ||||
| 	// You can change the options if you want. | ||||
| 	// | ||||
| 	// s.Colors(false)     // if your editor is light colored then enable this | ||||
| 	s.PrintBacking = true  // prints the backing arrays | ||||
| 	s.MaxPerLine = 15      // prints max 15 elements per line | ||||
| 	s.SpaceCharacter = "*" // print this instead of printing a newline (for debugging) | ||||
|  | ||||
| 	// | ||||
| 	// UNCOMMENT THE VARIABLE BELOW THEN START! | ||||
| 	// | ||||
|  | ||||
| 	// lyric := strings.Fields(`yesterday all my troubles seemed so far away now it looks as though they are here to stay oh i believe in yesterday`) | ||||
|  | ||||
| 	// | ||||
| 	// RESTRICTION EXPLANATION: | ||||
| 	// | ||||
| 	// Don't do something like this: | ||||
| 	// (Do not use slicing for printing the sentences) | ||||
| 	// | ||||
|  | ||||
| 	// fmt.Println(lyric[:8]) | ||||
| 	// fmt.Println(lyric[8:18]) | ||||
| 	// fmt.Println(lyric[18:23]) | ||||
|  | ||||
| 	// ======================================================================== | ||||
| 	// | ||||
| 	// #1: CREATE A LARGE ENOUGH BUFFER (A NEW SLICE) | ||||
| 	// | ||||
| 	//     You need to put each lyric sentence + a newline into this buffer | ||||
| 	// | ||||
|  | ||||
| 	// I name the buffer: `fix`, you can name it however you want | ||||
| 	// fix := make(...) | ||||
|  | ||||
| 	// ======================================================================== | ||||
| 	// | ||||
| 	// #2: CALCULATE THE CUT POINTS | ||||
| 	// | ||||
| 	//     You want to put newlines after each sentence. So you may want to put | ||||
| 	//     these index positions into a slice. Then you can use them to cut the | ||||
| 	//     lyric slice. | ||||
| 	// | ||||
|  | ||||
| 	// cutpoints := []int{...} | ||||
|  | ||||
| 	// ======================================================================== | ||||
| 	// | ||||
| 	// #3: CREATE A LOOP AND COPY THE SENTENCES INTO THE BUFFER | ||||
| 	// | ||||
|  | ||||
| 	// for ... { | ||||
| 	//   Use the `copy` function to copy from the `lyric` slice to the buffer. | ||||
| 	// | ||||
| 	//   Copy a newline character (in a string) to the buffer after each sentence. | ||||
| 	// | ||||
| 	//   You can use slicing here for filling the new buffer. | ||||
| 	// | ||||
| 	//   Uncomment this to aid debugging (to see how the fix slice changes) | ||||
| 	//   s.Show("fix slice", fix) | ||||
| 	// } | ||||
|  | ||||
| 	// ======================================================================== | ||||
| 	// | ||||
| 	// #4: PRINT THE BUFFER | ||||
| 	// | ||||
|  | ||||
| 	// ... | ||||
| } | ||||
							
								
								
									
										93
									
								
								16-slices/exercises/25-add-lines/solution/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								16-slices/exercises/25-add-lines/solution/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	s "github.com/inancgumus/prettyslice" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	// | ||||
| 	// YOU DON'T NEED TO TOUCH THIS | ||||
| 	// | ||||
| 	// This inits some options for the prettyslice package. | ||||
| 	// You can change the options if you want. | ||||
| 	// | ||||
| 	// s.Colors(false)     // if your editor is light colored then enable this | ||||
| 	s.PrintBacking = true  // prints the backing arrays | ||||
| 	s.MaxPerLine = 15      // prints max 15 elements per line | ||||
| 	s.SpaceCharacter = "*" // print this instead of printing a newline (for debugging) | ||||
|  | ||||
| 	lyric := strings.Fields(`yesterday all my troubles seemed so far away now it looks as though they are here to stay oh i believe in yesterday`) | ||||
|  | ||||
| 	// CREATE A LARGE ENOUGH BUFFER | ||||
| 	// `+3` because we're going to add 3 newline characters | ||||
| 	fix := make([]string, len(lyric)+3) | ||||
|  | ||||
| 	// CALCULATE THE CUT POINTS | ||||
| 	// | ||||
| 	// + The first sentence has 8 words so its cutpoint is 8. | ||||
| 	// | ||||
| 	// + The second one has 10 words so its cutpoint is 10. | ||||
| 	// | ||||
| 	// + The third one has 5 words so its cutpoint is 5. | ||||
| 	// | ||||
| 	// | ||||
| 	// yesterday all my troubles seemed so far away now it looks as though they are here to stay | ||||
| 	//                                         | | ||||
| 	//                                         v | ||||
| 	//                               cutpoint: 8 | ||||
| 	// | ||||
| 	// ... now it looks as though they are here to stay oh i believe in yesterday | ||||
| 	//                                             | | ||||
| 	//                                             v | ||||
| 	//                                             10 | ||||
| 	// | ||||
| 	// ... now it looks as though they are here to stay oh i believe in yesterday | ||||
| 	//                                                                  | | ||||
| 	//                                                                  v | ||||
| 	//                                                                  5 | ||||
| 	cutpoints := []int{8, 10, 5} | ||||
|  | ||||
| 	// `n` tracks how much we've moved inside the `lyric` slice | ||||
| 	// `i` tracks the sentence that we're on | ||||
| 	for i, n := 0, 0; n < len(lyric); i++ { | ||||
| 		// | ||||
| 		// copy to `fix` from the `lyric` | ||||
| 		// | ||||
| 		//   destination: | ||||
| 		//     fix[n+i] because we don't want to delete the previous copy. | ||||
| 		//     it moves sentence by sentence, using the cutpoints. | ||||
| 		// | ||||
| 		//   source: | ||||
| 		//     lyric[n:n+cutpoints[i]] because we want copy the next sentence | ||||
| 		//     beginning from the number of the last copied elements to the | ||||
| 		//     n+next cutpoint (the next sentence). | ||||
| 		// | ||||
| 		n += copy(fix[n+i:], lyric[n:n+cutpoints[i]]) | ||||
|  | ||||
| 		// add a newline after the number of copied elements | ||||
| 		// notice that the '\n' position slides as we move over | ||||
| 		// that's why n+i | ||||
| 		fix[n+i] = "\n" | ||||
|  | ||||
| 		// uncomment this to aid debugging (to see how the fix slice changes) | ||||
| 		// s.Show("fix slice", fix) | ||||
| 	} | ||||
|  | ||||
| 	// print the fix slice | ||||
| 	for _, w := range fix { | ||||
| 		fmt.Print(w) | ||||
| 		if w != "\n" { | ||||
| 			fmt.Print(" ") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										104
									
								
								16-slices/exercises/26-print-daily-requests/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								16-slices/exercises/26-print-daily-requests/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| package main | ||||
|  | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: Print daily requests | ||||
| // | ||||
| //  You've got a requests log for a system in a slice: `reqs`. | ||||
| //  The log contains the total requests counts per 8 hours. | ||||
| // | ||||
| //  The reqs slice is a single-dimensional slice but you need | ||||
| //  to group the daily into a slice named: `daily`. | ||||
| // | ||||
| //  Please follow the instructions inside the code to solve | ||||
| //  the exercise. | ||||
| // | ||||
| // | ||||
| // EXPECTED OUTPUT | ||||
| // | ||||
| //   Please run `solution/main.go` to see the expected | ||||
| //   output. | ||||
| // | ||||
| //   go run solution/main.go | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
|  | ||||
| func main() { | ||||
| 	// | ||||
| 	// #1: DAILY REQUESTS DATA | ||||
| 	// | ||||
| 	// . The system collects and groups the requests per 8 hours | ||||
| 	// | ||||
| 	// . So there are 3 requests totals per day | ||||
| 	// | ||||
| 	// . Your code should be robust enough to work with | ||||
| 	//   insufficient data. For example, in the last day | ||||
| 	//   there are only two request totals: 100 and 150. | ||||
| 	// | ||||
| 	//   So, don't forget to handle that edge case as well. | ||||
| 	// | ||||
| 	// . Uncomment the code below and start | ||||
| 	// | ||||
|  | ||||
| 	// reqs := []int{ | ||||
| 	// 	500, 600, 250, | ||||
| 	// 	200, 400, 50, | ||||
| 	// 	900, 800, 600, | ||||
| 	// 	750, 250, 100, | ||||
| 	// 	100, 150, | ||||
| 	// } | ||||
|  | ||||
| 	// | ||||
| 	// #2: Group the `reqs` per day into a slice named: `daily` | ||||
| 	// | ||||
| 	// . Create the daily slice using the `make` function | ||||
| 	// | ||||
| 	// . Anticipate the length argument to the make function using this data: | ||||
| 	// | ||||
| 	//   + The length of the reqs slice | ||||
| 	//   + There are 3 requests totals per day | ||||
| 	//   + There are residual elements (the last day) | ||||
| 	// | ||||
| 	//   ! So, do not blindly allocate a slice. | ||||
| 	// | ||||
| 	//   ! Allocate the slice efficiently with the exact size needed. | ||||
| 	// | ||||
| 	// . Then append to it the daily requests in a "loop" | ||||
| 	// | ||||
|  | ||||
| 	// | ||||
| 	// #3: Print the header: | ||||
| 	// | ||||
| 	// Day       Requests | ||||
| 	// ==================== | ||||
| 	// | ||||
|  | ||||
| 	// | ||||
| 	// #4: Print the data per day along with the totals: | ||||
| 	// | ||||
| 	// 1         500 | ||||
| 	// 1         600 | ||||
| 	// 1         250 | ||||
| 	// -------------------- | ||||
| 	//           1350  --> Print the daily total requests | ||||
| 	// | ||||
| 	// 2         200 | ||||
| 	// 2         400 | ||||
| 	// 2         50 | ||||
| 	// -------------------- | ||||
| 	//           650 | ||||
| 	// | ||||
| 	//           2000  --> Also print the grand total | ||||
|  | ||||
| 	// ------------------------------------------------------------------------ | ||||
| 	// | ||||
| 	// ❤️ NOTE ❤️ | ||||
| 	// | ||||
| 	// If you could't solve this challenge. Please do not get discouraged. | ||||
| 	// | ||||
| 	// Look at the solution, then try to solve it again. This is valuable too. | ||||
| 	// | ||||
| 	// Then ️change the request data, the number of requests per day (now it's 3), etc | ||||
| 	// and then try to solve it again. | ||||
| 	// | ||||
| 	// ------------------------------------------------------------------------ | ||||
| } | ||||
							
								
								
									
										81
									
								
								16-slices/exercises/26-print-daily-requests/solution/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								16-slices/exercises/26-print-daily-requests/solution/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	// | ||||
| 	// DAILY REQUESTS DATA | ||||
| 	// | ||||
| 	reqs := []int{ | ||||
| 		500, 600, 250, | ||||
| 		200, 400, 50, | ||||
| 		900, 800, 600, | ||||
| 		750, 250, 100, | ||||
| 		100, 150, | ||||
| 	} | ||||
|  | ||||
| 	// | ||||
| 	// There are 3 requests per day | ||||
| 	// | ||||
| 	const N = 3 | ||||
|  | ||||
| 	// | ||||
| 	// Allocate the slice efficiently with the exact size needed | ||||
| 	// | ||||
| 	l := len(reqs) | ||||
| 	size := l / N | ||||
| 	if l%N != 0 { | ||||
| 		size++ | ||||
| 	} | ||||
| 	daily := make([][]int, 0, size) | ||||
|  | ||||
| 	// | ||||
| 	// Group the `reqs` per day into a slice named: `daily` | ||||
| 	// | ||||
| 	for N < len(reqs) { | ||||
| 		daily = append(daily, reqs[:N]) // add the current batch of nums to the `groups` | ||||
| 		reqs = reqs[N:]                 // move the slice pointer for the next batch | ||||
| 	} | ||||
|  | ||||
| 	// | ||||
| 	// Add the residual elements to the group (len(reqs) % N) | ||||
| 	// | ||||
| 	daily = append(daily, reqs) | ||||
|  | ||||
| 	// | ||||
| 	// Print the 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, d := range daily { | ||||
| 		var sum int | ||||
|  | ||||
| 		for _, q := range d { | ||||
| 			sum += q | ||||
| 			fmt.Printf("%-10d%-10d\n", i+1, q) | ||||
| 		} | ||||
|  | ||||
| 		fmt.Println(strings.Repeat("-", 20)) | ||||
| 		fmt.Printf("%10s%-10d\n\n", "", sum) | ||||
|  | ||||
| 		grand += sum | ||||
| 	} | ||||
|  | ||||
| 	fmt.Printf("%10s%-10d\n", "", grand) | ||||
| } | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| ## Exercises Level I - Basics — Warm-Up | ||||
|  | ||||
| These are warm-up exercises that will reinforce your knowledge of slices. | ||||
| Let's reinforce your basic knowledge of slices. | ||||
|  | ||||
| 1. **[Declare nil slices](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/01-declare-nil)** | ||||
|  | ||||
| @@ -20,6 +20,8 @@ These are warm-up exercises that will reinforce your knowledge of slices. | ||||
|  | ||||
| ## Exercises Level II - Appending | ||||
|  | ||||
| Discover the power of the append function. | ||||
|  | ||||
| 1. **[Append #1 — Append and compare byte slices](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/07-append)** | ||||
|  | ||||
| 2. **[Append #2 — Append to a nil slice](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/08-append-2)** | ||||
| @@ -37,6 +39,8 @@ These are warm-up exercises that will reinforce your knowledge of slices. | ||||
|  | ||||
| ## Exercises Level III - Slicing | ||||
|  | ||||
| Discover the power of slicing. | ||||
|  | ||||
| 1. **[Slice the numbers](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/13-slicing-basics)** | ||||
|  | ||||
| 2. **[Slicing by arguments](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/14-slicing-by-args)** | ||||
| @@ -47,6 +51,8 @@ These are warm-up exercises that will reinforce your knowledge of slices. | ||||
|  | ||||
| ## Exercises Level IV - Internals | ||||
|  | ||||
| Peek into the internals of the slices and gain more insight. This is necessary for complete command of the slices. | ||||
|  | ||||
| 1. **[Fix the backing array problems](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/16-internals-backing-array-fix)** | ||||
|  | ||||
| 2. **[Sort the backing array](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/17-internals-backing-array-sort)** | ||||
| @@ -57,4 +63,30 @@ These are warm-up exercises that will reinforce your knowledge of slices. | ||||
|  | ||||
| 5. **[Observe the capacity growth](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/20-observe-the-cap-growth)** | ||||
|  | ||||
| 6. **[Correct the lyric](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/21-correct-the-lyric)** | ||||
| 6. **[Correct the lyric](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/21-correct-the-lyric)** | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Exercises Level V - Advanced Operations | ||||
|  | ||||
| Commonly used and more advanced operations are available to slices. Now, it's time to test yourself and fix some common problems. | ||||
|  | ||||
| 1. **[Practice Advanced Slice Operations](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/22-adv-ops-practice)** | ||||
|  | ||||
|     Let's warm you up for the advanced slice operations, and reinforce your neurons. | ||||
|  | ||||
| 2. **[Limit the backing array sharing](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/23-limit-the-backing-array-sharing)** | ||||
|  | ||||
|     Your API does not control the slices that it share with the outside world. You need to fix it. | ||||
|  | ||||
| 3. **[Fix the Memory Leak](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/25-fix-the-memory-leak)** | ||||
|  | ||||
|     A slice retrieved from an API causes a memory leak in your program. You need to fix it. | ||||
|  | ||||
| 4. **[Add newlines to the lyric sentences](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/25-add-lines)** | ||||
|  | ||||
|     Use the power of the `copy()` function and add newlines into a new buffer from a string slice. This exercise is more tricky than you might think. | ||||
|  | ||||
| 5. **[Print Daily Requests](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/26-print-daily-requests)** | ||||
|  | ||||
|     Group the requests log into a multi-dimensional from a single-dimensional slice. Allocate a slice with the exact size needed by doing some wizardary calculations. And lastly, pretty print the result. | ||||
|   | ||||
| @@ -25,8 +25,10 @@ func main() { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	report() | ||||
| 	img = append([]byte(nil), img[:24]...) | ||||
| 	img = img[:24:24] | ||||
| 	// img = img[:24:24] // unnecessary | ||||
| 	report() | ||||
|  | ||||
| 	// s.PrintBacking = true | ||||
| 	// s.MaxPerLine = 8 | ||||
|   | ||||
| @@ -1,68 +0,0 @@ | ||||
| # Slice Exercises | ||||
|  | ||||
| --- | ||||
|  | ||||
| # ANNOUNCEMENT | ||||
|  | ||||
| I teach you what the other courses don't even care to teach.  | ||||
|  | ||||
| **What's new?** | ||||
| * New Section: Advanced Slice Operations | ||||
| * New Exercises for the Slice Internals | ||||
| * New Exercises for the Slices: Advanced Operations | ||||
|  | ||||
| **What are you going to learn?** | ||||
| * Full Slice Expressions: Limiting access to the backing array | ||||
| * Make(): Preallocation | ||||
| * Copy(): Efficiently and safely copy elements without using a loop | ||||
| * Multi-Dimensional Slices | ||||
|  | ||||
| **What's coming next?** | ||||
| * Empty Filer Finder: Your first taste of file operations. | ||||
| * Bouncing Ball: Create a bouncing ball animation on a 2D surface. | ||||
| * Png Parser: Parse a PNG file by hand and tell its dimensions. | ||||
|  | ||||
| These lectures will be added in the next 3 weeks. | ||||
|  | ||||
| **Statistics:** | ||||
| * +1 hour of additional content! | ||||
| * +5 new lectures | ||||
| * +20 new questions | ||||
| * 3 + ? new exercises | ||||
|  | ||||
| **Total content in the slices section:** | ||||
| * ? hours | ||||
| * ? lectures | ||||
| * ? questions | ||||
| * ? exercises | ||||
|  | ||||
| --- | ||||
|  | ||||
| ## Full Slice Exp + Make + Copy + Multi-Dim Slices | ||||
|  | ||||
| # FIX THIS | ||||
| 1. **[Limit the backing array sharing](https://github.com/inancgumus/learngo/tree/master/16-slices/exercises/??-limit-the-backing-array-sharing)** | ||||
|  | ||||
| * fix the excess memory allocation | ||||
|   * return a huge slice from a func, ask the student fix it | ||||
| * full slice exp: https://play.golang.org/p/SPrLspRBXdI | ||||
| * copy: https://play.golang.org/p/SPrLspRBXdI | ||||
|   * + put \n for the beatles exercise using copy | ||||
|   ```go | ||||
|     s = append(s, 0 /* use the zero value of the element type */) | ||||
|     copy(s[i+1:], s[i:]) | ||||
|     s[i] = x | ||||
|   ``` | ||||
|  | ||||
|  | ||||
| * multi dim slices batches | ||||
| ```go | ||||
| actions := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} | ||||
| batchSize := 3 | ||||
| var batches [][]int | ||||
|  | ||||
| for batchSize < len(actions) { | ||||
|     actions, batches = actions[batchSize:], append(batches, actions[0:batchSize:batchSize]) | ||||
| } | ||||
| batches = append(batches, actions) | ||||
| ``` | ||||
| @@ -1,14 +0,0 @@ | ||||
| package main | ||||
|  | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: ? | ||||
| // | ||||
| // | ||||
| // | ||||
| // EXPECTED OUTPUT | ||||
| // | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
|  | ||||
| func main() { | ||||
| } | ||||
| @@ -1,11 +0,0 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| func main() { | ||||
| } | ||||
		Reference in New Issue
	
	Block a user