├── go.mod ├── cert.jpg ├── 1.3 ├── 1.3_step2.go └── 1.3_step3.go ├── README.md ├── 1.5 ├── 1.5_step13.go ├── 1.5_step14.go ├── 1.5_step15.go ├── 1.5_step11.go ├── 1.5_step12.go └── 1.5_step16.go ├── 1.10 ├── 1.10_step2.go ├── 1.10_step3.go ├── 1.10_step4.go ├── 1.10_step7.go ├── 1.10_step8.go ├── 1.10_step9.go ├── 1.10_step10.go └── 1.10_step5.go ├── 1.9 ├── 1.9_step5.go ├── 1.9_step7.go ├── 1.9_step6.go ├── 1.9_step8.go └── 1.9_step9.go ├── 2.6 ├── 2.6_step2.go ├── 2.6_step5.go ├── 2.6_step7.go └── 2.6_step4.go ├── .gitignore ├── 3.2 ├── 3.2_step4.go ├── 3.2_step3.go ├── 3.2_step6.go ├── 3.2_step2.go ├── 3.2_step13.go ├── 3.2_step9.go ├── 3.2_step8.go └── 3.2_step14.go ├── 2.5 ├── 2.5_step4.go ├── 2.5_step6.go ├── 2.5_step9.go ├── 2.5_step10.go ├── 2.5_step11.go ├── 2.5_step7.go ├── 2.5_step8.go └── 2.5_step12.go ├── 3.9__Goroutines_go_chan_PART2 ├── 3.9_step3.go ├── 3.9_step1.go ├── 3.9_step2.go ├── 3.9_step4__sync_WaitGroup.go ├── 3.9_step5__sync_WaitGroup.go ├── 3.9_step7__time_After__time__Tick.go ├── 3.9_step6__sync_Mutex.go ├── 3.9_step14__job_calculator.go ├── 3.9_step13__job_calculator.go ├── 3.9_step8__NewTimer__Ticker.go ├── 3.9_step9__select_case.go └── 3.9_step15__job_merge2Channels.go ├── 2.3 ├── 2.3_step5.go └── 2.3_step6.go ├── 2.7 ├── 2.7_step2.go ├── 2.7_step5.go ├── 2.7_step4.go ├── 2.7_step3.go └── 2.7_step7.go ├── 1.13 ├── 1.13_step2.go ├── 1.13_step3.go ├── 1.13_step7.go ├── 1.13_step15.go ├── 1.13_step5.go ├── 1.13_step16.go ├── 1.13_step8.go ├── 1.13_step13.go ├── 1.13_step6.go ├── 1.13_step11.go ├── 1.13_step9.go ├── 1.13_step4.go ├── 1.13_step14.go ├── 1.13_step12.go └── 1.13_step10.go ├── 3.8__Goroutines_go_chan ├── 3.8_step8.go ├── 3.8_step9.go ├── 3.8_step5.go └── 3.8_step10.go ├── 1.12 ├── 1.12_step13.go ├── 1.12_step14.go ├── 1.12_step15.go ├── 1.12_step16.go └── 1.12_step5.go ├── 2.1 ├── 2.1_step6.go ├── 2.1_step11.go ├── 2.1_step8.go ├── 2.1_step7.go └── 2.1_step9.go ├── 3.4 ├── 3.4_step9.go ├── 3.4_step12.go ├── 3.4_step11.go ├── 3.4_step13.go └── 3.4_step10.go ├── 2.4 ├── 2.4_step5.go └── 2.4_step8.go ├── 3.1 ├── 3.1_step1.go ├── 3.1_step2.go ├── 3.1_step5.go ├── 3.1_step4.go └── 3.1_step6.go ├── 3.6__JSON ├── 3.6_step8.go ├── 3.6_step7.go ├── 3.6_step9.go ├── 3.6_step3.go └── 3.6_step6.go ├── 3.7__Time ├── 3.7_step3.go ├── 3.7_step4.go ├── 3.7_step7.go ├── 3.7_step8.go ├── 3.7_step6.go ├── 3.7_step2.go └── 3.7_step1.go ├── 1.11 └── 1.11_step3.go ├── 3.3 ├── 3.3_step1.go ├── 3.3_step2.go ├── 3.3_step7.go ├── 3.3_step6.go └── 3.3_step8.go ├── 3.5 ├── 3.5_step11.go ├── 3.5_step14.go ├── 3.5_step9.go ├── 3.5_step2.go ├── 3.5_step13.go ├── 3.5_step10.go ├── 3.5_step4.go └── 3.5_step7.go └── 1.7 └── 1.7_step3.go /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gil9red/stepic_golang 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /cert.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gil9red/stepic_golang/HEAD/cert.jpg -------------------------------------------------------------------------------- /1.3/1.3_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("I like Go!") 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stepic_golang 2 | 3 | Course: https://stepik.org/course/54403 4 | 5 | My cert: https://stepik.org/cert/806321 6 | 7 | ![](cert.jpg) 8 | -------------------------------------------------------------------------------- /1.5/1.5_step13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var a int 7 | fmt.Scan(&a) 8 | 9 | fmt.Println(a * a) 10 | } 11 | -------------------------------------------------------------------------------- /1.10/1.10_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | for i := 1; i <= 10; i++ { 7 | fmt.Println(i * i) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /1.5/1.5_step14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var a int 7 | fmt.Scan(&a) 8 | 9 | fmt.Println(a % 10) 10 | } 11 | -------------------------------------------------------------------------------- /1.5/1.5_step15.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var a int 7 | fmt.Scan(&a) 8 | 9 | fmt.Println(a / 10 % 10) 10 | } 11 | -------------------------------------------------------------------------------- /1.5/1.5_step11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var a int 7 | fmt.Scan(&a) 8 | 9 | a *= 2 10 | a += 100 11 | fmt.Println(a) 12 | } 13 | -------------------------------------------------------------------------------- /1.3/1.3_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("I like Go!") 7 | fmt.Println("I like Go!") 8 | fmt.Println("I like Go!") 9 | } 10 | -------------------------------------------------------------------------------- /1.5/1.5_step12.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var a, b int 7 | fmt.Scan(&a) // считаем переменную 'a' с консоли 8 | fmt.Scan(&b) // считаем переменную 'b' с консоли 9 | 10 | a = a * a 11 | b = b * b 12 | fmt.Println(a + b) 13 | } 14 | -------------------------------------------------------------------------------- /1.9/1.9_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var n int 7 | fmt.Scan(&n) 8 | 9 | if n > 0 { 10 | fmt.Println("Число положительное") 11 | } else if n < 0 { 12 | fmt.Println("Число отрицательное") 13 | } else { 14 | fmt.Println("Ноль") 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /2.6/2.6_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | err := errors.New("my error") 10 | fmt.Println(err) 11 | // my error 12 | 13 | err2 := fmt.Errorf("my error: %s", "") 14 | fmt.Println(err2) 15 | // my error: 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | -------------------------------------------------------------------------------- /3.2/3.2_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var x int64 = 57 7 | var y = float64(x) 8 | fmt.Print(x, y) // 57 57 9 | 10 | fmt.Println() 11 | 12 | var f float64 = 56.231 13 | var i = int(f) 14 | fmt.Println(f, i) // 56.231 56 15 | 16 | fmt.Println() 17 | 18 | fmt.Println(5/2, 5.0/2) // 2 2.5 19 | } 20 | -------------------------------------------------------------------------------- /2.6/2.6_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func dividePanic(a, b float64) float64 { 8 | if b == 0 { 9 | panic("division by zero!") 10 | } 11 | return a / b 12 | } 13 | 14 | func main() { 15 | fmt.Println(dividePanic(15, 5)) 16 | fmt.Println(dividePanic(4, 0)) 17 | fmt.Println("Program has been finished") 18 | } 19 | -------------------------------------------------------------------------------- /3.2/3.2_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Напишите функцию с именем convert, которая конвертирует входное 7 | число типа int64 в uint16. 8 | */ 9 | 10 | func convert(num int64) uint16 { 11 | return uint16(num) 12 | } 13 | 14 | func main() { 15 | var num = int64(1000) 16 | var num2 = convert(num) 17 | fmt.Printf("%T %v\n", num2, num2) 18 | } 19 | -------------------------------------------------------------------------------- /2.5/2.5_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | rs := []rune("Это срез рун") 7 | 8 | // Итерируясь мы будем заменять символ 'р' на '*' 9 | for i := range rs { 10 | switch rs[i] { 11 | case 'р': 12 | rs[i] = '*' 13 | case ' ': 14 | rs[i] = '_' 15 | } 16 | } 17 | fmt.Printf("Измененнный срез в виде строки: %s\n", string(rs)) 18 | } 19 | -------------------------------------------------------------------------------- /3.2/3.2_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | text := "строка" 7 | 8 | bs := []byte(text) 9 | fmt.Println(text, string(bs)) 10 | fmt.Println(bs) // [209 129 209 130 209 128 208 190 208 186 208 176] 11 | 12 | fmt.Println() 13 | 14 | rs := []rune(text) 15 | fmt.Println(text, string(rs)) 16 | fmt.Println(rs) // [1089 1090 1088 1086 1082 1072] 17 | } 18 | -------------------------------------------------------------------------------- /2.5/2.5_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unicode/utf8" 6 | ) 7 | 8 | /* 9 | Для получения количества символов используйте utf8.RuneCountInString() 10 | */ 11 | 12 | func main() { 13 | var en = "english" 14 | var ru = "русский" 15 | fmt.Println(len(en), len(ru)) 16 | // 7 14 17 | 18 | fmt.Println(utf8.RuneCountInString(en), utf8.RuneCountInString(ru)) 19 | // 7 7 20 | } 21 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Started!") 9 | 10 | work := func() { 11 | fmt.Println("Hello World!") 12 | } 13 | 14 | myFunc := func() <-chan struct{} { 15 | done := make(chan struct{}) 16 | go func() { 17 | work() 18 | close(done) 19 | }() 20 | return done 21 | } 22 | <-myFunc() 23 | 24 | fmt.Println("Finish!") 25 | } 26 | -------------------------------------------------------------------------------- /2.3/2.3_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Напишите функцию, которая умножает значения на которые ссылаются два указателя 7 | и выводит получившееся произведение в консоль. 8 | 9 | Sample Input: 10 | 2 2 11 | 12 | Sample Output: 13 | 4 14 | */ 15 | 16 | // NOTE: need rename to "test" 17 | func testStep5(x1, x2 *int) { 18 | fmt.Println(*x1 * *x2) 19 | } 20 | 21 | func main() { 22 | a, b := 5, 4 23 | testStep5(&a, &b) 24 | } 25 | -------------------------------------------------------------------------------- /2.7/2.7_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | /* 9 | На вход подаются a и b - катеты прямоугольного треугольника. 10 | Нужно найти длину гипотенузы 11 | 12 | Sample Input: 13 | 6 8 14 | 15 | Sample Output: 16 | 10 17 | */ 18 | 19 | func main() { 20 | var a, b float64 21 | _, err := fmt.Scan(&a, &b) 22 | if err != nil { 23 | panic("invalid input values") 24 | } 25 | 26 | fmt.Println(math.Sqrt(a*a + b*b)) 27 | } 28 | -------------------------------------------------------------------------------- /2.3/2.3_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Поменяйте местами значения переменных на которые ссылаются указатели. 7 | После этого переменные нужно вывести. 8 | 9 | Sample Input: 10 | 2 4 11 | 12 | Sample Output: 13 | 4 2 14 | */ 15 | 16 | // NOTE: need rename to "test" 17 | func testStep6(x1, x2 *int) { 18 | *x1, *x2 = *x2, *x1 19 | fmt.Println(*x1, *x2) 20 | } 21 | 22 | func main() { 23 | a, b := 5, 4 24 | testStep6(&a, &b) 25 | } 26 | -------------------------------------------------------------------------------- /2.5/2.5_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | /* 9 | Даются две строки X и S. Нужно найти и вывести первое вхождение подстроки S в 10 | строке X. Если подстроки S нет в строке X - вывести -1 11 | 12 | Sample Input: 13 | awesome 14 | es 15 | 16 | Sample Output: 17 | 2 18 | */ 19 | 20 | func main() { 21 | var text1, text2 string 22 | _, _ = fmt.Scan(&text1, &text2) 23 | 24 | fmt.Println(strings.Index(text1, text2)) 25 | } 26 | -------------------------------------------------------------------------------- /1.9/1.9_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Дано неотрицательное целое число. Найдите и выведите первую цифру числа. 7 | 8 | Формат входных данных 9 | На вход дается натуральное число, не превосходящее 10000. 10 | 11 | Формат выходных данных 12 | Выведите одно целое число - первую цифру заданного числа. 13 | */ 14 | 15 | func main() { 16 | var n string 17 | fmt.Scan(&n) 18 | 19 | fmt.Println(string(n[0])) 20 | // OR: 21 | // fmt.Println(n[:1]) 22 | } 23 | -------------------------------------------------------------------------------- /1.13/1.13_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Дано трехзначное число. Найдите сумму его цифр. 9 | 10 | Формат входных данных 11 | На вход дается трехзначное число. 12 | 13 | Формат выходных данных 14 | Выведите одно целое число - сумму цифр введенного числа. 15 | 16 | Sample Input: 17 | 745 18 | 19 | Sample Output: 20 | 16 21 | */ 22 | 23 | func main() { 24 | var n int 25 | fmt.Scan(&n) 26 | fmt.Println((n / 100 % 10) + (n / 10 % 10) + (n % 10)) 27 | } 28 | -------------------------------------------------------------------------------- /1.10/1.10_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Требуется написать программу, при выполнении которой с клавиатуры считываются 7 | два натуральных числа A и B (каждое не более 100, A < B). 8 | Вывести сумму всех чисел от A до B включительно. 9 | 10 | Sample Input: 11 | 1 5 12 | 13 | Sample Output: 14 | 15 15 | */ 16 | 17 | func main() { 18 | var a, b int 19 | fmt.Scan(&a, &b) 20 | 21 | n := 0 22 | for i := a; i <= b; i++ { 23 | n += i 24 | } 25 | fmt.Println(n) 26 | } 27 | -------------------------------------------------------------------------------- /3.8__Goroutines_go_chan/3.8_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите функцию которая принимает канал и число N типа int. Необходимо вернуть значение N+1 в канал. 9 | Функция должна называться task(). 10 | */ 11 | 12 | func task(c chan int, n int) { 13 | c <- n + 1 14 | } 15 | 16 | func main() { 17 | fmt.Println("Started!") 18 | 19 | c := make(chan int) 20 | go task(c, 99) 21 | 22 | fmt.Println(<-c) 23 | // 100 24 | 25 | fmt.Println("Finish!") 26 | } 27 | -------------------------------------------------------------------------------- /1.13/1.13_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Дано трехзначное число. Переверните его, а затем выведите. 9 | 10 | Формат входных данных 11 | На вход дается трехзначное число, не оканчивающееся на ноль. 12 | 13 | Формат выходных данных 14 | Выведите перевернутое число. 15 | 16 | Sample Input: 17 | 843 18 | 19 | Sample Output: 20 | 348 21 | */ 22 | 23 | func main() { 24 | var n int 25 | fmt.Scan(&n) 26 | fmt.Printf("%d%d%d", (n % 10), (n / 10 % 10), (n / 100 % 10)) 27 | } 28 | -------------------------------------------------------------------------------- /1.12/1.12_step13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите программу, принимающая на вход число N (N ≥ 4), а затем N целых 9 | чисел-элементов среза. На вывод нужно подать 4-ый (3 по индексу) элемент 10 | данного среза. 11 | 12 | Sample Input: 13 | 5 14 | 41 -231 24 49 6 15 | 16 | Sample Output: 17 | 49 18 | */ 19 | 20 | func main() { 21 | var n uint 22 | fmt.Scan(&n) 23 | 24 | items := make([]int, n) 25 | for i := range items { 26 | fmt.Scan(&items[i]) 27 | } 28 | fmt.Println(items[3]) 29 | } 30 | -------------------------------------------------------------------------------- /2.5/2.5_step10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | /* 9 | На вход дается строка, из нее нужно сделать другую строку, оставив только 10 | нечетные символы (считая с нуля) 11 | 12 | Sample Input: 13 | ihgewlqlkot 14 | 15 | Sample Output: 16 | hello 17 | */ 18 | 19 | func main() { 20 | var text string 21 | _, _ = fmt.Scan(&text) 22 | 23 | var b strings.Builder 24 | for i, r := range text { 25 | if i%2 != 0 { 26 | b.WriteRune(r) 27 | } 28 | } 29 | 30 | fmt.Println(b.String()) 31 | } 32 | -------------------------------------------------------------------------------- /1.13/1.13_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Даны два числа. Найти их среднее арифметическое. 9 | 10 | Формат входных данных 11 | На вход дается два целых положительных числа a и b. 12 | 13 | Формат выходных данных 14 | Программа должна вывести среднее арифметическое чисел a и b (ответ может 15 | быть целым числом или дробным) 16 | 17 | Sample Input: 18 | 3 5 19 | 20 | Sample Output: 21 | 4 22 | */ 23 | 24 | func main() { 25 | var a, b float32 26 | fmt.Scan(&a, &b) 27 | fmt.Println((a + b) / 2) 28 | } 29 | -------------------------------------------------------------------------------- /1.9/1.9_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | По данному трехзначному числу определите, все ли его цифры различны. 7 | 8 | Формат входных данных 9 | На вход подается одно натуральное трехзначное число. 10 | 11 | Формат выходных данных 12 | Выведите "YES", если все цифры числа различны, в противном случае - "NO". 13 | */ 14 | 15 | func main() { 16 | var n string 17 | fmt.Scan(&n) 18 | 19 | if n[0] != n[1] && n[0] != n[2] && n[1] != n[2] { 20 | fmt.Println("YES") 21 | } else { 22 | fmt.Println("NO") 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2.5/2.5_step11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | /* 9 | Дается строка. Нужно удалить все символы, которые встречаются более одного раза 10 | и вывести получившуюся строку 11 | 12 | Sample Input: 13 | zaabcbd 14 | 15 | Sample Output: 16 | zcd 17 | */ 18 | 19 | func main() { 20 | var text string 21 | _, _ = fmt.Scan(&text) 22 | 23 | var b strings.Builder 24 | for _, r := range text { 25 | if strings.Count(text, string(r)) == 1 { 26 | b.WriteRune(r) 27 | } 28 | } 29 | 30 | fmt.Println(b.String()) 31 | } 32 | -------------------------------------------------------------------------------- /1.13/1.13_step15.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | /* 9 | Двоичная запись 10 | Дано натуральное число N. Выведите его представление в двоичном виде. 11 | 12 | Входные данные 13 | Задано единственное число N 14 | 15 | Выходные данные 16 | Необходимо вывести требуемое представление числа N. 17 | 18 | Sample Input: 19 | 12 20 | 21 | Sample Output: 22 | 1100 23 | */ 24 | 25 | func main() { 26 | var n int 27 | _, err := fmt.Scan(&n) 28 | if err != nil { 29 | log.Fatalln(err) 30 | } 31 | 32 | fmt.Printf("%b", n) 33 | } 34 | -------------------------------------------------------------------------------- /2.1/2.1_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите функцию f(), которая будет принимать строку text и выводить ее 9 | (печатать на экране). 10 | От вас требуется дописать только эту функцию, считайте что функция main() 11 | уже объявлена, считывать с консоли ничего не нужно! 12 | Пакет "fmt" уже импортирован! 13 | 14 | Sample Input: 15 | Hello! 16 | 17 | Sample Output: 18 | Hello! 19 | */ 20 | 21 | func f(text string) { 22 | fmt.Println(text) 23 | } 24 | 25 | func main() { 26 | text := "Hello World" 27 | f(text) 28 | } 29 | -------------------------------------------------------------------------------- /1.13/1.13_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Заданы три числа - a,b,c (a", a.Name, a.Age) 12 | } 13 | 14 | func main() { 15 | a := Animal{ 16 | Name: "Gopher", 17 | Age: 2, 18 | } 19 | fmt.Println(a) 20 | // {Gopher 2} 21 | 22 | fmt.Println(&a) 23 | // 24 | 25 | fmt.Println() 26 | 27 | aP := &Animal{ 28 | Name: "Gopher", 29 | Age: 2, 30 | } 31 | fmt.Println(aP) 32 | // 33 | 34 | fmt.Println(*aP) 35 | // {Gopher 2} 36 | } 37 | -------------------------------------------------------------------------------- /3.8__Goroutines_go_chan/3.8_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите функцию которая принимает канал и строку. Необходимо отправить эту же строку в заданный канал 9 | 5 раз, добавив к ней пробел. 10 | Функция должна называться task2(). 11 | */ 12 | 13 | func task2(c chan string, text string) { 14 | for i := 0; i < 5; i++ { 15 | c <- text + " " 16 | } 17 | } 18 | 19 | func main() { 20 | fmt.Println("Started!") 21 | 22 | c := make(chan string) 23 | go task2(c, "a") 24 | 25 | for i := 0; i < 5; i++ { 26 | fmt.Print(<-c) 27 | } 28 | // a a a a a 29 | 30 | fmt.Println("\nFinish!") 31 | } 32 | -------------------------------------------------------------------------------- /2.4/2.4_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Встраиваемые типы 7 | */ 8 | 9 | type Person struct { 10 | Name string 11 | } 12 | 13 | func (p *Person) Talk() { 14 | fmt.Println("Hi, my name is", p.Name) 15 | } 16 | 17 | type Android struct { 18 | // Person Person // Composition 19 | Person // Embedding (analogue of inheritance) 20 | Model string 21 | } 22 | 23 | func main() { 24 | android := &Android{ 25 | Person: Person{ 26 | Name: "Vasya", 27 | }, 28 | Model: "001", 29 | } 30 | fmt.Printf("%T, %v\n", android, android) 31 | fmt.Println(android.Name, android.Person.Name) 32 | android.Talk() 33 | } 34 | -------------------------------------------------------------------------------- /1.13/1.13_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Количество нулей 9 | По данным числам, определите количество чисел, которые равны нулю. 10 | 11 | Входные данные 12 | Вводится натуральное число N, а затем N чисел. 13 | 14 | Выходные данные 15 | Выведите количество чисел, которые равны нулю. 16 | 17 | Sample Input: 18 | 5 19 | 1 20 | 8 21 | 100 22 | 0 23 | 12 24 | 25 | Sample Output: 26 | 1 27 | */ 28 | 29 | func main() { 30 | var n, number int 31 | fmt.Scan(&n) 32 | 33 | for i := 0; i < n; i++ { 34 | var x int 35 | if fmt.Scan(&x); x == 0 { 36 | number++ 37 | } 38 | } 39 | 40 | fmt.Println(number) 41 | } 42 | -------------------------------------------------------------------------------- /1.13/1.13_step13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | /* 9 | По данному числу N распечатайте все целые значения степени двойки, не 10 | превосходящие N, в порядке возрастания. 11 | 12 | Входные данные 13 | Вводится натуральное число. 14 | 15 | Выходные данные 16 | Выведите ответ на задачу. 17 | 18 | Sample Input: 19 | 50 20 | 21 | Sample Output: 22 | 1 2 4 8 16 32 23 | */ 24 | 25 | func main() { 26 | var n int 27 | _, err := fmt.Scan(&n) 28 | if err != nil { 29 | log.Fatalln(err) 30 | } 31 | 32 | for i := 0; i < n; i++ { 33 | x := 1 << i 34 | if x > n { 35 | break 36 | } 37 | fmt.Print(x, " ") 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /1.13/1.13_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Входные данные 9 | Даны три натуральных числа a, b, c. Определите, существует ли треугольник 10 | с такими сторонами. 11 | 12 | Выходные данные 13 | Если треугольник существует, выведите строку "Существует", иначе выведите 14 | строку "Не существует". Строку выводите без кавычек. 15 | 16 | Sample Input: 17 | 4 5 6 18 | 19 | Sample Output: 20 | Существует 21 | */ 22 | 23 | func main() { 24 | var a, b, c int 25 | fmt.Scan(&a, &b, &c) 26 | 27 | if a+b > c && a+c > b && b+c > a { 28 | fmt.Println("Существует") 29 | } else { 30 | fmt.Println("Не существует") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /2.1/2.1_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите "функцию голосования", возвращающую то значение (0 или 1), 9 | которое среди значений ее аргументов x, y, z встречается чаще. 10 | 11 | Входные данные 12 | Вводится 3 числа - x, y и z (x, y и z равны 0 или 1). 13 | 14 | Выходные данные 15 | Необходимо вывести значение функции от x, y и z. 16 | 17 | Sample Input: 18 | 0 0 1 19 | 20 | Sample Output: 21 | 0 22 | */ 23 | 24 | func vote(x int, y int, z int) int { 25 | if x+y+z > 1 { 26 | return 1 27 | } else { 28 | return 0 29 | } 30 | } 31 | 32 | func main() { 33 | fmt.Println(vote(0, 0, 1)) 34 | fmt.Println(vote(1, 0, 1)) 35 | } 36 | -------------------------------------------------------------------------------- /1.10/1.10_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Напишите программу, которая в последовательности чисел находит сумму двузначных 7 | чисел, кратных 8. Программа в первой строке получает на вход число n - количество 8 | чисел в последовательности, во второй строке -- n чисел, входящих в данную 9 | последовательность. 10 | 11 | Sample Input: 12 | 5 13 | 38 24 800 8 16 14 | 15 | Sample Output: 16 | 40 17 | */ 18 | 19 | func main() { 20 | var n, num int 21 | fmt.Scan(&n) 22 | 23 | sum := 0 24 | for i := 0; i < n; i++ { 25 | fmt.Scan(&num) 26 | 27 | if num >= 10 && num < 100 && num%8 == 0 { 28 | sum += num 29 | } 30 | } 31 | fmt.Println(sum) 32 | } 33 | -------------------------------------------------------------------------------- /1.10/1.10_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Найдите первое число от 1 до n включительно, кратное c, но НЕ кратное d. 7 | 8 | Входные данные 9 | Вводится 3 натуральных числа n, c, d, каждое из которых не превышает 10000. 10 | 11 | Выходные данные 12 | Вывести первое число от 1 до n включительно, кратное c, но НЕ кратное d. 13 | Если такого числа нет - выводить ничего не нужно. 14 | 15 | Sample Input: 16 | 20 17 | 3 18 | 5 19 | 20 | Sample Output: 21 | 3 22 | */ 23 | 24 | func main() { 25 | var n, c, d int 26 | fmt.Scan(&n, &c, &d) 27 | 28 | for i := 0; i <= n; i++ { 29 | if i%c == 0 && i%d != 0 { 30 | fmt.Println(i) 31 | break 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /1.13/1.13_step11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Самое большое число, кратное 7 7 | Найдите самое большее число на отрезке от a до b, кратное 7 . 8 | 9 | Входные данные 10 | Вводится два целых числа a и b (a≤b). 11 | 12 | Выходные данные 13 | Найдите самое большее число на отрезке от a до b (отрезок включает в себя 14 | числа a и b), кратное 7 , или выведите "NO" - если таковых нет. 15 | 16 | Sample Input: 17 | 100 18 | 500 19 | 20 | Sample Output: 21 | 497 22 | */ 23 | 24 | func main() { 25 | var a, b int 26 | fmt.Scan(&a, &b) 27 | 28 | for i := b; i >= a; i-- { 29 | if i%7 == 0 { 30 | fmt.Println(i) 31 | return 32 | } 33 | } 34 | fmt.Println("NO") 35 | } 36 | -------------------------------------------------------------------------------- /1.12/1.12_step14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | На ввод подаются пять чисел, которые записываются в массив. 9 | Вам нужно написать фрагмент кода, с помощью которого можно найти 10 | и вывести максимальное число в этом массиве. 11 | 12 | Sample Input: 13 | 2 14 | 3 15 | 56 16 | 45 17 | 21 18 | 19 | Sample Output: 20 | 56 21 | */ 22 | 23 | func main() { 24 | var n uint 25 | fmt.Scan(&n) 26 | 27 | items := make([]int, n) 28 | for i := range items { 29 | fmt.Scan(&items[i]) 30 | } 31 | 32 | maxN := items[0] 33 | for i := 1; i < len(items); i++ { 34 | x := items[i] 35 | if x > maxN { 36 | maxN = x 37 | } 38 | } 39 | 40 | fmt.Println(maxN) 41 | } 42 | -------------------------------------------------------------------------------- /1.9/1.9_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Определите является ли билет счастливым. Счастливым считается билет, в шестизначном номере которого сумма первых трёх цифр совпадает с суммой трёх последних. 9 | 10 | Формат входных данных 11 | На вход подается номер билета - одно шестизначное число. 12 | 13 | Формат выходных данных 14 | Выведите "YES", если билет счастливый, в противном случае - "NO". 15 | */ 16 | 17 | func main() { 18 | var n int 19 | fmt.Scan(&n) 20 | 21 | left := n/100000%10 + n/10000%10 + n/1000%10 22 | right := n/100%10 + n/10%10 + n%10 23 | if left == right { 24 | fmt.Println("YES") 25 | } else { 26 | fmt.Println("NO") 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /1.10/1.10_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Напишите программу, которая считывает целые числа с консоли по одному числу в строке. 7 | 8 | Для каждого введённого числа проверить: 9 | если число меньше 10, то пропускаем это число; 10 | если число больше 100, то прекращаем считывать числа; 11 | в остальных случаях вывести это число обратно на консоль в отдельной строке. 12 | 13 | Sample Input: 14 | 30 15 | 11 16 | 7 17 | 101 18 | 19 | Sample Output: 20 | 30 21 | 11 22 | */ 23 | 24 | func main() { 25 | var n int 26 | for { 27 | fmt.Scan(&n) 28 | if n < 10 { 29 | continue 30 | } else if n > 100 { 31 | break 32 | } 33 | 34 | fmt.Println(n) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /2.1/2.1_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите функцию, находящую наименьшее из четырех введённых в 9 | этой же функции чисел. 10 | 11 | Входные данные 12 | Вводится четыре числа. 13 | 14 | Выходные данные 15 | Необходимо вернуть из функции наименьшее из 4-х данных чисел 16 | 17 | Sample Input: 18 | 4 5 6 7 19 | 20 | Sample Output: 21 | 4 22 | */ 23 | 24 | func minimumFromFour() int { 25 | var min int 26 | _, _ = fmt.Scan(&min) 27 | 28 | for i := 1; i < 4; i++ { 29 | var x int 30 | _, _ = fmt.Scan(&x) 31 | 32 | if x < min { 33 | min = x 34 | } 35 | } 36 | 37 | return min 38 | } 39 | 40 | func main() { 41 | fmt.Println(minimumFromFour()) 42 | } 43 | -------------------------------------------------------------------------------- /1.10/1.10_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Вклад в банке составляет x рублей. Ежегодно он увеличивается на p процентов, 7 | после чего дробная часть копеек отбрасывается. Каждый год сумма вклада 8 | становится больше. 9 | Определите, через сколько лет вклад составит не менее y рублей. 10 | 11 | Входные данные 12 | Программа получает на вход три натуральных числа: x, p, y. 13 | 14 | Выходные данные 15 | Программа должна вывести одно целое число. 16 | 17 | Sample Input: 18 | 100 19 | 10 20 | 200 21 | 22 | Sample Output: 23 | 8 24 | */ 25 | 26 | func main() { 27 | var x, p, y, years int 28 | fmt.Scan(&x, &p, &y) 29 | 30 | for ; x < y; years++ { 31 | x += x * p / 100 32 | } 33 | 34 | fmt.Println(years) 35 | } 36 | -------------------------------------------------------------------------------- /1.13/1.13_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Количество минимумов 9 | Найдите количество минимальных элементов в последовательности. 10 | 11 | Входные данные 12 | Вводится натуральное число N, а затем N чисел. 13 | 14 | Выходные данные 15 | Выведите количество минимальных элементов. 16 | 17 | Sample Input: 18 | 3 19 | 21 20 | 11 21 | 4 22 | 23 | Sample Output: 24 | 1 25 | */ 26 | 27 | func main() { 28 | var n, x int 29 | fmt.Scan(&n) 30 | 31 | fmt.Scan(&x) 32 | min := x 33 | number := 1 34 | 35 | for i := 1; i < n; i++ { 36 | fmt.Scan(&x) 37 | 38 | if x < min { 39 | min = x 40 | number = 0 41 | } 42 | if x == min { 43 | number++ 44 | } 45 | } 46 | fmt.Println(number) 47 | } 48 | -------------------------------------------------------------------------------- /2.1/2.1_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Последовательность Фибоначчи определена следующим образом: 9 | φ1=1, φ2=1, φn=φn-1+φn-2 при n>1. 10 | Начало ряда Фибоначчи выглядит следующим образом: 11 | 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... 12 | Напишите функцию, которая по указанному натуральному 13 | n возвращает φn. 14 | 15 | Входные данные 16 | Вводится одно число n. 17 | 18 | Выходные данные 19 | Необходимо вывести значение φn. 20 | 21 | Sample Input: 22 | 4 23 | 24 | Sample Output: 25 | 3 26 | */ 27 | 28 | func fibonacci(n int) int { 29 | a := 0 30 | b := 1 31 | for i := 0; i < n; i++ { 32 | a, b = b, b+a 33 | } 34 | return a 35 | } 36 | 37 | func main() { 38 | fmt.Println(fibonacci(4)) 39 | } 40 | -------------------------------------------------------------------------------- /1.5/1.5_step16.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Часовая стрелка повернулась с начала суток на d градусов. 7 | Определите, сколько сейчас целых часов h и целых минут m. 8 | 9 | Входные данные 10 | На вход программе подается целое число d (0d360). 11 | 12 | Выходные данные 13 | Выведите на экран фразу: 14 | It is ... hours ... minutes. 15 | 16 | Вместо многоточий программа должна выводить значения h и m, отделяя их 17 | от слов ровно одним пробелом. 18 | 19 | Sample Input: 20 | 90 21 | 22 | Sample Output: 23 | It is 3 hours 0 minutes. 24 | */ 25 | 26 | func main() { 27 | var d int 28 | fmt.Scan(&d) 29 | 30 | hours := d * 2 / 60 31 | minutes := d * 2 % 60 32 | fmt.Printf("It is %d hours %d minutes.", hours, minutes) 33 | } 34 | -------------------------------------------------------------------------------- /3.4/3.4_step11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unicode" 6 | ) 7 | 8 | type customError uint 9 | 10 | func (c customError) Error() string { 11 | return fmt.Sprintf("digit!!!: index %d", c) 12 | } 13 | 14 | func errorInString(str string) error { 15 | // Полезная работа со строкой проигнорирована 16 | for i, r := range []rune(str) { 17 | if unicode.IsDigit(r) { 18 | return customError(i) 19 | } 20 | } 21 | return nil 22 | } 23 | 24 | func main() { 25 | err := errorInString("Строка1Строка") 26 | if err != nil { 27 | fmt.Printf("Ошибка обработана: %v\n", err) 28 | } 29 | // Ошибка обработана: digit!!!: index 6 30 | 31 | if idx, ok := err.(customError); ok { 32 | fmt.Printf("Контекст: %d\n", idx) 33 | } 34 | // Контекст: 6 35 | } 36 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println("Started!") 9 | 10 | // Ручной wait через канал 11 | { 12 | myFunc := func(done chan struct{}) { 13 | fmt.Print("Hello") 14 | close(done) 15 | } 16 | 17 | done := make(chan struct{}) 18 | go myFunc(done) 19 | <-done 20 | fmt.Print(" World!") 21 | 22 | fmt.Println() 23 | } 24 | 25 | // Функция с само-wait 26 | { 27 | myFunc := func() <-chan struct{} { 28 | done := make(chan struct{}) 29 | go func() { 30 | fmt.Print("Hello") 31 | close(done) 32 | }() 33 | return done 34 | } 35 | <-myFunc() 36 | fmt.Print(" World!") 37 | 38 | fmt.Println() 39 | } 40 | 41 | fmt.Println("Finish!") 42 | } 43 | -------------------------------------------------------------------------------- /1.9/1.9_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Требуется определить, является ли данный год високосным, напомним: 7 | Год является високосным если он соответствует хотя бы одному из нижеперечисленных условий: 8 | - кратен 400; 9 | - кратен 4, но не кратен 100. 10 | 11 | Входные данные 12 | Вводится единственное число - номер года (целое, положительное, не превышает 10000). 13 | 14 | Выходные данные 15 | Требуется вывести слово YES, если год является високосным и NO - в противном случае. 16 | 17 | Sample Input: 18 | 2000 19 | 20 | Sample Output: 21 | YES 22 | */ 23 | 24 | func main() { 25 | var n int 26 | fmt.Scan(&n) 27 | 28 | if n%400 == 0 || (n%4 == 0 && n%100 != 0) { 29 | fmt.Println("YES") 30 | } else { 31 | fmt.Println("NO") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /3.1/3.1_step1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | var m map[int]int 9 | fmt.Printf("m is nil -> %t", m == nil) // Warning! m is nil! 10 | 11 | fmt.Println() 12 | 13 | // с помощью встроенной функции make: 14 | m1 := make(map[int]int) 15 | 16 | m2 := map[int]int{} 17 | 18 | // с помощью использования литерала отображения: 19 | m3 := map[int]int{ 20 | // Пары ключ:значение указываются при необходимости 21 | 12: 2, 22 | 1: 5, 23 | } 24 | 25 | fmt.Println(m1) // map[] 26 | fmt.Println(m2) // map[] 27 | fmt.Println(m3) // map[1:5 12:2] 28 | 29 | fmt.Println() 30 | 31 | m1[1], m2[1], m3[1] = 123, 123, 123 32 | fmt.Println(m1) // map[1:123] 33 | fmt.Println(m2) // map[1:123] 34 | fmt.Println(m3) // [1:123 12:2] 35 | } 36 | -------------------------------------------------------------------------------- /1.10/1.10_step10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Даны два числа. Определить цифры, входящие в запись как первого, 7 | так и второго числа. 8 | 9 | Входные данные 10 | Программа получает на вход два числа. Гарантируется, что цифры в числах 11 | не повторяются. Числа в пределах от 0 до 10000. 12 | 13 | Выходные данные 14 | Программа должна вывести цифры, которые имеются в обоих числах, через пробел. 15 | Цифры выводятся в порядке их нахождения в первом числе. 16 | 17 | Sample Input: 18 | 564 8954 19 | 20 | Sample Output: 21 | 5 4 22 | */ 23 | 24 | func main() { 25 | var a, b string 26 | fmt.Scan(&a, &b) 27 | 28 | for _, a1 := range a { 29 | for _, b1 := range b { 30 | if a1 == b1 { 31 | fmt.Print(string(a1) + " ") 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step4__sync_WaitGroup.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("Started!") 11 | 12 | work := func(id int, wg *sync.WaitGroup) { 13 | defer wg.Done() 14 | fmt.Printf("Горутина %d начала выполнение \n", id) 15 | time.Sleep(2 * time.Second) 16 | fmt.Printf("Горутина %d завершила выполнение \n", id) 17 | } 18 | 19 | wg := new(sync.WaitGroup) 20 | 21 | for i := 0; i < 5; i++ { 22 | wg.Add(1) // Увеличиваем счетчик горутин в группе 23 | go work(i, wg) // Вызываем функцию work в отдельной горутине 24 | } 25 | 26 | wg.Wait() // Ожидание завершения всех горутин в группе 27 | fmt.Println("Горутины завершили выполнение") 28 | 29 | fmt.Println("Finish!") 30 | } 31 | -------------------------------------------------------------------------------- /2.7/2.7_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | /* 9 | На вход подается целое число. Необходимо возвести в квадрат каждую цифру числа 10 | и вывести получившееся число. 11 | 12 | Например, у нас есть число 9119. Первая цифра - 9. 9 в квадрате - 81. Дальше 1. 13 | Единица в квадрате - 1. В итоге получаем 811181 14 | 15 | Sample Input: 16 | 9119 17 | 18 | Sample Output: 19 | 811181 20 | */ 21 | 22 | func main() { 23 | var text string 24 | _, err := fmt.Scan(&text) 25 | if err != nil { 26 | panic("invalid input values") 27 | } 28 | 29 | for _, r := range text { 30 | n, err := strconv.Atoi(string(r)) 31 | if err != nil { 32 | panic(fmt.Sprintf("invalid int value: %c", r)) 33 | } 34 | 35 | fmt.Print(n * n) 36 | } 37 | 38 | fmt.Println() 39 | } 40 | -------------------------------------------------------------------------------- /1.13/1.13_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Идёт k-я секунда суток. Определите, сколько целых часов h и целых минут m 9 | прошло с начала суток. Например, если 10 | k = 13257 = 3*3600 + 40*60 + 57, 11 | то h=3 и m=40. 12 | 13 | Входные данные 14 | На вход программе подается целое число k (0 <= k <= 86399). 15 | 16 | Выходные данные 17 | Выведите на экран фразу: 18 | It is ... hours ... minutes. 19 | 20 | Вместо многоточий программа должна выводить значения h и m, отделяя их 21 | от слов ровно одним пробелом. 22 | 23 | Sample Input: 24 | 13257 25 | 26 | Sample Output: 27 | It is 3 hours 40 minutes. 28 | */ 29 | 30 | func main() { 31 | var k int 32 | fmt.Scan(&k) 33 | 34 | hours := k / 3600 35 | minutes := k / 60 % 60 36 | fmt.Printf("It is %d hours %d minutes.", hours, minutes) 37 | } 38 | -------------------------------------------------------------------------------- /2.7/2.7_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Дана строка, содержащая только десятичные цифры. Найти и вывести наибольшую цифру. 9 | 10 | Входные данные 11 | Вводится строка ненулевой длины. Известно также, что длина строки не превышает 12 | 1000 знаков и строка содержит только десятичные цифры. 13 | 14 | Выходные данные 15 | Выведите максимальную цифру, которая встречается во введенной строке. 16 | 17 | Sample Input: 18 | 1112221112 19 | 20 | Sample Output: 21 | 2 22 | */ 23 | 24 | func main() { 25 | var text string 26 | _, err := fmt.Scan(&text) 27 | if err != nil { 28 | panic("invalid input values") 29 | } 30 | 31 | bs := []rune(text) 32 | maxR := bs[0] 33 | 34 | for i := 1; i < len(bs); i++ { 35 | r := bs[i] 36 | if r > maxR { 37 | maxR = r 38 | } 39 | } 40 | 41 | fmt.Println(string(maxR)) 42 | } 43 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step5__sync_WaitGroup.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | /* 9 | Внутри функции main (функцию объявлять не нужно), вам необходимо в отдельных горутинах 10 | вызвать функцию work() 10 раз и дождаться результатов выполнения вызванных функций. 11 | 12 | Функция work() ничего не принимает и не возвращает. Пакет "sync" уже импортирован. 13 | */ 14 | 15 | func main() { 16 | fmt.Println("Started!") 17 | 18 | work := func() { 19 | // Будет определена в stepic 20 | } 21 | 22 | wg := new(sync.WaitGroup) 23 | 24 | for i := 0; i < 10; i++ { 25 | wg.Add(1) 26 | go func() { 27 | defer wg.Done() 28 | work() 29 | }() 30 | } 31 | 32 | wg.Wait() // Ожидание завершения всех горутин в группе 33 | fmt.Println("Горутины завершили выполнение") 34 | 35 | fmt.Println("Finish!") 36 | } 37 | -------------------------------------------------------------------------------- /1.12/1.12_step15.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Дан массив, состоящий из целых чисел. Нумерация элементов начинается с 0. 9 | Напишите программу, которая выведет элементы массива, индексы которых четны 10 | (0, 2, 4...). 11 | 12 | Входные данные 13 | Сначала задано число N — количество элементов в массиве (1 ≤ N ≤ 100). 14 | Далее через пробел записаны NNN чисел — элементы массива. 15 | Массив состоит из целых чисел. 16 | 17 | Выходные данные 18 | Необходимо вывести все элементы массива с чётными номерами. 19 | 20 | Sample Input: 21 | 6 22 | 4 5 3 4 2 3 23 | 24 | Sample Output: 25 | 4 3 2 26 | */ 27 | 28 | func main() { 29 | var n uint 30 | fmt.Scan(&n) 31 | 32 | items := make([]int, n) 33 | for i := range items { 34 | fmt.Scan(&items[i]) 35 | } 36 | 37 | for i, x := range items { 38 | if i%2 == 0 { 39 | fmt.Print(x, " ") 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /1.13/1.13_step14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | /* 9 | Номер числа Фибоначчи 10 | Дано натуральное число A > 1. Определите, каким по счету числом Фибоначчи 11 | оно является, то есть выведите такое число n, что φn=A. Если А не является 12 | числом Фибоначчи, выведите число -1. 13 | 14 | Входные данные 15 | Вводится натуральное число. 16 | 17 | Выходные данные 18 | Выведите ответ на задачу. 19 | 20 | Sample Input: 21 | 8 22 | 23 | Sample Output: 24 | 6 25 | */ 26 | 27 | func fib(n int) int { 28 | a := 0 29 | b := 1 30 | for i := 0; i < n; i++ { 31 | a, b = b, b+a 32 | } 33 | return a 34 | } 35 | 36 | func main() { 37 | var n int 38 | _, err := fmt.Scan(&n) 39 | if err != nil { 40 | log.Fatalln(err) 41 | } 42 | 43 | for i := 0; i < n; i++ { 44 | if n == fib(i) { 45 | fmt.Println(i) 46 | return 47 | } 48 | } 49 | 50 | fmt.Println(-1) 51 | } 52 | -------------------------------------------------------------------------------- /1.10/1.10_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Последовательность состоит из натуральных чисел и завершается числом 0. 7 | Определите количество элементов этой последовательности, которые равны 8 | ее наибольшему элементу. 9 | 10 | Формат входных данных 11 | Вводится непустая последовательность натуральных чисел, оканчивающаяся числом 12 | 0 (само число 0 в последовательность не входит, а служит как признак ее окончания). 13 | 14 | Формат выходных данных 15 | Выведите ответ на задачу. 16 | 17 | Sample Input: 18 | 1 19 | 3 20 | 3 21 | 1 22 | 0 23 | 24 | Sample Output: 25 | 2 26 | */ 27 | 28 | func main() { 29 | var n int 30 | max := 0 31 | number := 0 32 | 33 | for { 34 | fmt.Scan(&n) 35 | if n == 0 { 36 | break 37 | } 38 | 39 | if n > max { 40 | max = n 41 | number = 0 42 | } 43 | if n == max { 44 | number++ 45 | } 46 | } 47 | fmt.Println(number) 48 | } 49 | -------------------------------------------------------------------------------- /3.6__JSON/3.6_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | ) 8 | 9 | func main() { 10 | type testStruct struct { 11 | Name string `json:"name"` 12 | Age int `json:"age"` 13 | } 14 | 15 | var ( 16 | src = testStruct{Name: "John Connor", Age: 35} // Структура с данными 17 | dst = testStruct{} // Структура без данных 18 | buf = new(bytes.Buffer) // Буфер для чтения и записи 19 | ) 20 | 21 | enc := json.NewEncoder(buf) // Работа с одним и тем же буфером 22 | dec := json.NewDecoder(buf) // Работа с одним и тем же буфером 23 | 24 | err := enc.Encode(src) // Записываем структуру src в буфер 25 | if err != nil { 26 | panic(err) 27 | } 28 | 29 | err = dec.Decode(&dst) // Из буфера заполняем структуру dst 30 | if err != nil { 31 | panic(err) 32 | } 33 | 34 | fmt.Println(dst) 35 | // {John Connor 35} 36 | } 37 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | /* 9 | На стандартный ввод подается строковое представление даты и времени в следующем формате: 10 | 1986-04-16T05:20:00+06:00 11 | 12 | Ваша задача конвертировать эту строку в Time, а затем вывести в формате UnixDate: 13 | Wed Apr 16 05:20:00 +0600 1986 14 | 15 | Для более эффективной работы рекомендуется ознакомиться с документацией о содержащихся в 16 | модуле time константах. 17 | 18 | Sample Input: 19 | 1986-04-16T05:20:00+06:00 20 | 21 | Sample Output: 22 | Wed Apr 16 05:20:00 +0600 1986 23 | */ 24 | 25 | func main() { 26 | var dateStr string 27 | _, err := fmt.Scan(&dateStr) 28 | if err != nil { 29 | panic(err) 30 | } 31 | //dateStr = "1986-04-16T05:20:00+06:00" 32 | 33 | date, err := time.Parse(time.RFC3339, dateStr) 34 | if err != nil { 35 | panic(err) 36 | } 37 | 38 | fmt.Println(date.Format(time.UnixDate)) 39 | } 40 | -------------------------------------------------------------------------------- /2.5/2.5_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | "unicode" 9 | ) 10 | 11 | /* 12 | На вход подается строка. Нужно определить, является ли она правильной или нет. 13 | Правильная строка начинается с заглавной буквы и заканчивается точкой. 14 | Если строка правильная - вывести Right иначе - вывести Wrong 15 | 16 | Маленькая подсказка: fmt.Scan() считывает строку до первого пробела, вы можете 17 | считать полностью строку за раз с помощью bufio: 18 | text, _ := bufio.NewReader(os.Stdin).ReadString('\n') 19 | 20 | Sample Input: 21 | Быть или не быть. 22 | 23 | Sample Output: 24 | Right 25 | */ 26 | 27 | func main() { 28 | text, _ := bufio.NewReader(os.Stdin).ReadString('\n') 29 | text = strings.TrimSpace(text) 30 | 31 | rs := []rune(text) 32 | 33 | if unicode.IsUpper(rs[0]) && strings.HasSuffix(text, ".") { 34 | fmt.Println("Right") 35 | } else { 36 | fmt.Println("Wrong") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /1.13/1.13_step12.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | По данному числу n закончите фразу "На лугу пасется..." одним из возможных 7 | продолжений: "n коров", "n корова", "n коровы", правильно склоняя слово "корова". 8 | 9 | Входные данные 10 | Дано число n (0= 10 { 33 | newN := 0 34 | for n > 0 { 35 | newN += n % 10 36 | n /= 10 37 | } 38 | n = newN 39 | } 40 | fmt.Println(n) 41 | } 42 | -------------------------------------------------------------------------------- /2.5/2.5_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | На вход подается строка. Нужно определить, является ли она палиндромом. 7 | Если строка является паллиндромом - вывести Палиндром иначе - вывести Нет. 8 | Все входные строчки в нижнем регистре. 9 | 10 | Палиндром — буквосочетание, слово или текст, одинаково читающееся в обоих 11 | направлениях (например, "топот", "око", "заказ"). 12 | 13 | Sample Input: 14 | топот 15 | 16 | Sample Output: 17 | Палиндром 18 | */ 19 | 20 | func ToReversed(text string) string { 21 | rs := []rune(text) 22 | 23 | reversed_bs := make([]rune, len(rs)) 24 | for i := 0; i < len(reversed_bs); i++ { 25 | reversed_bs[i] = rs[len(reversed_bs)-i-1] 26 | } 27 | return string(reversed_bs) 28 | } 29 | 30 | func main() { 31 | var text string 32 | _, _ = fmt.Scan(&text) 33 | 34 | reversed := ToReversed(text) 35 | 36 | if text == reversed { 37 | fmt.Println("Палиндром") 38 | } else { 39 | fmt.Println("Нет") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /1.12/1.12_step16.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Дана последовательность, состоящая из целых чисел. Напишите программу, 9 | которая подсчитывает количество положительных чисел среди элементов 10 | последовательности. 11 | 12 | Входные данные 13 | Сначала задано число N — количество элементов в последовательности (1 ≤ N ≤ 100). 14 | Далее через пробел записаны N чисел — элементы последовательности. 15 | Последовательность состоит из целых чисел. 16 | 17 | Выходные данные 18 | Необходимо вывести единственное число - количество положительных элементов 19 | в последовательности. 20 | 21 | Sample Input: 22 | 5 23 | 1 2 3 -1 -4 24 | 25 | Sample Output: 26 | 3 27 | */ 28 | 29 | func main() { 30 | var n, number uint 31 | fmt.Scan(&n) 32 | 33 | items := make([]int, n) 34 | for i := range items { 35 | fmt.Scan(&items[i]) 36 | } 37 | 38 | for _, x := range items { 39 | if x > 0 { 40 | number++ 41 | } 42 | } 43 | 44 | fmt.Println(number) 45 | } 46 | -------------------------------------------------------------------------------- /2.5/2.5_step12.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "unicode" 6 | ) 7 | 8 | /* 9 | Ваша задача сделать проверку подходит ли пароль вводимый пользователем под 10 | заданные требования. Длина пароля должна быть не менее 5 символов, он должен 11 | содержать только цифры и буквы латинского алфавита. На вход подается строка-пароль. 12 | Если пароль соответствует требованиям - вывести "Ok", иначе вывести "Wrong password" 13 | 14 | Sample Input: 15 | fdsghdfgjsdDD1 16 | 17 | Sample Output: 18 | Ok 19 | */ 20 | 21 | func IsValidPassword(password string) bool { 22 | rs := []rune(password) 23 | if len(rs) < 5 { 24 | return false 25 | } 26 | 27 | for _, r := range rs { 28 | if !unicode.Is(unicode.Latin, r) && !unicode.Is(unicode.Digit, r) { 29 | return false 30 | } 31 | } 32 | 33 | return true 34 | } 35 | 36 | func main() { 37 | var text string 38 | _, _ = fmt.Scan(&text) 39 | 40 | if IsValidPassword(text) { 41 | fmt.Println("Ok") 42 | } else { 43 | fmt.Println("Wrong password") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step7__time_After__time__Tick.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Started!") 10 | 11 | // func Sleep(d Duration) 12 | // программа засыпает на заданное время 13 | time.Sleep(time.Second * 2) // спим ровно 2 секунды 14 | fmt.Println("Прошло 2 секунды") 15 | 16 | // func After(d Duration) <-chan Time 17 | // создает канал, который через заданное время вернет значение 18 | timer := time.After(time.Second) 19 | <-timer // значение будет получено из канала ровно через 1 секунду 20 | fmt.Println("Прошла 1 секунда") 21 | 22 | // func Tick(d Duration) <-chan Time 23 | // создает канал, который будет посылать сигналы постоянно через заданный промежуток времени 24 | ticker := time.Tick(time.Second) 25 | count := 0 26 | 27 | for { 28 | <-ticker 29 | fmt.Println("Очередной тик") 30 | count++ 31 | if count == 3 { 32 | break 33 | } 34 | } 35 | // Очередной тик 36 | // Очередной тик 37 | // Очередной тик 38 | 39 | fmt.Println("Finish!") 40 | } 41 | -------------------------------------------------------------------------------- /1.11/1.11_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | На вход подается число типа float64. Вам нужно вывести преобразованное число 7 | по правилу: число возводится в квадрат, затем обрезается дробная часть так что 8 | остается 4 знака после запятой. Но если число равно или меньше нуля - выводить: 9 | "число R не подходит", где R - исходное число с 2 цифрами после запятой и с 2 10 | по ширине. 11 | А если число больше чем 10 000 - выводить исходное число в экспоненциальном 12 | представлении (знак экспоненты в нижнем регистре). 13 | 14 | Sample input: 15 | -000012.2123 16 | 17 | Sample output: 18 | число -12.21 не подходит 19 | 20 | Sample input: 21 | 1000001 22 | Sample output: 23 | 1.000001e+06 24 | 25 | Sample Input: 26 | 12.12345678 27 | 28 | Sample Output: 29 | 146.9782 30 | */ 31 | 32 | func main() { 33 | var n float32 34 | fmt.Scan(&n) 35 | 36 | pow_n := n * n 37 | 38 | if n <= 0 { 39 | fmt.Printf("число %2.2f не подходит", n) 40 | } else if pow_n > 10_000 { 41 | fmt.Printf("%e", n) 42 | } else { 43 | fmt.Printf("%.4f", pow_n) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /3.3/3.3_step1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "unicode" 7 | ) 8 | 9 | func invert(r rune) rune { 10 | // Если буква строчная, то она возвращается заглавной 11 | if unicode.IsLower(r) { 12 | return unicode.ToUpper(r) 13 | } 14 | // Иначе возвращается строчной 15 | return unicode.ToLower(r) 16 | } 17 | 18 | func returnFunction() func(rune) rune { 19 | return invert 20 | } 21 | 22 | func main() { 23 | src := "aBcDeFg" 24 | test := "AbCdEfG" 25 | 26 | // Обратите внимание, что скобки после имени функции используются только при ее вызове 27 | src1 := strings.Map(invert, src) 28 | src2 := strings.Map(returnFunction(), src) 29 | 30 | fmt.Printf("Инвертированная строка: %s. Результат: %v.\n", src, src1 == test) 31 | // Инвертированная строка: AbCdEfG. Результат: true. 32 | 33 | fmt.Printf("Инвертированная строка: %s. Результат: %v.\n", src, src2 == test) 34 | // Инвертированная строка: AbCdEfG. Результат: true. 35 | 36 | fmt.Println() 37 | 38 | fmt.Println(src == strings.Map(invert, strings.Map(invert, src))) 39 | // true 40 | } 41 | -------------------------------------------------------------------------------- /2.7/2.7_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Дана строка, содержащая только английские буквы (большие и маленькие). 9 | Добавить символ ‘*’ (звездочка) между буквами (перед первой буквой и после 10 | последней символ ‘*’ добавлять не нужно). 11 | 12 | Входные данные 13 | Вводится строка ненулевой длины. Известно также, что длина строки не превышает 14 | 1000 знаков. 15 | 16 | Выходные данные 17 | Вывести строку, которая получится после добавления символов '*'. 18 | 19 | Sample Input: 20 | LItBeoFLcSGBOFQxMHoIuDDWcqcVgkcRoAeocXO 21 | 22 | Sample Output: 23 | L*I*t*B*e*o*F*L*c*S*G*B*O*F*Q*x*M*H*o*I*u*D*D*W*c*q*c*V*g*k*c*R*o*A*e*o*c*X*O 24 | 25 | Sample Input: 26 | LItBeoFLcSGBOFQxMHoIuDDWcqcVgkcRoAeocXO 27 | 28 | Sample Output: 29 | L*I*t*B*e*o*F*L*c*S*G*B*O*F*Q*x*M*H*o*I*u*D*D*W*c*q*c*V*g*k*c*R*o*A*e*o*c*X*O 30 | */ 31 | 32 | func main() { 33 | var text string 34 | _, err := fmt.Scan(&text) 35 | if err != nil { 36 | panic("invalid input values") 37 | } 38 | bs := []rune(text) 39 | 40 | fmt.Print(string(bs[0])) 41 | for i := 1; i < len(bs); i++ { 42 | fmt.Print("*", string(bs[i])) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /2.6/2.6_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | /* 9 | Вы должны вызвать функцию divide которая делит два числа, но она возвращает 10 | не только результат деления, но и информацию об ошибке. В случае какой-либо 11 | ошибки вы должны вывести "ошибка", если ошибки нет - результат функции. 12 | Функция divide(a int, b int) (int, error) получает на вход два числа которые 13 | нужно поделить и возвращает результат (int) и ошибку (error). 14 | Не забудьте считать два числа которые необходимо поделить (передать в функцию)! 15 | 16 | Sample Input: 17 | 10 5 18 | 19 | Sample Output: 20 | 2 21 | */ 22 | 23 | func divide(a, b float64) (float64, error) { 24 | if b == 0 { 25 | return 0, errors.New("division by 0") 26 | } 27 | 28 | return a / b, nil 29 | } 30 | 31 | func main() { 32 | var a, b float64 33 | _, err := fmt.Scan(&a, &b) 34 | if err != nil { 35 | fmt.Println("ошибка") 36 | return 37 | } 38 | 39 | c, err := divide(a, b) 40 | if err != nil { 41 | fmt.Println("ошибка") 42 | return 43 | } 44 | 45 | fmt.Println(c) 46 | 47 | //fmt.Println(divide(4, 2)) 48 | //fmt.Println(divide(4, 0)) 49 | } 50 | -------------------------------------------------------------------------------- /3.5/3.5_step11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func walkFunc(path string, info os.FileInfo, err error) error { 10 | if err != nil { 11 | return err // Если по какой-то причине мы получили ошибку, проигнорируем эту итерацию 12 | } 13 | 14 | // Проигнорируем директории 15 | if info.IsDir() { 16 | // Не спускаемся в директории .git и .idea 17 | if info.Name() == ".git" || info.Name() == ".idea" { 18 | return filepath.SkipDir 19 | } 20 | 21 | return nil 22 | } 23 | 24 | fmt.Printf("Name: %s\tSize: %d byte\tPath: %s\n", info.Name(), info.Size(), path) 25 | return nil 26 | } 27 | 28 | func main() { 29 | const root = "." 30 | 31 | if err := filepath.Walk(root, walkFunc); err != nil { 32 | fmt.Printf("Какая-то ошибка: %v\n", err) 33 | } 34 | // Name: .gitignore Size: 269 byte Path: .gitignore 35 | // Name: 1.10_step10.go Size: 909 byte Path: 1.10\1.10_step10.go 36 | // Name: 1.10_step2.go Size: 96 byte Path: 1.10\1.10_step2.go 37 | // Name: 1.10_step3.go Size: 508 byte Path: 1.10\1.10_step3.go 38 | // Name: 1.10_step4.go Size: 736 byte Path: 1.10\1.10_step4.go 39 | // ... 40 | } 41 | -------------------------------------------------------------------------------- /3.5/3.5_step14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | /* 11 | Данная задача в основном ориентирована на изучение типа bufio.Reader, поскольку этот тип позволяет 12 | считывать данные постепенно. 13 | 14 | В тестовом файле, который вы можете скачать из нашего репозитория на github.com, содержится 15 | длинный ряд чисел, разделенных символом ";". Требуется найти, на какой позиции находится 16 | число 0 и указать его в качестве ответа. Требуется вывести именно позицию числа, а не индекс 17 | (то-есть порядковый номер, нумерация с 1). 18 | 19 | Например: 12;234;6;0;78 : 20 | Правильный ответ будет порядковый номер числа: 4 21 | */ 22 | 23 | func main() { 24 | const URL = "https://github.com/semyon-dev/stepik-go/raw/master/work_with_files/task_sep_1/task.data" 25 | 26 | rs, err := http.Get(URL) 27 | if err != nil { 28 | panic(err) 29 | } 30 | defer rs.Body.Close() 31 | 32 | rd := bufio.NewReader(rs.Body) 33 | 34 | i := 1 35 | for { 36 | s, err := rd.ReadString(';') 37 | if err == io.EOF { 38 | break 39 | } 40 | 41 | if s == "0;" { 42 | fmt.Println(i) 43 | break 44 | } 45 | i++ 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step6__sync_Mutex.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("Started!") 10 | 11 | const N = 1000 12 | 13 | // NOTE: WRONG. Result x will not 1000 14 | { 15 | var x int 16 | wg := new(sync.WaitGroup) 17 | 18 | for i := 0; i < N; i++ { 19 | // Запускаем 1000 экземпляров горутины, увеличивающей счетчик на 1 20 | wg.Add(1) 21 | go func(wg *sync.WaitGroup) { 22 | defer wg.Done() 23 | x++ 24 | }(wg) 25 | } 26 | 27 | wg.Wait() 28 | 29 | // По идее значение счетчика должно быть 1000, но крайне вероятно, 30 | // что этого не произойдет 31 | fmt.Println(x) 32 | } 33 | 34 | // That's right. 35 | { 36 | var x int 37 | wg := new(sync.WaitGroup) 38 | mu := new(sync.Mutex) 39 | 40 | for i := 0; i < N; i++ { 41 | // Запускаем 1000 экземпляров горутины, увеличивающей счетчик на 1 42 | wg.Add(1) 43 | go func(wg *sync.WaitGroup, mu *sync.Mutex) { 44 | defer wg.Done() 45 | mu.Lock() 46 | x++ 47 | mu.Unlock() 48 | }(wg, mu) 49 | } 50 | 51 | wg.Wait() 52 | fmt.Println(x) 53 | } 54 | 55 | fmt.Println("Finish!") 56 | } 57 | -------------------------------------------------------------------------------- /3.3/3.3_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "unicode" 7 | ) 8 | 9 | func main() { 10 | src := "aBcDeFg" 11 | test := "AbCdEfG" 12 | 13 | // Обратите внимание, что скобки после имени функции используются только при ее вызове 14 | src = strings.Map(func(r rune) rune { 15 | if unicode.IsLower(r) { 16 | return unicode.ToUpper(r) 17 | } 18 | return unicode.ToLower(r) 19 | }, src) 20 | 21 | fmt.Printf("Инвертированная строка: %s. Результат: %v.\n", src, src == test) 22 | // Инвертированная строка: AbCdEfG. Результат: true. 23 | 24 | fmt.Println() 25 | 26 | // Присваивание переменной значение анонимной функции 27 | fn := func(a, b int) int { return a + b } 28 | fmt.Println(fn(17, 15)) 29 | // 32 30 | 31 | invertBin := func(r rune) rune { 32 | switch r { 33 | case '0': 34 | return '1' 35 | case '1': 36 | return '0' 37 | default: 38 | return r 39 | } 40 | } 41 | fmt.Println(strings.Map(invertBin, "bin: 101010")) 42 | // bin: 010101 43 | 44 | // Выполняем анонимную функцию на месте 45 | // Обратите внимание на использование скобок при вызове функции 46 | func(a, b int) { 47 | fmt.Println(a + b) 48 | }(12, 34) 49 | // 46 50 | } 51 | -------------------------------------------------------------------------------- /3.3/3.3_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | /* 9 | Внутри функции main (объявлять ее не нужно) вы должны объявить функцию вида 10 | func(uint) uint, которую внутри функции main в дальнейшем можно будет вызвать 11 | по имени fn. 12 | 13 | Функция на вход получает целое положительное число (uint), возвращает число 14 | того же типа в котором отсутствуют нечетные цифры или цифра 0, если же получившееся 15 | число равно 0, то возвращается число 100. Цифры в возвращаемом числе имеют тот же 16 | порядок, что и в исходном числе. 17 | 18 | Пакет main объявлять не нужно! 19 | Вводить и выводить что-либо не нужно! 20 | Уже импортированы - "fmt" и "strconv", другие пакеты импортировать нельзя. 21 | 22 | Sample Input: 23 | 727178 24 | 25 | Sample Output: 26 | 28 27 | */ 28 | 29 | func main() { 30 | fn := func(num uint) uint { 31 | numStr := strconv.FormatUint(uint64(num), 10) 32 | rs := make([]rune, 0, len(numStr)) 33 | 34 | for _, r := range numStr { 35 | if r%2 == 0 { 36 | rs = append(rs, r) 37 | } 38 | } 39 | numStr = string(rs) 40 | 41 | x, _ := strconv.Atoi(numStr) 42 | if x == 0 { 43 | x = 100 44 | } 45 | 46 | return uint(x) 47 | } 48 | 49 | fmt.Println(fn(727178)) 50 | // 28 51 | } 52 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | "time" 9 | ) 10 | 11 | /* 12 | На стандартный ввод подается строковое представление даты и времени определенного события в 13 | следующем формате: 14 | 2020-05-15 08:00:00 15 | 16 | Если время события до обеда (13-00), то ничего менять не нужно, достаточно вывести дату на 17 | стандартный вывод в том же формате. 18 | Если же событие должно произойти после обеда, необходимо перенести его на то же время на 19 | следующий день, а затем вывести на стандартный вывод в том же формате. 20 | 21 | Sample Input: 22 | 2020-05-15 08:00:00 23 | 24 | Sample Output: 25 | 2020-05-15 08:00:00 26 | */ 27 | 28 | func main() { 29 | var dateStr string 30 | dateStr, err := bufio.NewReader(os.Stdin).ReadString('\n') 31 | if err != nil { 32 | panic(err) 33 | } 34 | dateStr = strings.TrimSpace(dateStr) 35 | 36 | //dateStr = "2020-05-15 08:00:00" 37 | //dateStr = "2020-05-15 14:00:00" 38 | 39 | const dateLayout = "2006-01-02 15:04:05" 40 | 41 | date, err := time.Parse(dateLayout, dateStr) 42 | if err != nil { 43 | panic(err) 44 | } 45 | 46 | if date.Hour() >= 13 { 47 | date = date.Add(time.Hour * 24) 48 | } 49 | 50 | fmt.Println(date.Format(dateLayout)) 51 | } 52 | -------------------------------------------------------------------------------- /3.8__Goroutines_go_chan/3.8_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("Started!") 11 | 12 | { 13 | c := make(chan string) 14 | 15 | f := func(c chan string) { 16 | c <- "1" 17 | c <- "2" 18 | c <- "3" 19 | close(c) 20 | } 21 | go f(c) 22 | 23 | for i := 0; i < 3; i++ { 24 | fmt.Println(<-c) 25 | } 26 | 27 | fmt.Println() 28 | } 29 | 30 | { 31 | const N = 5 32 | 33 | worker := func(wg *sync.WaitGroup, c chan string, name string, timeout time.Duration) { 34 | defer wg.Done() 35 | 36 | for i := 1; i <= N; i++ { 37 | c <- fmt.Sprintf("[%v] %v", name, i) 38 | time.Sleep(timeout) 39 | } 40 | } 41 | 42 | monitorWorker := func(wg *sync.WaitGroup, cs chan string) { 43 | wg.Wait() 44 | close(cs) 45 | } 46 | 47 | wg := &sync.WaitGroup{} 48 | c := make(chan string, 10) 49 | 50 | wg.Add(1) 51 | go worker(wg, c, "a", time.Millisecond*100) 52 | 53 | wg.Add(1) 54 | go worker(wg, c, "b", time.Millisecond*300) 55 | 56 | wg.Add(1) 57 | go worker(wg, c, "c", time.Millisecond*50) 58 | 59 | go monitorWorker(wg, c) 60 | 61 | for x := range c { 62 | fmt.Println(x) 63 | } 64 | } 65 | 66 | fmt.Println("Finish!") 67 | } 68 | -------------------------------------------------------------------------------- /3.6__JSON/3.6_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | func main() { 9 | // Аннотация выглядит так: `json:"используемое_имя,опция,опция"` 10 | 11 | type myStruct struct { 12 | // При кодировании / декодировании будет использовано имя name, а не Name 13 | Name string `json:"name"` 14 | 15 | Comment string 16 | 17 | // При кодировании / декодировании будет использовано то же имя (Age), 18 | // но если значение поля равно 0 (пустое значение: false, nil, пустой слайс и пр.), 19 | // то при кодировании оно будет опущено 20 | Age int `json:",omitempty"` 21 | 22 | // При кодировании / декодировании поле всегда игнорируется 23 | Status bool `json:"-"` 24 | 25 | // Поля в нижнем регистре не (де)сериализуются 26 | notExported string 27 | } 28 | 29 | m := myStruct{Name: "John Connor", Age: 0, Status: true} 30 | data, err := json.Marshal(m) 31 | if err != nil { 32 | panic(err) 33 | } 34 | fmt.Printf("%s\n", data) 35 | // {"name":"John Connor","Comment":""} 36 | 37 | m = myStruct{Name: "John Connor", Age: 99, Status: false, Comment: "Not alive"} 38 | data, err = json.Marshal(m) 39 | if err != nil { 40 | panic(err) 41 | } 42 | fmt.Printf("%s\n", data) 43 | // {"name":"John Connor","Comment":"Not alive","Age":99} 44 | } 45 | -------------------------------------------------------------------------------- /2.4/2.4_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | Вам необходимо реализовать структуру со свойствами-полями On, Ammo и Power, 7 | с типами bool, int, int соответственно. У этой структуры должны быть методы: 8 | Shoot и RideBike, которые не принимают аргументов, но возвращают значение bool. 9 | Если значение On == false, то оба метода вернут false. 10 | 11 | Делать Shoot можно только при наличии Ammo (тогда Ammo уменьшается на единицу, 12 | а метод возвращает true), если его нет, то метод вернет false. 13 | Метод RideBike работает также, но только зависит от свойства Power. 14 | 15 | Чтобы проверить, что вы все сделали правильно, вы должны создать указатель на 16 | экземпляр этой структуры с именем testStruct в функции main, в дальнейшем 17 | программа проверит результат. 18 | */ 19 | 20 | type Terminator struct { 21 | On bool 22 | Ammo, Power uint 23 | } 24 | 25 | func (obj *Terminator) Shoot() bool { 26 | if obj.On == false || obj.Ammo == 0 { 27 | return false 28 | } 29 | obj.Ammo-- 30 | return true 31 | } 32 | 33 | func (obj *Terminator) RideBike() bool { 34 | if obj.On == false || obj.Power == 0 { 35 | return false 36 | } 37 | obj.Power-- 38 | return true 39 | } 40 | 41 | func main() { 42 | testStruct := new(Terminator) 43 | fmt.Println(testStruct) 44 | } 45 | -------------------------------------------------------------------------------- /3.2/3.2_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | var index int8 = 15 10 | var bigIndex int32 11 | bigIndex = int32(index) 12 | fmt.Printf("%v %T\n", bigIndex, bigIndex) // 15 int32 13 | 14 | // По аналогии выше легко понять как конвертировать в другие типы: 15 | var a int32 = 22 16 | var b = uint64(a) 17 | fmt.Printf("%v %T\n", b, b) // 22 uint64 18 | 19 | var big int64 = 64 20 | var little = int8(big) 21 | fmt.Printf("%v %T\n", little, little) // 64 int8 22 | 23 | var big2 int64 = 129 24 | var little2 = int8(big2) 25 | fmt.Printf("%v %T\n", little2, little2) // -127 int8 26 | 27 | fmt.Println() 28 | 29 | fmt.Println("MaxInt8: ", int8(math.MaxInt8)) 30 | fmt.Println("MinInt8: ", int8(math.MinInt8)) 31 | fmt.Println("MaxInt16: ", int16(math.MaxInt16)) 32 | fmt.Println("MinInt16: ", int16(math.MinInt16)) 33 | fmt.Println("MaxInt32: ", int32(math.MaxInt32)) 34 | fmt.Println("MinInt32: ", int32(math.MinInt32)) 35 | fmt.Println("MaxInt64: ", int64(math.MaxInt64)) 36 | fmt.Println("MinInt64: ", int64(math.MinInt64)) 37 | fmt.Println("MaxUint8: ", uint8(math.MaxUint8)) 38 | fmt.Println("MaxUint16: ", uint16(math.MaxUint16)) 39 | fmt.Println("MaxUint32: ", uint32(math.MaxUint32)) 40 | fmt.Println("MaxUint64: ", uint64(math.MaxUint64)) 41 | } 42 | -------------------------------------------------------------------------------- /3.1/3.1_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func main() { 9 | m := map[int]int{ 10 | 12: 2, 11 | 1: 5, 12 | } 13 | fmt.Println(m) // map[1:5 12:2] 14 | fmt.Println(len(m)) // 2 15 | fmt.Println(m[12]) // 2 16 | 17 | fmt.Println() 18 | 19 | for key, value := range m { 20 | fmt.Printf("for. key: %v, value: %v\n", key, value) 21 | } 22 | 23 | fmt.Println() 24 | 25 | var value int 26 | var hasValue bool 27 | 28 | value, hasValue = m[404] 29 | fmt.Println(value, hasValue) // 0 false 30 | 31 | value, hasValue = m[1] 32 | fmt.Println(value, hasValue) // 5 true 33 | 34 | fmt.Println() 35 | 36 | delete(m, 12) 37 | fmt.Println(m) // map[1:5 12:2] 38 | 39 | fmt.Println() 40 | 41 | if value, ok := m[1]; ok { 42 | fmt.Println("key: 1, value:", value) // 10 43 | } 44 | 45 | if value, ok := m[404]; ok { 46 | fmt.Println("key: 404, value:", value) // Условие не выполняется 47 | } 48 | 49 | fmt.Println() 50 | 51 | cityPopulation := map[string]int{ 52 | "A_10": 10, "B_10": 15, "C_10": 20, 53 | "A_100": 100, "B_100": 200, "C_100": 400, 54 | "A_1000": 1001, "B_1000": 2000, "C_1000": 3000, 55 | } 56 | for k := range cityPopulation { 57 | if strings.HasPrefix(k, "C_") { 58 | delete(cityPopulation, k) 59 | } 60 | } 61 | fmt.Println(cityPopulation) 62 | // map[A_10:10 A_100:100 A_1000:1001 B_10:15 B_100:200 B_1000:2000] 63 | } 64 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | /* 13 | На стандартный ввод подается строковое представление двух дат, разделенных запятой (формат данных 14 | смотрите в примере). 15 | 16 | Необходимо преобразовать полученные данные в тип Time, а затем вывести продолжительность периода 17 | между меньшей и большей датами. 18 | 19 | Sample Input: 20 | 13.03.2018 14:00:15,12.03.2018 14:00:15 21 | 22 | Sample Output: 23 | 24h0m0s 24 | */ 25 | 26 | func main() { 27 | var text string 28 | text, err := bufio.NewReader(os.Stdin).ReadString('\n') 29 | if err != nil && err != io.EOF { 30 | panic(err) 31 | } 32 | text = strings.TrimSpace(text) 33 | 34 | //text = "13.03.2018 14:00:15,12.03.2018 14:00:15" 35 | //text = "12.03.2018 14:00:15,13.03.2018 14:00:15" 36 | 37 | items := strings.Split(text, ",") 38 | if len(items) != 2 { 39 | panic("Invalid text format") 40 | } 41 | 42 | dateStr1, dateStr2 := strings.TrimSpace(items[0]), strings.TrimSpace(items[1]) 43 | const dateLayout = "02.01.2006 15:04:05" 44 | 45 | date1, err := time.Parse(dateLayout, dateStr1) 46 | if err != nil { 47 | panic(err) 48 | } 49 | 50 | date2, err := time.Parse(dateLayout, dateStr2) 51 | if err != nil { 52 | panic(err) 53 | } 54 | 55 | if date1.After(date2) { 56 | fmt.Println(date1.Sub(date2)) 57 | } else { 58 | fmt.Println(date2.Sub(date1)) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /3.8__Goroutines_go_chan/3.8_step10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Напишите элемент конвейера (функцию), что запоминает предыдущее значение и отправляет значения 9 | на следующий этап конвейера только если оно отличается от того, что пришло ранее. 10 | 11 | Ваша фукнция должна принимать два канала - inputStream и outputStream, в первый вы будете 12 | получать строки, во второй вы должны отправлять значения без повторов. В итоге в outputStream 13 | должны остаться значения, которые не повторяются подряд. Не забудьте закрыть канал ;) 14 | 15 | Функция должна называться removeDuplicates() 16 | */ 17 | 18 | func removeDuplicates(inputStream <-chan string, outputStream chan<- string) { 19 | defer close(outputStream) 20 | 21 | prevValue := <-inputStream 22 | outputStream <- prevValue 23 | 24 | for value := range inputStream { 25 | if prevValue == value { 26 | continue 27 | } 28 | 29 | outputStream <- value 30 | prevValue = value 31 | } 32 | } 33 | 34 | func main() { 35 | fmt.Println("Started!") 36 | 37 | inputStream := make(chan string) 38 | outputStream := make(chan string) 39 | go removeDuplicates(inputStream, outputStream) 40 | 41 | go func() { 42 | defer close(inputStream) 43 | 44 | for _, r := range "112334456" { 45 | inputStream <- string(r) 46 | } 47 | }() 48 | 49 | for x := range outputStream { 50 | fmt.Print(x) 51 | } 52 | // 123456 53 | 54 | fmt.Println("\nFinish!") 55 | } 56 | -------------------------------------------------------------------------------- /1.7/1.7_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | const ( 7 | Sunday = 0 8 | Monday = 1 9 | Tuesday = 2 10 | Wednesday = 3 11 | Thursday = 4 12 | Friday = 5 13 | Saturday = 6 14 | ) 15 | fmt.Println(Sunday) // вывод 0 16 | fmt.Println(Saturday) // вывод 6 17 | 18 | fmt.Println() 19 | 20 | const ( 21 | Sunday2 = iota 22 | Monday2 23 | Tuesday2 24 | Wednesday2 25 | Thursday2 26 | Friday2 27 | Saturday2 28 | ) 29 | fmt.Println(Sunday2) // вывод 0 30 | fmt.Println(Saturday2) // вывод 6 31 | 32 | const Sunday3 = iota 33 | const Saturday3 = iota 34 | fmt.Println(Sunday3, Saturday3) // 0 0 35 | 36 | fmt.Println() 37 | 38 | const ( 39 | N0 = iota 40 | N1 41 | _ 42 | N3 43 | _ 44 | N5 45 | ) 46 | fmt.Println(N0, N1, N3, N5) // 0 1 3 5 47 | 48 | fmt.Println() 49 | 50 | const ( 51 | A10 = (iota + 1) * 10 52 | A20 53 | A30 54 | ) 55 | fmt.Println(A10, A20, A30) // 10 20 30 56 | 57 | fmt.Println() 58 | 59 | const ( 60 | u = iota * 42 // u == 0 (индекс - 0, поэтому 0 * 42 = 0) 61 | v float64 = iota * 42 // v == 42.0 (индекс - 1, поэтому 1.0 * 42 = 42.0) 62 | c = iota * 42 // w == 84 (индекс - 2, поэтому 2 * 42 = 84) 63 | ) 64 | fmt.Println(u, v, c) // 10 20 30 65 | 66 | fmt.Println() 67 | 68 | const ( 69 | a = iota + 1 70 | _ 71 | b 72 | c2 73 | d = c2 + 2 74 | t 75 | i 76 | i2 = iota + 2 77 | ) 78 | fmt.Println(a, b, c2, d, t, i, i2) // 1 3 4 6 6 6 9 79 | } 80 | -------------------------------------------------------------------------------- /3.3/3.3_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func externalFunction() func() { 8 | text := "TEXT" 9 | 10 | return func() { 11 | fmt.Println(text) 12 | } 13 | } 14 | 15 | func externalFunctionV2(text string) func() { 16 | return func() { 17 | fmt.Println(text) 18 | } 19 | } 20 | 21 | func main() { 22 | { 23 | fn := externalFunction() 24 | fn() 25 | // TEXT 26 | 27 | fnHello := externalFunctionV2("Hello World!") 28 | fnHello() 29 | fnHello() 30 | // Hello World! 31 | // Hello World! 32 | 33 | fmt.Println() 34 | } 35 | 36 | { 37 | fn := func() func() int { 38 | count := 0 39 | return func() int { 40 | count++ 41 | return count 42 | } 43 | }() 44 | 45 | for i := 1; i <= 5; i++ { 46 | fmt.Print(fn()) 47 | } 48 | fmt.Println() 49 | // 12345 50 | 51 | fmt.Println() 52 | } 53 | 54 | { 55 | counterFabric := func(count int) func() int { 56 | return func() int { 57 | count++ 58 | return count 59 | } 60 | } 61 | 62 | fn1 := counterFabric(0) 63 | fmt.Println(fn1(), fn1(), fn1(), fn1(), fn1()) 64 | // 1 2 3 4 5 65 | 66 | fn2 := counterFabric(10) 67 | fmt.Println(fn2(), fn2(), fn2(), fn2(), fn2()) 68 | // 11 12 13 14 15 69 | 70 | fmt.Println() 71 | } 72 | 73 | { 74 | fn := func() func(int) int { 75 | count := 0 76 | return func(i int) int { 77 | count++ 78 | return count * i 79 | } 80 | }() 81 | 82 | for i := 1; i <= 5; i++ { 83 | fmt.Print(fn(i), " ") 84 | } 85 | // 1 4 9 16 25 86 | 87 | fmt.Println() 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /3.5/3.5_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | /* 10 | Задача состоит в следующем: на стандартный ввод подаются целые числа в диапазоне 0-100, каждое 11 | число подается на стандартный ввод с новой строки (количество чисел не известно). 12 | Требуется прочитать все эти числа и вывести в стандартный вывод их сумму. 13 | 14 | Несколько подсказок: для чтения вы можете использовать типы bufio.Reader и bufio.Scanner, 15 | а для записи - bufio.Writer. При чтении помните об ошибке io.EOF. Конвертирование данных 16 | из строки в целое число и обратно осуществляется функциями Atoi и Itoa из пакета strconv 17 | соответственно. Чтение производится из стандартного ввода (os.Stdin), а запись - в стандартный 18 | вывод (os.Stdout). 19 | 20 | Все указанные в тексте задачи пакеты (strconv, bufio, os, io), уже импортированы (другие 21 | использовать нельзя), package main объявлен. 22 | 23 | Sample Input: 24 | 33 25 | 47 26 | 12 27 | 79 28 | 15 29 | 30 | Sample Output: 31 | 186 32 | */ 33 | 34 | func main() { 35 | in := bufio.NewScanner(os.Stdin) 36 | 37 | num := 0 38 | for in.Scan() { 39 | if len(in.Text()) == 0 { 40 | break 41 | } 42 | n, err := strconv.Atoi(in.Text()) 43 | if err != nil { 44 | panic(err) 45 | } 46 | 47 | num += n 48 | } 49 | 50 | _, _ = os.Stdout.WriteString(strconv.Itoa(num)) 51 | // OR: 52 | //_, _ = io.WriteString(os.Stdout, strconv.Itoa(num)) 53 | // 54 | // OR: 55 | //out := bufio.NewWriter(os.Stdout) 56 | //_, _ = out.WriteString(strconv.Itoa(num)) 57 | //_ = out.Flush() 58 | } 59 | -------------------------------------------------------------------------------- /3.1/3.1_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Внутри функции main (объявлять функцию не нужно) необходимо написать программу: 9 | На стандартный ввод подается 10 целых чисел, разделенных пробелами (числа могут 10 | повторяться). Для чтения из стандартного ввода импортирован пакет fmt. 11 | Вам необходимо вычислить результат выполнения функции work для каждого из 12 | полученных чисел. Функция work имеет следующий вид: 13 | func work(x int) int 14 | 15 | Результаты вычислений , разделенные пробелами, должны быть напечатаны в строку. 16 | Однако работа функции work занимает слишком много времени. Выделенного вам времени 17 | выполнения не хватит на последовательную обработку каждого числа, поэтому необходимо 18 | реализовать кэширование уже готовых результатов и использовать их в работе. 19 | После завершения работы программы результат выполнения будет дополнен информацией 20 | о соблюдении установленного лимита времени выполнения. 21 | 22 | Sample Input: 23 | 3 1 5 2 3 5 3 0 3 4 24 | 25 | Sample Output: 26 | 2 0 6 1 2 6 2 -1 2 5 time limit ok 27 | */ 28 | 29 | func work(x int) int { 30 | return x * x 31 | } 32 | 33 | func main() { 34 | const N = 10 35 | cache := map[int]int{} 36 | 37 | var n int 38 | for i := 0; i < N; i++ { 39 | _, err := fmt.Scan(&n) 40 | fmt.Println(n) 41 | if err != nil { 42 | panic(fmt.Sprintf("invalid int value: %d", n)) 43 | } 44 | 45 | // Если значения нет в словаре 46 | if _, ok := cache[n]; !ok { 47 | cache[n] = work(n) 48 | } 49 | n = cache[n] 50 | 51 | fmt.Printf("%d ", n) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | "regexp" 9 | "strconv" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | /* 15 | На стандартный ввод подаются данные о продолжительности периода (формат приведен в примере). Кроме того, 16 | вам дана дата в формате Unix-Time: 1589570165 в виде константы типа int64 (наносекунды для целей 17 | преобразования равны 0). 18 | 19 | Требуется считать данные о продолжительности периода, преобразовать их в тип Duration, а затем 20 | вывести (в формате UnixDate) дату и время, получившиеся при добавлении периода к стандартной дате. 21 | 22 | Небольшая подсказка: базовую дату необходимо явно перенести в зону UTC с помощью одноименного метода. 23 | 24 | Sample Input: 25 | 12 мин. 13 сек. 26 | 27 | Sample Output: 28 | Fri May 15 19:28:18 UTC 2020 29 | */ 30 | 31 | func main() { 32 | startDate := time.Unix(1589570165, 0) 33 | 34 | var text string 35 | text, err := bufio.NewReader(os.Stdin).ReadString('\n') 36 | if err != nil && err != io.EOF { 37 | panic(err) 38 | } 39 | text = strings.TrimSpace(text) 40 | 41 | //text = "12 мин. 13 сек." 42 | //text = "71 мин. 8 сек." 43 | 44 | re := regexp.MustCompile(`(\d+) мин\. (\d+) сек\.`) 45 | items := re.FindStringSubmatch(text) 46 | if len(items) == 0 { 47 | panic("Invalid text format!") 48 | } 49 | 50 | minutes, _ := strconv.Atoi(items[1]) 51 | seconds, _ := strconv.Atoi(items[2]) 52 | d := time.Minute*time.Duration(minutes) + time.Second*time.Duration(seconds) 53 | fmt.Println(startDate.Add(d).UTC().Format(time.UnixDate)) 54 | } 55 | -------------------------------------------------------------------------------- /3.2/3.2_step13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | "unicode" 8 | ) 9 | 10 | /* 11 | Представьте что вы работаете в большой компании где используется 12 | модульная архитектура. Ваш коллега написал модуль с какой-то логикой 13 | (вы не знаете) и передает в вашу программу какие-то данные. Вы же пишите 14 | функцию которая считывает две переменных типа string, а возвращает число 15 | типа int64 которое нужно получить сложением этим строк. 16 | 17 | Но было бы так все просто, ведь ваш коллега не пишет на Go, и он зол из-за 18 | того что гоферам платят больше. Поэтому он решил подшутить над вами и подсунул 19 | вам подвох. Он придумал вставлять мусор в строки перед тем как вызывать вашу функцию. 20 | 21 | Поэтому предварительно вам нужно убрать из них мусор и конвертировать в числа. 22 | Под мусором имеются ввиду лишние символы и спец знаки. Разрешается использовать 23 | только определенные пакеты: fmt, strconv, unicode, strings, bytes. 24 | 25 | Sample Input: 26 | %^80 hhhhh20&&&&nd 27 | 28 | Sample Output: 29 | 100 30 | */ 31 | 32 | func ParseNumber(numStr string) int64 { 33 | builder := strings.Builder{} 34 | for _, r := range numStr { 35 | if unicode.Is(unicode.Digit, r) { 36 | builder.WriteRune(r) 37 | } 38 | } 39 | 40 | number, err := strconv.ParseInt(builder.String(), 10, 64) 41 | if err != nil { 42 | panic(err) 43 | } 44 | 45 | return number 46 | } 47 | 48 | func adding(a, b string) int64 { 49 | return ParseNumber(a) + ParseNumber(b) 50 | } 51 | 52 | func main() { 53 | fmt.Println(adding("%^80", "hhhhh20&&&&nd")) 54 | } 55 | -------------------------------------------------------------------------------- /1.12/1.12_step5.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Внутри функции main (объявлять функцию не нужно) необходимо написать программу: 9 | На первом этапе на стандартный ввод подается 10 целых положительных чисел, 10 | которые должны быть записаны в порядке ввода в массив из 10 элементов. 11 | Тип чисел, входящих в массив, должен соответствовать минимально возможному 12 | целому беззнаковому числу. Имя массива который вы должны сами создать 13 | workArray (условие обязательное). Для чтения из стандартного ввода уже 14 | импортирован пакет fmt. 15 | На втором этапе на стандартный ввод подаются еще 3 пары чисел - индексы 16 | элементов этого массива, которые требуется поменять местами (если такая 17 | пара чисел 3 и 7, значит в массиве элемент с 3 индексом нужно поменять 18 | местами с элементом, индекс которого 7). 19 | 20 | Элементы полученного массива должны быть выведены через пробел на стандартный вывод. 21 | Далее автоматически будет проведена проверка используемых типов, результат которой 22 | будет добавлен к вашему ответу. 23 | 24 | Использование массива - обязательное условие! 25 | 26 | Sample Input: 27 | 99 151 137 71 117 187 20 93 187 67 1 2 3 5 7 8 28 | 29 | Sample Output: 30 | 99 137 151 187 117 71 20 187 93 67 type ok 31 | */ 32 | 33 | func main() { 34 | var workArray [10]uint8 35 | 36 | for i := range workArray { 37 | fmt.Scan(&workArray[i]) 38 | } 39 | 40 | var ind1, ind2 uint 41 | for i := 0; i < 3; i++ { 42 | fmt.Scan(&ind1, &ind2) 43 | workArray[ind1], workArray[ind2] = workArray[ind2], workArray[ind1] 44 | } 45 | 46 | for _, x := range workArray { 47 | fmt.Print(x, " ") 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /3.3/3.3_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | func someFuncWithPanic(needPanic bool) (err error) { 9 | defer func() { 10 | // Отложенный вызов анонимной функции, проверяющей, что работа функции завершена 11 | // без ошибок. Если функция recover() возвращает что угодно кроме nil, значит в ходе 12 | // выполнения функции возникла паника. 13 | if e := recover(); e != nil { 14 | // Здесь происходит приведение интерфейса (об этом мы расскажем буквально в 15 | // следующем уроке. Результат приведения присваивается переменной err типа error 16 | // которая уже объявлена при самом вызове функции someFuncWithPanic. 17 | err = e.(error) 18 | 19 | // После этого анонимная функция завершает свою работу, паника обработана, 20 | // переменная err, в которой содержится информации о возникшей панике, 21 | // возвращается как результат выполнения функции. 22 | } 23 | }() 24 | 25 | if needPanic { 26 | panic(errors.New("fatal error")) 27 | } 28 | 29 | return err 30 | } 31 | 32 | func someFuncWithPanic2() { 33 | panic(errors.New("fatal error someFuncWithPanic2")) 34 | } 35 | 36 | func main() { 37 | defer func() { 38 | if e := recover(); e != nil { 39 | fmt.Println("Recover from:", e) 40 | } 41 | }() 42 | 43 | defer func() { fmt.Println(1) }() 44 | defer func() { fmt.Println(2) }() 45 | defer func() { fmt.Println(3) }() 46 | 47 | fmt.Println("Err1:", someFuncWithPanic(false)) 48 | fmt.Println("Err2:", someFuncWithPanic(true)) 49 | 50 | if err := someFuncWithPanic(false); err != nil { 51 | fmt.Println("Err3:", err) 52 | } 53 | 54 | //panic("error 123") 55 | someFuncWithPanic2() 56 | } 57 | -------------------------------------------------------------------------------- /2.7/2.7_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | /* 9 | Внимательно прочитайте ВСЕ условия и подсказки чтобы правильно решить задачу! 10 | 11 | Требуется вычислить период колебаний (t) математического маятника (мы округлили 12 | некоторые значения для удобства проверки), для этого нужно найти циклическую 13 | частоту колебания пружинного маятника (w), в формуле w встречается масса которую 14 | также нужно найти, все нужные формулы приведены ниже: 15 | 16 | Напишите три функции, каждая из которых будет выполнять конкретную формулу. 17 | Название функций обязательно должны соответствовать букве формулы: T(), W() и M(). 18 | Для того чтобы найти t - необходимо сначало найти w, и тд. Так что используйте 19 | результат функции W() в формуле функции T() - то-есть вызывайте функцию W() в T(). 20 | Анологично и с W(), M(). 21 | t = 6 / w, 22 | w = sqrt(k / m), 23 | m = p ∗ v 24 | 25 | ВАЖНО! считайте что пакет main уже объявлен, а также функция main() с вызовом 26 | ВАШЕЙ будущей функцией T() уже есть. Не смотря на то что тестирование будет 27 | через ввод-вывод вам НЕ требуется вводить и выводить что-либо. Для подсчета 28 | используйте УЖЕ ВВЕДЕННЫЕ ГЛОБАЛЬНЫЕ переменные k,p,v ТИПА float64 !!! 29 | 30 | Пакет math уже импортирован! Напоминаю: корень (sqrt) можно найти с помощью пакета "math", например: 31 | fmt.Println(math.Sqrt(9)) 32 | // результат: 3 33 | 34 | Sample Input: 35 | 1296 6 6 36 | 37 | Sample Output: 38 | 1 39 | */ 40 | 41 | var k, p, v float64 42 | 43 | func T() float64 { 44 | return 6 / W() 45 | } 46 | 47 | func W() float64 { 48 | return math.Sqrt(k / M()) 49 | } 50 | 51 | func M() float64 { 52 | return p * v 53 | } 54 | 55 | func main() { 56 | k, p, v = 1296, 6, 6 57 | fmt.Println(T()) 58 | } 59 | -------------------------------------------------------------------------------- /3.1/3.1_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | https://stepik.org/lesson/345543/step/4?unit=329288 9 | */ 10 | 11 | func main() { 12 | var s1 []map[int]int 13 | fmt.Println(s1) // [] 14 | s1 = append(s1, map[int]int{ 15 | 1: 123, 16 | 2: 456, 17 | 3: 789, 18 | }) 19 | s1 = append(s1, map[int]int{ 20 | 1: 1, 21 | 2: 4, 22 | 3: 9, 23 | }) 24 | fmt.Println(s1) // [map[1:123 2:456 3:789] map[1:1 2:4 3:9]] 25 | fmt.Println(s1[0][1], s1[1][3]) // 123 9 26 | 27 | fmt.Println() 28 | 29 | var s2 []map[int]string 30 | fmt.Println(s2) // [] 31 | s2 = append(s2, map[int]string{ 32 | 1: "123", 33 | 2: "456", 34 | 3: "789", 35 | }) 36 | s2 = append(s2, map[int]string{ 37 | 1: "1", 38 | 2: "4", 39 | 3: "9", 40 | }) 41 | fmt.Println(s2) // [map[1:123 2:456 3:789] map[1:1 2:4 3:9]] 42 | fmt.Println(s2[0][1], s2[1][3]) // 123 9 43 | 44 | fmt.Println() 45 | 46 | m1 := make(map[float32]int) 47 | m1[1.23] = 123 48 | m1[4.56] = 456 49 | m1[7.89] = 789 50 | fmt.Println(m1) // map[1.23:123 4.56:456 7.89:789] 51 | 52 | fmt.Println() 53 | 54 | m2 := map[string][]string{ 55 | "result_1": {"1", "abc"}, 56 | "result_2": {"123"}, 57 | } 58 | m2["result_3"] = []string{"999"} 59 | fmt.Println(m2) // map[result_1:[1 abc] result_2:[123] result_3:[999]] 60 | 61 | fmt.Println() 62 | 63 | m3 := map[string]map[string]string{ 64 | "result_1": { 65 | "1": "123", 66 | "abc": "999", 67 | }, 68 | "result_2": { 69 | "value": "123", 70 | }, 71 | } 72 | m3["result_3"] = map[string]string{ 73 | "999": "777", 74 | } 75 | m3["result_4"] = nil 76 | fmt.Println(m3) // map[result_1:map[1:123 abc:999] result_2:map[value:123] result_3:map[999:777] result_4:map[]] 77 | } 78 | -------------------------------------------------------------------------------- /3.6__JSON/3.6_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | ) 8 | 9 | /* 10 | Данная задача ориентирована на реальную работу с данными в формате JSON. Для решения мы будем 11 | использовать справочник ОКВЭД (Общероссийский классификатор видов экономической деятельности), 12 | который был размещен на web-портале data.gov.ru. 13 | 14 | Необходимая вам информация о структуре данных содержится в файле structure-20190514T0000.json, 15 | а сами данные, которые вам потребуется декодировать, содержатся в файле data-20190514T0100.json. 16 | Файлы размещены в https://github.com/semyon-dev/stepik-go/tree/master/work_with_json. 17 | 18 | Для того, чтобы показать, что вы действительно смогли декодировать документ вам необходимо в 19 | качестве ответа записать сумму полей global_id всех элементов, закодированных в файле. 20 | */ 21 | 22 | type Item struct { 23 | SystemObjectId string `json:"system_object_id"` 24 | Kod string `json:"Kod"` 25 | IsDeleted int `json:"is_deleted"` 26 | SignatureDate string `json:"signature_date"` 27 | Nomdescr string `json:"Nomdescr"` 28 | GlobalId int `json:"global_id"` 29 | Idx string `json:"Idx"` 30 | Razdel string `json:"Razdel"` 31 | Name string `json:"Name"` 32 | } 33 | 34 | func main() { 35 | const URL = "https://raw.githubusercontent.com/semyon-dev/stepik-go/master/work_with_json/data-20190514T0100.json" 36 | 37 | rs, err := http.Get(URL) 38 | if err != nil { 39 | panic(err) 40 | } 41 | defer rs.Body.Close() 42 | 43 | dec := json.NewDecoder(rs.Body) 44 | 45 | var items []Item 46 | err = dec.Decode(&items) 47 | if err != nil { 48 | panic(err) 49 | } 50 | 51 | sum := 0 52 | for _, x := range items { 53 | sum += x.GlobalId 54 | } 55 | fmt.Println(sum) 56 | // 763804981288 57 | } 58 | -------------------------------------------------------------------------------- /3.4/3.4_step13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | /* 9 | Ваш тип должен предусматривать, что на печати он будет выглядеть так: 10 | [ XXXX]: где пробелы - "опустошенная" емкость батареи, а X - "заряженная". 11 | 12 | Во-вторых, на стандартный ввод вы получаете строку, состоящую ровно из 10 цифр: 13 | 0 или 1 (порядок 0/1 случайный). Ваша задача считать эту строку любым возможным 14 | способом и создать на основе этой строки объект объявленного вами на первом этапе 15 | типа: надеюсь, вы понимаете, что строка символизирует емкость батарейки: 0 - это 16 | "опустошенная" часть, а 1 - "заряженная". 17 | 18 | В-третьих, созданный вами объект должен называться batteryForTest (использование 19 | этого имени обязательно). 20 | 21 | В вашем распоряжении фактически весь файл, НО завершающая фигурная скобка функции 22 | main() вам не видна, но она присутствует. Перед этой скобкой присутствует функция 23 | (которая вам тоже не видна), принимающая в качестве аргумента объект типа 24 | fmt.Stringer - batteryForTest, и направляющая его на стандартный вывод, 25 | поэтому вам не требуется выводить что-то на печать самостоятельно. 26 | Удачи! 27 | 28 | Sample Input: 29 | 1000010011 30 | 31 | Sample Output: 32 | [ XXXX] 33 | */ 34 | 35 | type Battery struct { 36 | capacity int 37 | } 38 | 39 | func NewBattery(value string) Battery { 40 | return Battery{ 41 | capacity: strings.Count(value, "1"), 42 | } 43 | } 44 | 45 | func (b Battery) String() string { 46 | return fmt.Sprintf("[%10s]", strings.Repeat("X", b.capacity)) 47 | } 48 | 49 | func main() { 50 | fmt.Println(NewBattery("1000010011")) 51 | // [ XXXX] 52 | 53 | var value string 54 | _, err := fmt.Scan(&value) 55 | if err != nil { 56 | panic(err) 57 | } 58 | 59 | batteryForTest := NewBattery(value) 60 | fmt.Println(batteryForTest) 61 | } 62 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step14__job_calculator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Вам необходимо написать функцию calculator следующего вида: 9 | func calculator(arguments <-chan int, done <-chan struct{}) <-chan int 10 | 11 | В качестве аргумента эта функция получает два канала только для чтения, возвращает 12 | канал только для чтения. 13 | 14 | Через канал arguments функция получит ряд чисел, а через канал done - сигнал о 15 | необходимости завершить работу. Когда сигнал о завершении работы будет получен, 16 | функция должна в выходной (возвращенный) канал отправить сумму полученных чисел. 17 | 18 | Функция calculator должна быть неблокирующей, сразу возвращая управление. 19 | 20 | Выходной канал должен быть закрыт после выполнения всех оговоренных условий, если вы 21 | этого не сделаете, то превысите предельное время работы. 22 | */ 23 | 24 | func main() { 25 | fmt.Println("Started!") 26 | 27 | calculator := func(arguments <-chan int, done <-chan struct{}) <-chan int { 28 | result := make(chan int) 29 | 30 | go func() { 31 | defer close(result) 32 | 33 | var sum int 34 | 35 | for { 36 | select { 37 | case value := <-arguments: 38 | sum += value 39 | case <-done: 40 | result <- sum 41 | return 42 | } 43 | } 44 | }() 45 | 46 | return result 47 | } 48 | 49 | arguments := make(chan int) 50 | done := make(chan struct{}) 51 | 52 | go func() { 53 | // NOTE: для повторного использования канала лучше не закрывать канал, а отправить в него 54 | // done <- struct{}{} 55 | //defer close(done) 56 | 57 | for i := 1; i < 10; i++ { 58 | arguments <- i 59 | } 60 | 61 | done <- struct{}{} 62 | }() 63 | fmt.Println("Result:", <-calculator(arguments, done)) 64 | // Result: 45 65 | 66 | go func() { 67 | for i := 1; i < 5; i++ { 68 | arguments <- i 69 | } 70 | done <- struct{}{} 71 | }() 72 | fmt.Println("Result:", <-calculator(arguments, done)) 73 | // Result: 10 74 | 75 | fmt.Println("Finish!") 76 | } 77 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | // Duration 10 | { 11 | now := time.Now() 12 | post := now.AddDate(0, 0, -1) 13 | future := now.AddDate(0, 0, 1) 14 | 15 | var d time.Duration 16 | 17 | // func Since(t Time) Duration 18 | // вычисляет период между текущим моментом и заданным временем в прошлом 19 | d = time.Since(post) 20 | fmt.Println(d, d.Seconds(), d.Round(time.Second), d.Round(time.Second).Seconds(), d.Round(time.Second).Hours()) 21 | // 24h0m0.0080068s 86400.0080068 24h0m0s 86400 24 22 | 23 | // func Until(t Time) Duration 24 | // вычисляет период между текущим моментом и заданным временем в будущем 25 | d = time.Until(future) 26 | fmt.Println(d, d.Seconds(), d.Round(time.Second), d.Round(time.Second).Seconds(), d.Round(time.Second).Hours()) 27 | // 23h59m59.9919935s 86399.9919935 24h0m0s 86400 24 28 | 29 | // func ParseDuration(s string) (Duration, error) 30 | // преобразует строку в Duration с использованием аннотаций: 31 | // "ns" - наносекунды, 32 | // "us" - микросекунды, 33 | // "ms" - миллисекунды, 34 | // "s" - секунды, 35 | // "m" - минуты, 36 | // "h" - часы. 37 | dur, err := time.ParseDuration("1h12m3s") 38 | if err != nil { 39 | panic(err) 40 | } 41 | fmt.Println(dur, dur.Round(time.Hour), dur.Round(time.Hour).Hours()) 42 | // 1h12m3s 1h0m0s 1 43 | 44 | fmt.Println() 45 | } 46 | 47 | { 48 | fmt.Println(time.Hour) // 1h0m0s 49 | fmt.Println(time.Minute) // 1m0s 50 | fmt.Println(time.Second) // 1s 51 | fmt.Println(time.Millisecond) // 1ms 52 | fmt.Println(time.Microsecond) // 1µs 53 | fmt.Println(time.Nanosecond) // 1ns 54 | 55 | fmt.Println() 56 | 57 | d := time.Hour*3 + time.Minute*4 + time.Second*5 58 | fmt.Println(d, d.Hours(), d.Minutes(), d.Seconds(), d.Milliseconds()) 59 | // 3h4m5s 3.0680555555555555 184.08333333333334 11045 11045000 60 | 61 | fmt.Println(d, d.Round(time.Hour), d.Round(time.Minute), d.Round(time.Second), d.Round(time.Millisecond)) 62 | // 3h4m5s 3h0m0s 3h4m0s 3h4m5s 3h4m5s 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /3.5/3.5_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | func main() { 12 | // ReadFile | WriteFile 13 | { 14 | const fileName = "test.txt" 15 | var err error 16 | var dataFromFile []byte 17 | 18 | _ = os.Remove(fileName) 19 | 20 | dataFromFile, err = ioutil.ReadFile(fileName) 21 | if err != nil { 22 | fmt.Println(err) 23 | } 24 | fmt.Printf("dataFromFile (%d): %s\n", len(dataFromFile), dataFromFile) 25 | // open test.txt: The system cannot find the file specified. 26 | // dataFromFile: [] 27 | 28 | fmt.Println() 29 | 30 | dataForFile := []byte("Тестовая строка, предназначенная для записи в файл") 31 | 32 | // Создаем новый файл и записываем в него данные dataForFile 33 | if err := ioutil.WriteFile(fileName, dataForFile, 0600); err != nil { 34 | fmt.Println(err) 35 | } 36 | dataFromFile, err = ioutil.ReadFile(fileName) 37 | if err != nil { 38 | fmt.Println(err) 39 | } 40 | fmt.Printf("dataFromFile (%d): %s\n", len(dataFromFile), dataFromFile) 41 | // dataFromFile: Тестовая строка, предназначенная для записи в файл 42 | 43 | // Сравниваем исходные данные с записанными в файл и прочитанными из него 44 | fmt.Printf("dataForFile == dataFromFile: %v\n", bytes.Equal(dataFromFile, dataForFile)) 45 | 46 | _ = os.Remove(fileName) 47 | 48 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 49 | } 50 | 51 | // ReadDir 52 | { 53 | var filesFromDir []os.FileInfo 54 | var err error 55 | 56 | filesFromDir, err = ioutil.ReadDir(".") 57 | if err != nil { 58 | fmt.Println(err) 59 | } 60 | 61 | // Print directories 62 | for _, file := range filesFromDir { 63 | if file.IsDir() { 64 | fmt.Printf("Directory: %s\n", file.Name()) 65 | } 66 | } 67 | 68 | fmt.Println() 69 | 70 | filesFromDir, err = ioutil.ReadDir("1.10") 71 | if err != nil { 72 | fmt.Println(err) 73 | } 74 | 75 | // Print files 76 | for _, file := range filesFromDir { 77 | if !file.IsDir() { 78 | fmt.Printf("name: %s, size: %d\n", file.Name(), file.Size()) 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /3.2/3.2_step9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | { 10 | foo := "10" 11 | bar := "15" 12 | barInt, err := strconv.Atoi(bar) 13 | if err != nil { 14 | panic(err) 15 | } 16 | fooInt, err := strconv.Atoi(foo) 17 | if err != nil { 18 | panic(err) 19 | } 20 | baz := barInt - fooInt 21 | fmt.Println(baz) // 5 22 | 23 | fmt.Println() 24 | } 25 | 26 | { 27 | s := "323str" 28 | result, err := strconv.Atoi(s) 29 | if err != nil { 30 | fmt.Println(err) // strconv.Atoi: parsing "323str": invalid syntax 31 | } else { 32 | fmt.Println(result) 33 | } 34 | 35 | fmt.Println() 36 | } 37 | 38 | { 39 | s := "23.23456" 40 | // как и в прошлом шаге, здесь 2 параметр - bitSize 41 | // bitSize - 32 или 64 (32 для float32, 64 для float64) 42 | // но нужно понимать что метод все равно вернет float64 43 | result, err := strconv.ParseFloat(s, 64) 44 | if err != nil { 45 | panic(err) 46 | } 47 | fmt.Println(result) // 23.23456 48 | fmt.Printf("%T \n", result) // float64 49 | 50 | // Конкретный пример для разных bitSize: 51 | s = "1.0000000012345678" 52 | // не будем обрабатывать ошибки в примерах, но на практике так не делайте ;) 53 | result32, _ := strconv.ParseFloat(s, 32) 54 | result64, _ := strconv.ParseFloat(s, 64) 55 | fmt.Println("bitSize32:", result32) // вывод 1 (не уместились) 56 | fmt.Println("bitSize64:", result64) // вывод 1.0000000012345678 57 | 58 | fmt.Println() 59 | } 60 | 61 | { 62 | s := "-12345" 63 | res, err := strconv.ParseInt(s, 10, 64) 64 | if err != nil { // не забываем проверить ошибку 65 | panic(err) 66 | } 67 | fmt.Println(res) // -12345 68 | 69 | s = "12345" 70 | res2, err := strconv.ParseUint(s, 10, 64) 71 | if err != nil { // не забываем проверить ошибку 72 | panic(err) 73 | } 74 | fmt.Println(res2) // 12345 75 | 76 | fmt.Println() 77 | } 78 | 79 | { 80 | s := "true" 81 | res, err := strconv.ParseBool(s) 82 | if err != nil { // не забываем проверить ошибку 83 | panic(err) 84 | } 85 | fmt.Println(res) // true 86 | fmt.Printf("%T", res) // bool 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /3.2/3.2_step8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | // Itoa 10 | { 11 | text := strconv.Itoa(2020) // int -> string 12 | fmt.Printf("%T %v\n", text, text) // string 2020 13 | 14 | fmt.Println() 15 | } 16 | 17 | // FormatInt 18 | { 19 | var n int64 = 0xB // 'B' в шестнадцатеричной это 11 в десятичной системе 20 | fmt.Println(strconv.FormatInt(n, 2)) // 1011 21 | fmt.Println(strconv.FormatInt(n, 10)) // 11 22 | fmt.Println(strconv.FormatInt(n, 16)) // b 23 | 24 | fmt.Println() 25 | } 26 | 27 | // FormatUint 28 | { 29 | var n uint64 = 93101 30 | res := strconv.FormatUint(n, 10) 31 | fmt.Printf("%T %v\n", res, res) // string 93101 32 | 33 | fmt.Println() 34 | } 35 | 36 | // FormatFloat 37 | { 38 | var a float64 = 1.0123456789 39 | 40 | // 1 параметр - число для конвертации 41 | // fmt - форматирование 42 | // prec - точность (кол-во знаков после запятой) 43 | // bitSize - 32 или 64 (32 для float32, 64 для float64) 44 | fmt.Println(strconv.FormatFloat(a, 'f', 2, 64)) // 1.01 45 | 46 | // если мы хотим учесть все цифры после запятой, то можем в prec передать -1 47 | fmt.Println(strconv.FormatFloat(a, 'f', -1, 64)) // 1.0123456789 48 | 49 | // Возможные форматы fmt: 50 | // 'f' (-ddd.dddd, no exponent), 51 | // 'b' (-ddddp±ddd, a binary exponent), 52 | // 'e' (-d.dddde±dd, a decimal exponent), 53 | // 'E' (-d.ddddE±dd, a decimal exponent), 54 | // 'g' ('e' for large exponents, 'f' otherwise), 55 | // 'G' ('E' for large exponents, 'f' otherwise), 56 | // 'x' (-0xd.ddddp±ddd, a hexadecimal fraction and binary exponent), or 57 | // 'X' (-0Xd.ddddP±ddd, a hexadecimal fraction and binary exponent). 58 | var b float64 = 2222 * 1023 * 245 * 2 * 52 59 | fmt.Println(strconv.FormatFloat(b, 'e', -1, 64)) // 5.791874088e+10 60 | 61 | fmt.Println() 62 | } 63 | 64 | // Sprint and Sprintf 65 | { 66 | fmt.Println(fmt.Sprint(20.19)) // Краткая форма 67 | 68 | a := 20.20 69 | fmt.Println(fmt.Sprintf("%f", a)) // Полная форма 70 | 71 | fmt.Println() 72 | } 73 | 74 | // FormatBool 75 | { 76 | a := true 77 | res := strconv.FormatBool(a) 78 | fmt.Printf("%T %v", res, res) // string true 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /3.5/3.5_step13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "archive/zip" 5 | "encoding/csv" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "os" 10 | ) 11 | 12 | /* 13 | Поиск файла в заданном формате и его обработка 14 | Данная задача поможет вам разобраться в пакете encoding/csv и path/filepath, хотя для решения 15 | может быть использован также пакет archive/zip (поскольку файл с заданием предоставляется 16 | именно в этом формате). 17 | 18 | В тестовом архиве, который мы можете скачать из нашего репозитория на github.com, содержится 19 | набор папок и файлов. Один из этих файлов является файлом с данными в формате CSV, прочие же 20 | файлы структурированных данных не содержат. 21 | 22 | Требуется найти и прочитать этот единственный файл со структурированными данными (это таблица 23 | 10х10, разделителем является запятая), а в качестве ответа необходимо указать число, находящееся 24 | на 5 строке и 3 позиции (индексы 4 и 2 соответственно). 25 | */ 26 | 27 | // Exists reports whether the named file or directory exists. 28 | func Exists(name string) bool { 29 | if _, err := os.Stat(name); err != nil { 30 | if os.IsNotExist(err) { 31 | return false 32 | } 33 | } 34 | return true 35 | } 36 | 37 | func download(fileName, url string) *os.File { 38 | f, err := os.Create(fileName) 39 | if err != nil { 40 | panic(err) 41 | } 42 | defer f.Close() 43 | 44 | rs, err := http.Get(url) 45 | if err != nil { 46 | panic(err) 47 | } 48 | defer rs.Body.Close() 49 | 50 | _, err = io.Copy(f, rs.Body) 51 | if err != nil { 52 | panic(err) 53 | } 54 | 55 | return f 56 | } 57 | 58 | func main() { 59 | const URL = "https://github.com/semyon-dev/stepik-go/raw/master/work_with_files/task_csv_1/task.zip" 60 | const FileName = "task_step13.zip" 61 | 62 | ok := Exists(FileName) 63 | if !ok { 64 | fmt.Printf("Download from %v\n", URL) 65 | download(FileName, URL) 66 | } 67 | 68 | zf, err := zip.OpenReader(FileName) 69 | if err != nil { 70 | panic(err) 71 | } 72 | defer zf.Close() 73 | 74 | for _, file := range zf.File { 75 | f, err := file.Open() 76 | if err != nil { 77 | continue 78 | } 79 | defer f.Close() 80 | 81 | lines, _ := csv.NewReader(f).ReadAll() 82 | if len(lines) > 1 { 83 | fmt.Println(lines[4][2]) 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step13__job_calculator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Вам необходимо написать функцию calculator следующего вида: 9 | func calculator(firstChan <-chan int, secondChan <-chan int, stopChan <-chan struct{}) <-chan int 10 | 11 | Функция получает в качестве аргументов 3 канала, и возвращает канал типа <-chan int. 12 | * в случае, если аргумент будет получен из канала firstChan, в выходной (возвращенный) канал 13 | вы должны отправить квадрат аргумента. 14 | * в случае, если аргумент будет получен из канала secondChan, в выходной (возвращенный) канал 15 | вы должны отправить результат умножения аргумента на 3. 16 | * в случае, если аргумент будет получен из канала stopChan, нужно просто завершить работу функции. 17 | 18 | Функция calculator должна быть неблокирующей, сразу возвращая управление. Ваша функция получит 19 | всего одно значение в один из каналов - получили значение, обработали его, завершили работу. 20 | 21 | После завершения работы необходимо освободить ресурсы, закрыв выходной канал, если вы этого 22 | не сделаете, то превысите предельное время работы. 23 | */ 24 | 25 | func main() { 26 | fmt.Println("Started!") 27 | 28 | calculator := func(firstChan <-chan int, secondChan <-chan int, stopChan <-chan struct{}) <-chan int { 29 | result := make(chan int) 30 | 31 | go func() { 32 | defer close(result) 33 | 34 | select { 35 | case value := <-firstChan: 36 | result <- value * value 37 | case value := <-secondChan: 38 | result <- value * 3 39 | case <-stopChan: 40 | return 41 | } 42 | }() 43 | 44 | return result 45 | } 46 | 47 | firstChan := make(chan int) 48 | secondChan := make(chan int) 49 | stopChan := make(chan struct{}) 50 | 51 | go func() { 52 | // NOTE: для повторного использования канала лучше не закрывать канал, а отправить в него 53 | // done <- struct{}{} 54 | defer close(stopChan) 55 | 56 | firstChan <- 10 57 | firstChan <- 100 58 | secondChan <- 10 59 | }() 60 | 61 | for i := 0; i < 4; i++ { 62 | fmt.Println("Result:", <-calculator(firstChan, secondChan, stopChan)) 63 | } 64 | // Result: 100 65 | // Result: 10000 66 | // Result: 30 67 | // Result: 0 68 | 69 | fmt.Println("Finish!") 70 | } 71 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step8__NewTimer__Ticker.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("Started!") 11 | 12 | { 13 | t := time.NewTimer(time.Second) // создаем новый таймер, который сработает через 1 секунду 14 | go func() { 15 | <-t.C // C - канал, который должен вернуть значение через заданное время 16 | }() 17 | t.Stop() // но мы можем остановить таймер и раньше установленного времени 18 | 19 | t.Reset(time.Second * 2) // пока таймер не сработал, мы можем сбросить его, установив новый срок выполнения 20 | <-t.C 21 | fmt.Println("Прошло 2 секунды") 22 | fmt.Println() 23 | } 24 | 25 | { 26 | work := func() <-chan struct{} { 27 | done := make(chan struct{}) // канал для синхронизации горутин 28 | 29 | go func() { 30 | defer close(done) // синхронизирующий канал будет закрыт, когда функция завершит свою работу 31 | 32 | stop := time.NewTimer(time.Second) 33 | tick := time.NewTicker(time.Millisecond * 200) 34 | defer tick.Stop() // освободим ресурсы, при завершении работы функции 35 | 36 | for { 37 | select { 38 | case <-stop.C: 39 | // stop - Timer, который через 1 секунду даст сигнал завершить работу 40 | return 41 | case <-tick.C: 42 | // tick - Ticker, посылающий сигнал выполнить работу каждый 200 миллисекунд 43 | fmt.Println("Тик-так") 44 | } 45 | } 46 | }() 47 | 48 | return done 49 | } 50 | <-work() 51 | 52 | // Тик-так 53 | // Тик-так 54 | // Тик-так 55 | // Тик-так 56 | // Тик-так 57 | fmt.Println() 58 | } 59 | 60 | { 61 | worker := func(id int, limit <-chan time.Time, wg *sync.WaitGroup) { 62 | defer wg.Done() 63 | <-limit 64 | fmt.Printf("Worker %d выполнил работу\n", id) 65 | } 66 | 67 | tick := time.NewTicker(time.Second) 68 | defer tick.Stop() 69 | 70 | wg := new(sync.WaitGroup) 71 | 72 | for i := 1; i <= 5; i++ { 73 | wg.Add(1) 74 | go worker(i, tick.C, wg) 75 | } 76 | 77 | wg.Wait() 78 | 79 | // Worker 1 выполнил работу 80 | // Worker 3 выполнил работу 81 | // Worker 4 выполнил работу 82 | // Worker 5 выполнил работу 83 | // Worker 2 выполнил работу 84 | } 85 | 86 | fmt.Println("Finish!") 87 | } 88 | -------------------------------------------------------------------------------- /3.2/3.2_step14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | /* 12 | Для решения данной задачи вам понадобится пакет strconv, возможно использовать 13 | пакеты strings или encoding/csv, или даже bufio - вы не ограничены в выборе 14 | способа решения задачи. В решениях мы поделимся своими способами решения 15 | этой задачи, предлагаем вам сделать то же самое. 16 | 17 | В привычных нам редакторах электронных таблиц присутствует удобное представление 18 | числа с разделителем разрядов в виде пробела, кроме того в России целая часть от 19 | дробной отделяется запятой. Набор таких чисел был экспортирован в формат CSV, где 20 | в качестве разделителя используется символ ";". 21 | 22 | На стандартный ввод вы получаете 2 таких вещественных числа, в качестве результата 23 | требуется вывести частное от деления первого числа на второе с точностью до четырех 24 | знаков после "запятой" (на самом деле после точки, результат не требуется приводить 25 | к исходному формату). 26 | 27 | P.S. небольшое отступление, связанное с чтением из стандартного ввода. Кто-то захочет 28 | использовать для этого пакет bufio.Reader. Это вполне допустимый вариант, но если вы 29 | резонно обрабатываете ошибку метода ReadString('\n'), то получаете ошибку EOF, а 30 | точнее (io.EOF - End Of File). На самом деле это не ошибка, а состояние, означающее, 31 | что файл (а os.Stdin является файлом) прочитан до конца. Чтобы ошибка была обработана 32 | правильно, вы можете поступить так: 33 | if err != nil && err != io.EOF { 34 | ... 35 | } 36 | 37 | Sample Input: 38 | 1 149,6088607594936;1 179,0666666666666 39 | 40 | Sample Output: 41 | 0.9750 42 | */ 43 | 44 | func main() { 45 | text, _ := bufio.NewReader(os.Stdin).ReadString('\n') 46 | text = strings.Trim(text, "\n") 47 | 48 | text = strings.Replace(text, " ", "", -1) 49 | text = strings.Replace(text, ",", ".", -1) 50 | 51 | items := strings.Split(text, ";") 52 | if len(items) != 2 { 53 | panic("invalid format, must be two numbers!") 54 | } 55 | 56 | num1, err := strconv.ParseFloat(items[0], 64) 57 | if err != nil { 58 | panic(err) 59 | } 60 | 61 | num2, err := strconv.ParseFloat(items[1], 64) 62 | if err != nil { 63 | panic(err) 64 | } 65 | 66 | fmt.Printf("%.4f\n", num1/num2) 67 | } 68 | -------------------------------------------------------------------------------- /3.1/3.1_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | /* 6 | В ходе анализа результатов переписи населения информация была сохранена в 7 | объекте типа map: 8 | groupCity := map[int][]string{ 9 | 10: []string{...}, // города с населением 10-99 тыс. человек 10 | 100: []string{...}, // города с населением 100-999 тыс. человек 11 | 1000: []string{...}, // города с населением 1000 тыс. человек и более 12 | } 13 | 14 | При подготовке важного отчета о городах с населением 100-999 тыс. человек был 15 | подготовлен другой объект типа map: 16 | cityPopulation := map[string]int{ 17 | город: население города в тысячах человек, 18 | } 19 | 20 | Однако база данных с информацией о точной численности населения содержала ошибки, 21 | поэтому в cityPopulation в т.ч. была сохранена информация о городах, которые входят 22 | в другие группы из groupCity. 23 | 24 | Ваша программа имеет доступ к обоим указанным отображениям, требуется исправить 25 | cityPopulation, чтобы в ней была сохранена информация только о городах из 26 | группы groupCity[100]. 27 | 28 | Функция main() уже объявлена, доступ к отображениям осуществляется по 29 | указанным именам. По результатам выполнения ничего больше делать не требуется, 30 | проверка будет осуществлена автоматически. 31 | */ 32 | 33 | func main() { 34 | /* 35 | * Группировка городов по численности населения в тысячах человек 36 | * от 10 до 100, от 100 до 1000 и более 1000: 37 | * groupCity map[int][]string{ 38 | * 10: []string{...}, 39 | * 100: []string{...}, 40 | * 1000: []string{...}, 41 | * } 42 | * 43 | * Население городов в тысячах человек: 44 | * cityPopulation map[string]int{...} 45 | */ 46 | 47 | groupCity := map[int][]string{ 48 | 10: {"A_10", "B_10", "C_10"}, 49 | 100: {"A_100", "B_100", "C_100"}, 50 | 1000: {"A_1000", "B_1000", "C_1000"}, 51 | } 52 | fmt.Println(groupCity) 53 | 54 | cityPopulation := map[string]int{ 55 | "A_10": 10, "B_10": 15, "C_10": 20, 56 | "A_100": 100, "B_100": 200, "C_100": 400, 57 | "A_1000": 1001, "B_1000": 2000, "C_1000": 3000, 58 | } 59 | 60 | for number, cities := range groupCity { 61 | if number == 100 { 62 | continue 63 | } 64 | 65 | for _, city := range cities { 66 | delete(cityPopulation, city) 67 | } 68 | } 69 | fmt.Println(cityPopulation) 70 | } 71 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step9__select_case.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | fmt.Println("Started!") 11 | 12 | // Пример ограничения времени жизни выполнения кода. Последовательное выполнение 13 | { 14 | c := make(chan int) 15 | go func() { 16 | for i := 0; i < 100; i++ { 17 | c <- i 18 | time.Sleep(time.Millisecond * 300) 19 | } 20 | }() 21 | 22 | timeout := time.After(2 * time.Second) 23 | 24 | LOOP: 25 | for { 26 | //for i := 0; i < 5; i++ { 27 | select { // Оператор select 28 | case gopherID := <-c: // Ждет, когда проснется гофер 29 | fmt.Println("gopher", gopherID, "has finished sleeping") 30 | 31 | case <-timeout: // Ждет окончания времени 32 | fmt.Println("my patience ran out") 33 | break LOOP 34 | //return // Сдается и возвращается 35 | } 36 | } 37 | 38 | fmt.Println() 39 | } 40 | 41 | // Еще пример ограничения времени жизни выполнения кода + рандом задержки. Параллельное выполнение 42 | { 43 | c := make(chan int) 44 | 45 | sleepyGopher := func(id int, c chan int) { 46 | time.Sleep(time.Duration(rand.Intn(4000)) * time.Millisecond) 47 | c <- id 48 | } 49 | 50 | for i := 0; i < 100; i++ { 51 | go sleepyGopher(i, c) 52 | } 53 | 54 | timeout := time.After(2 * time.Second) 55 | 56 | LOOP2: 57 | for { 58 | //for i := 0; i < 5; i++ { 59 | select { // Оператор select 60 | case gopherID := <-c: // Ждет, когда проснется гофер 61 | fmt.Println("gopher", gopherID, "has finished sleeping") 62 | 63 | case <-timeout: // Ждет окончания времени 64 | fmt.Println("my patience ran out") 65 | break LOOP2 66 | //return // Сдается и возвращается 67 | } 68 | } 69 | 70 | fmt.Println() 71 | } 72 | 73 | // select - case - default 74 | { 75 | tick1 := time.After(time.Second) 76 | tick2 := time.After(time.Second * 2) 77 | select { 78 | case <-tick1: 79 | fmt.Println("Получено значение из первого канала") 80 | case <-tick2: 81 | fmt.Println("Получено значение из второго канала") 82 | // Блок default выполнится раньше блока case - 1 секунда слишком много для Go 83 | default: 84 | fmt.Println("Действие по умолчанию") 85 | } 86 | // Действие по умолчанию 87 | } 88 | 89 | fmt.Println("Finish!") 90 | } 91 | -------------------------------------------------------------------------------- /3.5/3.5_step10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/csv" 6 | "fmt" 7 | "io" 8 | "io/ioutil" 9 | "strconv" 10 | ) 11 | 12 | func createCSVBuffer() *bytes.Buffer { 13 | // Записывать данные, а в дальнейшем читать их мы будем из буфера, 14 | // но его можно заменить любым другим объектом, удовлетворяющим 15 | // интерфейсу io.ReadWriter 16 | buf := bytes.NewBuffer(nil) 17 | 18 | w := csv.NewWriter(buf) 19 | 20 | for i := 1; i <= 3; i++ { 21 | // Запись данных может производится поэтапно, например в цикле 22 | val1 := fmt.Sprintf("row%d_col1", i) 23 | val2 := fmt.Sprintf("row%d_col2", i) 24 | val3 := fmt.Sprintf("row%d_col3", i) 25 | if err := w.Write([]string{val1, val2, val3}); err != nil { // Аргументом Write является срез строк 26 | panic(err) 27 | } 28 | } 29 | w.Flush() // Этот метод приведет к фактической записи данных из буфера csv.Writer в buf 30 | 31 | // Либо данные можно записать за один раз 32 | _ = w.WriteAll([][]string{ // Аргументом WriteAll является срез срезов строк 33 | {"row4_col1", "row4_col2", "row4_col3"}, 34 | {"row5_col1", "row5_col2", "row5_col3"}, 35 | }) 36 | 37 | return buf 38 | } 39 | 40 | func main() { 41 | { 42 | buf := createCSVBuffer() 43 | 44 | data, _ := ioutil.ReadAll(buf) 45 | fmt.Println(strconv.Quote(string(data))) 46 | fmt.Printf("%q\n", data) 47 | // "row1_col1,row1_col2,row1_col3\nrow2_col1,row2_col2,row2_col3\nrow3_col1,row3_col2,row3_col3\nrow4_col1,row4_col2,row4_col3\nrow5_col1,row5_col2,row5_col3\n" 48 | // "row1_col1,row1_col2,row1_col3\nrow2_col1,row2_col2,row2_col3\nrow3_col1,row3_col2,row3_col3\nrow4_col1,row4_col2,row4_col3\nrow5_col1,row5_col2,row5_col3\n" 49 | 50 | fmt.Println() 51 | } 52 | 53 | { 54 | buf := createCSVBuffer() 55 | r := csv.NewReader(buf) 56 | 57 | for i := 0; i < 2; i++ { 58 | // Читать данные мы тоже можем построчно, получая срез строк за каждую итерацию 59 | row, err := r.Read() 60 | if err != nil && err != io.EOF { // Здесь тоже нужно учитывать конец файла 61 | panic(err) 62 | } 63 | fmt.Println(row) 64 | } 65 | // [row1_col1 row1_col2 row1_col3] 66 | // [row2_col1 row2_col2 row2_col3] 67 | 68 | // Либо прочитать данные за один раз 69 | lines, err := r.ReadAll() 70 | if err != nil { 71 | // Когда мы читаем данные до конца файла io.EOF не возвращается, а служит сигналом к завершению чтения 72 | panic(err) 73 | } 74 | 75 | for _, row := range lines { 76 | fmt.Println(row) 77 | } 78 | // [row3_col1 row3_col2 row3_col3] 79 | // [row4_col1 row4_col2 row4_col3] 80 | // [row5_col1 row5_col2 row5_col3] 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /3.9__Goroutines_go_chan_PART2/3.9_step15__job_merge2Channels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | /* 9 | Необходимо написать функцию 10 | func merge2Channels(fn func(int) int, in1 <-chan int, in2 <- chan int, out chan<- int, n int). 11 | 12 | Описание ее работы: 13 | n раз сделать следующее 14 | * прочитать по одному числу из каждого из двух каналов in1 и in2, назовем их x1 и x2. 15 | * вычислить f(x1) + f(x2) 16 | * записать полученное значение в out 17 | 18 | Функция merge2Channels должна быть неблокирующей, сразу возвращая управление. 19 | 20 | Функция fn может работать долгое время, ожидая чего-либо или производя вычисления. 21 | 22 | Формат ввода: 23 | * количество итераций передается через аргумент n. 24 | * целые числа подаются через аргументы-каналы in1 и in2. 25 | * функция для обработки чисел перед сложением передается через аргумент fn. 26 | 27 | Формат вывода: 28 | * канал для вывода результатов передается через аргумент out. 29 | */ 30 | 31 | // SOURCE: https://habr.com/ru/company/ozontech/blog/507932/ 32 | func merge2Channels(f func(int) int, in1 <-chan int, in2 <-chan int, out chan<- int, n int) { 33 | idx := make(chan int) // Для передачи индекса 34 | val := make(chan int) // Для передачи значения 35 | 36 | go func() { 37 | for i := 0; i < n; i++ { 38 | x1 := <-in1 39 | x2 := <-in2 40 | 41 | done := make(chan int) 42 | go func() { 43 | done <- f(x1) 44 | }() 45 | go func() { 46 | done <- f(x2) 47 | }() 48 | 49 | go func(i int) { 50 | idx <- i 51 | val <- (<-done) + (<-done) 52 | }(i) 53 | } 54 | }() 55 | 56 | go func() { 57 | m := make(map[int]int) 58 | for i := 0; i < n; i++ { 59 | m[<-idx] = <-val 60 | } 61 | 62 | // Для возврата значений по порядку 63 | for i := 0; i < n; i++ { 64 | out <- m[i] 65 | } 66 | }() 67 | } 68 | 69 | func main() { 70 | fmt.Println("Started!") 71 | 72 | start := time.Now() 73 | 74 | fn := func(x int) int { 75 | time.Sleep(time.Second * 2) 76 | return x 77 | } 78 | 79 | in1 := make(chan int) 80 | in2 := make(chan int) 81 | out := make(chan int) 82 | n := 5 83 | 84 | go func() { 85 | for i := 0; i < n; i++ { 86 | fmt.Println("Send", i) 87 | go func() { 88 | in1 <- 1 89 | in2 <- 2 90 | }() 91 | } 92 | }() 93 | 94 | merge2Channels(fn, in1, in2, out, n) 95 | 96 | for i := 0; i < n; i++ { 97 | value := <-out 98 | fmt.Println("Result:", value) 99 | } 100 | 101 | fmt.Println("Elapsed:", time.Since(start)) 102 | fmt.Println("Finish!") 103 | } 104 | -------------------------------------------------------------------------------- /3.6__JSON/3.6_step3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | ) 8 | 9 | func main() { 10 | type myStruct struct { 11 | Name string 12 | Age int 13 | Status bool 14 | Values []int 15 | } 16 | s := myStruct{ 17 | Name: "John Connor", 18 | Age: 35, 19 | Status: true, 20 | Values: []int{15, 11, 37}, 21 | } 22 | 23 | // json.Marshal 24 | { 25 | // Функция Marshal принимает аргумент типа interface{} (в нашем случае это структура) 26 | // и возвращает байтовый срез с данными, кодированными в формат JSON. 27 | data, err := json.Marshal(s) 28 | if err != nil { 29 | panic(err) 30 | } 31 | 32 | fmt.Printf("%s\n", data) 33 | // {"Name":"John Connor","Age":35,"Status":true,"Values":[15,11,37]} 34 | 35 | fmt.Println() 36 | } 37 | 38 | // json.MarshalIndent 39 | { 40 | // MarshalIndent похож на Marshal, но применяет отступ (indent) для форматирования вывода. 41 | // Каждый элемент JSON в выходных данных начинается с новой строки, начинающейся с 42 | // префикса (prefix), за которым следует один или несколько отступов в соответствии с вложенностью: 43 | data, err := json.MarshalIndent(s, "", " ") 44 | if err != nil { 45 | panic(err) 46 | } 47 | 48 | fmt.Printf("%s\n", data) 49 | // { 50 | // "Name": "John Connor", 51 | // "Age": 35, 52 | // "Status": true, 53 | // "Values": [ 54 | // 15, 55 | // 11, 56 | // 37 57 | // ] 58 | // } 59 | 60 | fmt.Println() 61 | } 62 | 63 | // json.Unmarshal 64 | { 65 | var s myStruct 66 | 67 | data := []byte(`{"Name":"John Connor","Age":35,"Status":true,"Values":[15,11,37]}`) 68 | if err := json.Unmarshal(data, &s); err != nil { 69 | panic(err) 70 | } 71 | fmt.Printf("%v\n", s) 72 | // {John Connor 35 true [15 11 37]} 73 | 74 | data = []byte(` 75 | { 76 | "Name": "John Connor", 77 | "Age": 35, 78 | "Status": true, 79 | "Values": [ 80 | 15, 81 | 11, 82 | 37 83 | ] 84 | } 85 | `) 86 | if err := json.Unmarshal(data, &s); err != nil { 87 | panic(err) 88 | } 89 | fmt.Printf("%v\n", s) 90 | // {John Connor 35 true [15 11 37]} 91 | 92 | fmt.Println() 93 | } 94 | 95 | // json.Valid 96 | { 97 | data, _ := json.Marshal(s) 98 | data = bytes.Trim(data, "{") // испортим json удалив '{' 99 | 100 | // функция json.Valid возвращает bool, true - если json правильный 101 | if !json.Valid(data) { 102 | fmt.Printf("invalid json: %s\n", data) 103 | } 104 | // invalid json: "Name":"John Connor","Age":35,"Status":true,"Values":[15,11,37]} 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /3.5/3.5_step4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "strings" 8 | ) 9 | 10 | func removeFile(f *os.File) (err error) { 11 | _ = f.Close() 12 | 13 | err = os.Remove(f.Name()) 14 | if err != nil { 15 | return err 16 | } 17 | 18 | return nil 19 | } 20 | 21 | func main() { 22 | // os.Create | os.Remove -- with Close 23 | { 24 | f, err := os.Create("fileName.txt") 25 | if err != nil { 26 | fmt.Println(err) 27 | } 28 | f.Close() 29 | 30 | err = os.Remove(f.Name()) 31 | fmt.Println(err) 32 | // 33 | 34 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 35 | } 36 | 37 | // os.Create | os.Remove -- without Close 38 | { 39 | f, err := os.Create("fileName.txt") 40 | // f.Close() 41 | 42 | err = os.Remove(f.Name()) 43 | fmt.Println(err) 44 | // remove fileName.txt: The process cannot access the file because it is being used by another process. 45 | 46 | _ = removeFile(f) 47 | 48 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 49 | } 50 | 51 | // os.Create | os.Rename | os.Remove 52 | { 53 | // Создание файла 54 | f, _ := os.Create("text.txt") 55 | f.Close() 56 | 57 | // Переименование файла 58 | os.Rename("text.txt", "new_text.txt") 59 | 60 | // Удаление файла 61 | os.Remove("new_text.txt") 62 | 63 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 64 | } 65 | 66 | // os.Create | WriteString | ioutil.ReadFile | strconv.Quote 67 | { 68 | f, _ := os.Create("text.txt") 69 | f.WriteString("1 строка\n") 70 | f.WriteString("2 строка\n") 71 | f.Close() 72 | 73 | data, _ := ioutil.ReadFile(f.Name()) 74 | text := string(data) 75 | fmt.Printf("text (%d): %q\n", len(text), text) 76 | // data (30): "1 строка\n2 строка\n" 77 | 78 | removeFile(f) 79 | 80 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 81 | } 82 | 83 | // os.Create | Stat 84 | { 85 | f, _ := os.Create("text.txt") 86 | f.WriteString("1234") 87 | info, _ := f.Stat() 88 | 89 | fmt.Printf( 90 | "name: %v, size: %v, mode: %v, modTime: %v, sys: %v\n", 91 | info.Name(), info.Size(), info.Mode(), info.ModTime(), info.Sys(), 92 | ) 93 | // name: text.txt, size: 4, mode: -rw-rw-rw-, modTime: 2020-10-24 18:35:04.5977649 +0500 +05, sys: &{32 {2065564442 30845450} {2065574449 30845450} {2065574449 30845450} 0 4} 94 | 95 | removeFile(f) 96 | 97 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 98 | } 99 | 100 | // os.Exit 101 | { 102 | const fileName = "fileName.txt" 103 | os.Remove(fileName) 104 | 105 | f, _ := os.Create(fileName) 106 | defer removeFile(f) 107 | 108 | fmt.Println("Before os.Exit") 109 | os.Exit(0) 110 | fmt.Println("After os.Exit") 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | // Методы, возвращающие отдельные элементы структуры 10 | // Таких методов довольно много и в целом они не должны вызвать никаких проблем, для 11 | // большей части этих методов мы сделаем короткие примеры: 12 | { 13 | current := time.Date(2020, time.May, 15, 17, 45, 12, 0, time.Local) 14 | 15 | // func (t Time) Date() (year int, month Month, day int) 16 | fmt.Println(current.Date()) // 2020 May 15 17 | 18 | // func (t Time) Year() int 19 | fmt.Println(current.Year()) // 2020 20 | 21 | // func (t Time) Month() Month 22 | fmt.Println(current.Month()) // May 23 | 24 | // func (t Time) Day() int 25 | fmt.Println(current.Day()) // 15 26 | 27 | // func (t Time) Clock() (hour, min, sec int) 28 | fmt.Println(current.Clock()) // 17 45 12 29 | 30 | // func (t Time) Hour() int 31 | fmt.Println(current.Hour()) //17 32 | 33 | // func (t Time) Minute() int 34 | fmt.Println(current.Minute()) // 45 35 | 36 | // func (t Time) Second() int 37 | fmt.Println(current.Second()) // 12 38 | 39 | // func (t Time) Unix() int64 40 | fmt.Println(current.Unix()) // 1589546712 41 | 42 | // func (t Time) Weekday() Weekday 43 | fmt.Println(current.Weekday()) // Friday 44 | 45 | // func (t Time) YearDay() int 46 | fmt.Println(current.YearDay()) // 136 47 | 48 | fmt.Println() 49 | } 50 | 51 | // Конвертирование структуры Time в строку 52 | { 53 | // func (t Time) Format(layout string) string 54 | current := time.Date(2020, time.May, 15, 17, 45, 12, 0, time.Local) 55 | fmt.Println(current.Format("02-01-2006 15:04:05")) // 15-05-2020 17:45:12 56 | 57 | fmt.Println() 58 | } 59 | 60 | // Сравнение структур Time 61 | { 62 | firstTime := time.Date(2020, time.May, 15, 17, 45, 12, 0, time.Local) 63 | secondTime := time.Date(2020, time.May, 15, 16, 45, 12, 0, time.Local) 64 | 65 | // func (t Time) After(u Time) bool 66 | // true если позже 67 | fmt.Println(firstTime.After(secondTime)) // true 68 | 69 | // func (t Time) Before(u Time) bool 70 | // true если раньше 71 | fmt.Println(firstTime.Before(secondTime)) // false 72 | 73 | // func (t Time) Equal(u Time) bool 74 | // true если равны 75 | fmt.Println(firstTime.Equal(secondTime)) // false 76 | 77 | fmt.Println() 78 | } 79 | 80 | // Методы, изменяющие структуру Time 81 | { 82 | now := time.Date(2020, time.May, 15, 17, 45, 12, 0, time.Local) 83 | 84 | // func (t Time) Add(d Duration) Time 85 | // изменяет дату в соответствии с параметром - "продолжительностью" 86 | future := now.Add(time.Hour * 12) // перемещаемся на 12 часов вперед 87 | 88 | // func (t Time) AddDate(years int, months int, days int) Time 89 | // изменяет дату в соответствии с параметрами - количеством лет, месяцев и дней 90 | past := now.AddDate(-1, -2, -3) // перемещаемся на 1 год, два месяца и 3 дня назад 91 | 92 | // func (t Time) Sub(u Time) Duration 93 | // вычисляет время, прошедшее между двумя датами 94 | fmt.Println(future.Sub(past)) // 10332h0m0s 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /3.5/3.5_step7.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | func createTestFile(autoClose bool) *os.File { 13 | f, err := os.Create("test.txt") 14 | if err != nil { 15 | panic(err) 16 | } 17 | _, _ = f.WriteString("123456\nabc\nFOOBAR") 18 | 19 | if autoClose { 20 | defer f.Close() 21 | } 22 | 23 | return f 24 | } 25 | 26 | func main() { 27 | // bufio.Reader - позволяет читать данные по байтам, рунам, строкам и пр., указывать символ, 28 | // на котором необходимо прекратить чтение. Когда данные будут прочитаны до конца, метод вернет 29 | // ошибку io.EOF. 30 | { 31 | f := createTestFile(true) 32 | 33 | f, err := os.Open(f.Name()) 34 | if err != nil { 35 | panic(err) 36 | } 37 | defer func() { 38 | f.Close() 39 | os.Remove(f.Name()) 40 | }() 41 | 42 | rd := bufio.NewReader(f) 43 | 44 | buf := make([]byte, 5) 45 | n, err := rd.Read(buf) // читаем в buf 10 байт из ранее открытого файла 46 | if err != nil && err != io.EOF { 47 | // io.EOF не совсем ошибка - это состояние, указывающее, что файл прочитан до конца 48 | panic(err) 49 | } 50 | fmt.Printf("Прочитано %d байт: %q\n", n, buf) 51 | // Прочитано 5 байт: "12345" 52 | 53 | s, err := rd.ReadString('\n') // читаем данные до разрыва абзаца ('\n') 54 | fmt.Printf("Text (%v): %q EOF=%v\n", len(s), s, err == io.EOF) 55 | // Text (2): "6\n" EOF=false 56 | 57 | s, err = rd.ReadString('\n') 58 | fmt.Printf("Text (%v): %q EOF=%v\n", len(s), s, err == io.EOF) 59 | // Text (4): "abc\n" EOF=false 60 | 61 | s, err = rd.ReadString('\n') 62 | fmt.Printf("Text (%v): %q EOF=%v\n", len(s), s, err == io.EOF) 63 | // Text (6): "FOOBAR" EOF=true 64 | 65 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 66 | } 67 | 68 | // bufio.Writer - создан для записи в объекты, удовлетворяющие интерфейсу io.Writer, 69 | // но предоставляет ряд более высокоуровневых методов, в частности метод WriteString(s string) 70 | { 71 | f, err := os.Create("test.txt") 72 | if err != nil { 73 | panic(err) 74 | } 75 | defer func() { 76 | f.Close() 77 | os.Remove(f.Name()) 78 | }() 79 | 80 | w := bufio.NewWriter(f) 81 | n, err := w.WriteString("Запишем строку") 82 | if err != nil { 83 | panic(err) 84 | } 85 | fmt.Printf("Записано %d байт\n", n) 86 | // Записано 27 байт 87 | 88 | data, _ := ioutil.ReadFile(f.Name()) 89 | text := string(data) 90 | fmt.Printf("Text (%v): %q\n", len(text), text) 91 | // Text (0): "" 92 | 93 | // bufio.Writer имеет собственный буфер, чтобы быть уверенным, что данные точно записаны, 94 | // вызываем метод Flush() 95 | w.Flush() 96 | 97 | data, _ = ioutil.ReadFile(f.Name()) 98 | text = string(data) 99 | fmt.Printf("Text (%v): %q\n", len(text), text) 100 | // Text (27): "Запишем строку" 101 | 102 | fmt.Println("\n" + strings.Repeat("-", 100) + "\n") 103 | } 104 | 105 | // bufio.Scanner - создан для построчного чтения данных. 106 | { 107 | f := createTestFile(false) 108 | 109 | f, err := os.Open(f.Name()) 110 | if err != nil { 111 | panic(err) 112 | } 113 | defer func() { 114 | f.Close() 115 | os.Remove(f.Name()) 116 | }() 117 | 118 | s := bufio.NewScanner(f) 119 | 120 | // Возвращает true, пока файл не будет прочитан до конца 121 | for s.Scan() { 122 | // s.Text() содержит данные, считанные на данной итерации 123 | line := s.Text() 124 | fmt.Printf("Line (%v) %q\n", len(line), line) 125 | } 126 | // Line (6) "123456" 127 | // Line (3) "abc" 128 | // Line (6) "FOOBAR" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /3.4/3.4_step10.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | /* 9 | Пришло время для задач, где вы сможете применить полученные знания на практике. 10 | 11 | Обязательные условия выполнения: данные со стандартного ввода читаются функцией readTask(), 12 | которая возвращает 3 значения типа пустой интерфейс. Эта функция использует пакеты 13 | encoding/json, fmt, и os - не удаляйте их из импорта. Скорее всего, вам понадобится 14 | пакет "fmt", но вы можете использовать любой другой пакет для записи в стандартный вывод 15 | не удаляя fmt. 16 | 17 | И так, вы получаете 3 значения типа пустой интерфейс: если все удачно, то первые 2 значения 18 | будут float64. Третье значение в идеальном случае будет строкой, которая может иметь 19 | значения: "+", "-", "*", "/" (определенная математическая операция). Но такие идеальные 20 | случаи будут не всегда, вы можете получить значения других типов, а также строка в третьем 21 | значении может не относится к одной из указанных математических операций. 22 | 23 | Результат выполнения программы должен быть таков: 24 | 1. в штатной ситуации вы должны напечатать в стандартный вывод результат выполнения 25 | математической операции с точностью до 4 цифры после запятой (fmt.Printf(%.4f)); 26 | 2. если первое или второе значение не является типом float64, вы должны напечатать 27 | сообщение об ошибке вида: value=полученное_значение: тип_значения 28 | (например: value=true: bool) 29 | 3. если третье значение имеет неверный тип или передан знак, не относящийся к указанным 30 | выше математическим операциям, сообщение об ошибке должно иметь вид: неизвестная операция 31 | 32 | Гарантируется, что ошибка в аргументах может быть только одна, поэтому если вы при проверке 33 | первого значения увидели, что оно содержит ошибку - печатайте сообщение об ошибке и 34 | завершайте работу программы, проверка остальных аргументов значения уже не имеет, а 35 | проверяющая система воспримет 2 сообщения об ошибке как нарушение условия выполнения задания. 36 | 37 | Удачи! 38 | */ 39 | 40 | func getValue(value interface{}) (float64, error) { 41 | if v, ok := value.(float64); ok { 42 | return v, nil 43 | } 44 | return 0, errors.New(fmt.Sprintf("value=%v: %T", value, value)) 45 | } 46 | 47 | func getOperation(operation interface{}) (fn func(a float64, b float64) float64, err error) { 48 | v, ok := operation.(string) 49 | if !ok { 50 | return nil, errors.New(fmt.Sprintf("invalid type '%T', must be string", operation)) 51 | } 52 | 53 | switch v { 54 | case "+": 55 | fn = func(a float64, b float64) float64 { 56 | return a + b 57 | } 58 | case "-": 59 | fn = func(a float64, b float64) float64 { 60 | return a - b 61 | } 62 | case "*": 63 | fn = func(a float64, b float64) float64 { 64 | return a * b 65 | } 66 | case "/": 67 | fn = func(a float64, b float64) float64 { 68 | return a / b 69 | } 70 | default: 71 | err = errors.New("неизвестная операция") 72 | } 73 | 74 | return 75 | } 76 | 77 | func readTask() (interface{}, interface{}, interface{}) { 78 | return 5.4, 2.0, "+" 79 | } 80 | 81 | func main() { 82 | defer func() { 83 | if e := recover(); e != nil { 84 | fmt.Println(e) 85 | } 86 | }() 87 | 88 | value1, value2, operation := readTask() 89 | 90 | var num1, num2 float64 91 | var err error 92 | var fnOper func(a float64, b float64) float64 93 | 94 | num1, err = getValue(value1) 95 | if err != nil { 96 | panic(err) 97 | } 98 | 99 | num2, err = getValue(value2) 100 | if err != nil { 101 | panic(err) 102 | } 103 | 104 | fnOper, err = getOperation(operation) 105 | if err != nil { 106 | panic(err) 107 | } 108 | 109 | fmt.Printf("%.4f\n", fnOper(num1, num2)) 110 | } 111 | -------------------------------------------------------------------------------- /3.7__Time/3.7_step1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | // stdLongMonth = "January" 10 | // stdMonth = "Jan" 11 | // stdNumMonth = "1" 12 | // stdZeroMonth = "01" 13 | // stdLongWeekDay = "Monday" 14 | // stdWeekDay = "Mon" 15 | // stdDay = "2" 16 | // stdUnderDay = "_2" 17 | // stdZeroDay = "02" 18 | // stdHour = "15" 19 | // stdHour12 = "3" 20 | // stdZeroHour12 = "03" 21 | // stdMinute = "4" 22 | // stdZeroMinute = "04" 23 | // stdSecond = "5" 24 | // stdZeroSecond = "05" 25 | // stdLongYear = "2006" 26 | // stdYear = "06" 27 | // stdPM = "PM" 28 | // stdpm = "pm" 29 | // stdTZ = "MST" 30 | // stdISO8601TZ = "Z0700" // prints Z for UTC 31 | // stdISO8601ColonTZ = "Z07:00" // prints Z for UTC 32 | // stdNumTZ = "-0700" // always numeric 33 | // stdNumShortTZ = "-07" // always numeric 34 | // stdNumColonTZ = "-07:00" // always numeric 35 | 36 | // time.Now | time.Date | time.Unix | Format 37 | { 38 | // func Now() Time 39 | // возвращает текущую дату и время 40 | now := time.Now() 41 | 42 | // func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time 43 | // возвращает дату и время в соответствии с заданными параметрами: годом, месяцем, днем, временем и пр. 44 | currentTime := time.Date( 45 | 2020, // год 46 | time.May, // месяц 47 | 15, // день 48 | 10, // часы 49 | 13, // минуты 50 | 12, // секунды 51 | 45, // наносекунды 52 | time.UTC, // временная зона 53 | ) 54 | 55 | // func Unix(sec int64, nsec int64) Time 56 | // возвращает дату и время в соответствии с заданными параметрами: секундами и наносекундами, прошедшими с начала эпохи Unix — 01.01.1970 г. 57 | // https://ru.wikipedia.org/wiki/Unix-%D0%B2%D1%80%D0%B5%D0%BC%D1%8F 58 | unixTime := time.Unix( 59 | 150000, // секунды 60 | 1, // наносекунды 61 | ) 62 | 63 | fmt.Println(now.Format("02-01-2006 15:04:05")) // 27-10-2020 10:58:52 64 | fmt.Println(currentTime.Format("02-01-2006 15:04:05")) // 15-05-2020 10:13:12 65 | fmt.Println(unixTime.Format("02-01-2006 15:04:05")) // 02-01-1970 22:40:00 66 | 67 | fmt.Println() 68 | } 69 | 70 | // time.Parse | time.LoadLocation | time.ParseInLocation | Format 71 | { 72 | // func Parse(layout, value string) (Time, error) 73 | // парсит дату и время в строковом представлении 74 | firstTime, err := time.Parse("2006/01/02 15-04", "2020/05/15 17-45") 75 | if err != nil { 76 | panic(err) 77 | } 78 | 79 | // LoadLocation находит временную зону в справочнике IANA 80 | // https://www.iana.org/time-zones 81 | loc, err := time.LoadLocation("Asia/Yekaterinburg") 82 | if err != nil { 83 | panic(err) 84 | } 85 | 86 | // func ParseInLocation(layout, value string, loc *Location) (Time, error) 87 | // парсит дату и время в строковом представлении с отдельным указанием временной зоны 88 | secondTime, err := time.ParseInLocation("Jan 2 06 03:04:05pm", "May 15 20 05:45:00pm", loc) 89 | if err != nil { 90 | panic(err) 91 | } 92 | 93 | fmt.Println(firstTime, "|", secondTime) 94 | fmt.Println(firstTime.UTC(), "|", secondTime.UTC()) 95 | // 2020-05-15 17:45:00 +0000 UTC | 2020-05-15 17:45:00 +0500 +05 96 | // 2020-05-15 17:45:00 +0000 UTC | 2020-05-15 12:45:00 +0000 UTC 97 | 98 | const dateLayout = "02-01-2006 15:04:05" 99 | fmt.Println( 100 | firstTime.Format(dateLayout), 101 | "|", 102 | secondTime.Format(dateLayout), 103 | ) 104 | fmt.Println( 105 | firstTime.UTC().Format(dateLayout), 106 | "|", 107 | secondTime.UTC().Format(dateLayout), 108 | ) 109 | // 15-05-2020 17:45:00 | 15-05-2020 17:45:00 110 | // 15-05-2020 17:45:00 | 15-05-2020 12:45:00 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /3.6__JSON/3.6_step6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | /* 9 | На стандартный ввод подаются данные о студентах университетской группы в формате JSON: 10 | { 11 | "ID":134, 12 | "Number":"ИЛМ-1274", 13 | "Year":2, 14 | "Students":[ 15 | { 16 | "LastName":"Вещий", 17 | "FirstName":"Лифон", 18 | "MiddleName":"Вениаминович", 19 | "Birthday":"4апреля1970года", 20 | "Address":"632432,г.Тобольск,ул.Киевская,дом6,квартира23", 21 | "Phone":"+7(948)709-47-24", 22 | "Rating":[1,2,3] 23 | }, 24 | { 25 | // ... 26 | } 27 | ] 28 | } 29 | 30 | В сведениях о каждом студенте содержится информация о полученных им оценках (Rating). 31 | Требуется прочитать данные, и рассчитать среднее количество оценок, полученное студентами группы. 32 | Ответ на задачу требуется записать на стандартный вывод в формате JSON в следующей форме: 33 | { 34 | "Average": 14.1 35 | } 36 | 37 | Как вы понимаете, для декодирования используется функция Unmarshal, а для кодирования 38 | MarshalIndent (префикс - пустая строка, отступ - 4 пробела). 39 | 40 | Если у вас возникли проблемы с чтением / записью данных, то этот комментарий для вас: в уроках об 41 | интерфейсах и работе с файлами мы рассказывали, что стандартный ввод / вывод - это файлы, к которым 42 | можно обратиться через os.Stdin и os.Stdout соответственно, они удовлетворяют интерфейсам 43 | io.Reader и io.Writer, из них можно читать, в них можно писать. 44 | 45 | Один из способов чтения, использовать ioutil.ReadAll: 46 | data, err := ioutil.ReadAll(os.Stdin) 47 | if err != nil { 48 | // ... 49 | } 50 | 51 | // data - тип []byte 52 | 53 | Задачу можно выполнить и другими способами, в частности использовать bufio. Буквально в следующем 54 | шаге (через один, на самом деле) будет рассказано о еще одном способе чтения / записи, можете 55 | забежать немного вперед, а затем вернуться к задаче. 56 | */ 57 | 58 | type Student struct { 59 | LastName string 60 | FirstName string 61 | MiddleName string 62 | Birthday string 63 | Address string 64 | Phone string 65 | Rating []int 66 | } 67 | 68 | type Group struct { 69 | ID int 70 | Number string 71 | Year int 72 | Students []Student 73 | } 74 | 75 | type Result struct { 76 | Average float64 77 | } 78 | 79 | func main() { 80 | var group Group 81 | 82 | //if err := json.NewDecoder(os.Stdin).Decode(&group); err != nil { 83 | // panic(err) 84 | //} 85 | // 86 | // OR: 87 | // 88 | //data, err := ioutil.ReadAll(os.Stdin) 89 | //if err != nil { 90 | // panic(err) 91 | //} 92 | 93 | data := []byte(` 94 | { 95 | "ID":134, 96 | "Number":"ИЛМ-1274", 97 | "Year":2, 98 | "Students":[ 99 | { 100 | "LastName":"Вещий", 101 | "FirstName":"Лифон", 102 | "MiddleName":"Вениаминович", 103 | "Birthday":"4апреля1970года", 104 | "Address":"632432,г.Тобольск,ул.Киевская,дом6,квартира23", 105 | "Phone":"+7(948)709-47-24", 106 | "Rating":[1,2,3] 107 | }, 108 | { 109 | "LastName":"Вещий", 110 | "FirstName":"Лифон", 111 | "MiddleName":"Вениаминович", 112 | "Birthday":"4апреля1970года", 113 | "Address":"632432,г.Тобольск,ул.Киевская,дом6,квартира23", 114 | "Phone":"+7(948)709-47-24", 115 | "Rating":[4,2,4] 116 | } 117 | ] 118 | } 119 | `) 120 | //fmt.Println(string(data)) 121 | 122 | if err := json.Unmarshal(data, &group); err != nil { 123 | panic(err) 124 | } 125 | 126 | var numberRating int 127 | for _, student := range group.Students { 128 | numberRating += len(student.Rating) 129 | } 130 | 131 | result := Result{ 132 | Average: float64(numberRating) / float64(len(group.Students)), 133 | } 134 | dataJson, err := json.MarshalIndent(result, "", " ") 135 | if err != nil { 136 | panic(err) 137 | } 138 | 139 | fmt.Println(string(dataJson)) 140 | } 141 | --------------------------------------------------------------------------------