├── .gitignore ├── 1-single-file ├── README.md └── main.go ├── 2-multi-file ├── README.md ├── calorie_calculator.go ├── input_parser.go └── main.go ├── 3-packages ├── README.md ├── calculator │ └── calories_by_elf_list.go ├── input_parser.go └── main.go ├── 4-hexagonal-architecture ├── README.md ├── dao │ ├── input_parser.go │ └── input_parser_test.go ├── domain │ ├── calories.go │ ├── elf.go │ ├── elves_list.go │ └── elves_list_test.go └── main.go ├── LICENSE ├── README.md ├── go.mod ├── go.sum └── puzzle_input /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /1-single-file/README.md: -------------------------------------------------------------------------------- 1 | # Single-file structure 2 | 3 | Aka all your code is in one file called `main.go`. 🙂 4 | 5 | This structure is great for: 6 | - beginners who don't want to worry about how to split their code into files or packages just yet 7 | - super simple projects/apps which don't require more than a single file 8 | 9 | I cannot stress enough that this structure is **absolutely fine** for simple or quick scripts which don't need to be perfect! 10 | Most of my Advent of Code answers for example, or at least the first few "easy" days all tend to get solved in a single file. 11 | Don't feel like you always have to have multiple files or packages. Go's premise is to keep things as simple as possible but no simpler, so don't add complexity for no reason! -------------------------------------------------------------------------------- /1-single-file/main.go: -------------------------------------------------------------------------------- 1 | package single_file // change this to package main to be able to run main() 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | func main() { 11 | list, err := os.ReadFile("./puzzle_input") 12 | if err != nil { 13 | panic(err) 14 | } 15 | 16 | input := parseInput(string(list)) 17 | 18 | elf, calories := findMostCalories(input) 19 | 20 | fmt.Printf("Elf %d carries %d calories\n", elf, calories) 21 | } 22 | 23 | func parseInput(raw string) map[int]int { 24 | input := map[int]int{} 25 | 26 | lines := strings.Split(raw, "\n") 27 | elfIndex := 0 28 | calorieCount := 0 29 | 30 | for _, l := range lines { 31 | if len(l) == 0 { 32 | input[elfIndex] = calorieCount 33 | calorieCount = 0 34 | elfIndex++ 35 | continue 36 | } 37 | 38 | c, err := strconv.Atoi(l) 39 | if err != nil { 40 | panic("can't parse the calories!") 41 | } 42 | calorieCount += c 43 | } 44 | 45 | input[elfIndex] = calorieCount 46 | 47 | return input 48 | } 49 | 50 | func findMostCalories(input map[int]int) (int, int) { 51 | elf := 0 52 | mostCalories := 0 53 | 54 | for k, v := range input { 55 | if v > mostCalories { 56 | mostCalories = v 57 | elf = k 58 | } 59 | } 60 | 61 | return elf + 1, mostCalories 62 | } 63 | -------------------------------------------------------------------------------- /2-multi-file/README.md: -------------------------------------------------------------------------------- 1 | # Multi-file structure 2 | 3 | Aka your start to group related code into separate files. The structure of your project remains flat otherwise - all files live next to each other in a single top-level directory. 🙂 4 | 5 | This structure is great for: 6 | - beginners who are just starting to figure out how to group related functionality together 7 | - simple projects/apps which don't require more than a few files 8 | 9 | Note that there's no right or wrong here - I could have just one file called `calorie_calculator.go` which would also contain the input parsing function, or I can have two files as in the example. Whatever works for your use case and helps you organise your code best (while keeping things simple)! -------------------------------------------------------------------------------- /2-multi-file/calorie_calculator.go: -------------------------------------------------------------------------------- 1 | package multi_file // change this to package main to be able to run main() 2 | 3 | func findMostCalories(input caloriesByElfList) (elf, calories) { 4 | elfNo := elf(0) 5 | mostCalories := calories(0) 6 | 7 | for k, v := range input { 8 | if v > mostCalories { 9 | mostCalories = v 10 | elfNo = k 11 | } 12 | } 13 | 14 | return elfNo + 1, mostCalories 15 | } 16 | -------------------------------------------------------------------------------- /2-multi-file/input_parser.go: -------------------------------------------------------------------------------- 1 | package multi_file // change this to package main to be able to run main() 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func parseInput(raw string) caloriesByElfList { 9 | input := caloriesByElfList{} 10 | 11 | lines := strings.Split(raw, "\n") 12 | elfIndex := 0 13 | calorieCount := 0 14 | 15 | for _, l := range lines { 16 | if len(l) == 0 { 17 | input[elf(elfIndex)] = calories(calorieCount) 18 | calorieCount = 0 19 | elfIndex++ 20 | continue 21 | } 22 | 23 | c, err := strconv.Atoi(l) 24 | if err != nil { 25 | panic("can't parse the calories!") 26 | } 27 | calorieCount += c 28 | } 29 | 30 | input[elf(elfIndex)] = calories(calorieCount) 31 | 32 | return input 33 | } 34 | -------------------------------------------------------------------------------- /2-multi-file/main.go: -------------------------------------------------------------------------------- 1 | package multi_file // change this to package main to be able to run main() 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | // Here we've added some custom types to help the functions in different files "communicate" their intent better. 9 | // You could of course use the plain types (int, map) instead, but now that the functions live in different files 10 | // it might be easier to remember what all the return values are by using custom types. 11 | type ( 12 | elf int 13 | calories int 14 | caloriesByElfList map[elf]calories 15 | ) 16 | 17 | func main() { 18 | list, err := os.ReadFile("./puzzle_input") 19 | if err != nil { 20 | panic(err) 21 | } 22 | 23 | input := parseInput(string(list)) 24 | 25 | e, c := findMostCalories(input) 26 | 27 | fmt.Printf("Elf %d carries %d calories\n", e, c) 28 | } 29 | -------------------------------------------------------------------------------- /3-packages/README.md: -------------------------------------------------------------------------------- 1 | # Package structure 2 | 3 | If the file(s) containing your grouped code are really large, or you've considered breaking one large file into a few smaller ones all still related to the same group of code, then it might be time to introduce packages to your structure. 🙂 4 | 5 | Packages are exactly that - a way to group all code related to one well-defined functionality into a single directory. 6 | You can have as many files as you need in a single package, but having the directories is a nice way to visually group related files together. It also allows you to control what is and isn't visible to the rest of your code within each package. 7 | 8 | This structure is great for: 9 | - beginners who are starting to use packages (without having a specific application structure pattern in mind) 10 | - simple projects/apps which benefit from having packages to improve their readability and understandability 11 | -------------------------------------------------------------------------------- /3-packages/calculator/calories_by_elf_list.go: -------------------------------------------------------------------------------- 1 | package calculator 2 | 3 | // Declaring a few exported types here makes it easier for the rest of the code to interact with our package. 4 | // These types add meaning to the generic types which can make the code more understandable. 5 | // You could of course use the plain int or map types instead! 6 | 7 | type ( 8 | Elf int 9 | Calories int 10 | CaloriesByElfList map[Elf]Calories 11 | ) 12 | 13 | // FindMostCalories takes the list of calories carried by each elf, 14 | // and returns the elf which carries the most calories and the amount of calories they carry. 15 | func FindMostCalories(input CaloriesByElfList) (Elf, Calories) { 16 | elfNo := Elf(0) 17 | mostCalories := Calories(0) 18 | 19 | for k, v := range input { 20 | if v > mostCalories { 21 | mostCalories = v 22 | elfNo = k 23 | } 24 | } 25 | 26 | return elfNo + 1, mostCalories 27 | } 28 | -------------------------------------------------------------------------------- /3-packages/input_parser.go: -------------------------------------------------------------------------------- 1 | package packages // change this to package main to be able to run main() 2 | 3 | import ( 4 | "github.com/katzien/app-structure-examples/3-packages/calculator" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | func parseInput(raw string) calculator.CaloriesByElfList { 10 | input := calculator.CaloriesByElfList{} 11 | 12 | lines := strings.Split(raw, "\n") 13 | elfIndex := 0 14 | calorieCount := 0 15 | 16 | for _, l := range lines { 17 | if len(l) == 0 { 18 | input[calculator.Elf(elfIndex)] = calculator.Calories(calorieCount) 19 | calorieCount = 0 20 | elfIndex++ 21 | continue 22 | } 23 | 24 | c, err := strconv.Atoi(l) 25 | if err != nil { 26 | panic("can't parse the calories!") 27 | } 28 | calorieCount += c 29 | } 30 | 31 | input[calculator.Elf(elfIndex)] = calculator.Calories(calorieCount) 32 | 33 | return input 34 | } 35 | -------------------------------------------------------------------------------- /3-packages/main.go: -------------------------------------------------------------------------------- 1 | package packages // change this to package main to be able to run main() 2 | 3 | import ( 4 | "fmt" 5 | "github.com/katzien/app-structure-examples/3-packages/calculator" 6 | "os" 7 | ) 8 | 9 | func main() { 10 | list, err := os.ReadFile("./puzzle_input") 11 | if err != nil { 12 | panic(err) 13 | } 14 | 15 | input := parseInput(string(list)) 16 | 17 | e, c := calculator.FindMostCalories(input) 18 | 19 | fmt.Printf("Elf %d carries %d calories\n", e, c) 20 | } 21 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/README.md: -------------------------------------------------------------------------------- 1 | # Hexagonal architecture 2 | 3 | We arrive at one of the well-known ways of grouping functionality together - Hexagonal Architecture, also known as Ports & Adapters or the onion architecture. 🙂 4 | 5 | This is my favourite way of structuring Go apps, especially when coupled with a microservice architecture. 6 | I find that it scales well to problems of different sizes and complexity, and you can add or remove as many layers as you need: 7 | 8 | ``` 9 | ├── main.go 10 | ├── dao 11 | ├── domain 12 | └── handler 13 | ``` 14 | 15 | You can also combine many smaller hex structures to form your entire program: 16 | 17 | (imagine an app which compiles a restaurant menu by pulling information from three completely different sources) 18 | 19 | ``` 20 | ├── main.go 21 | ├── beer 22 | │ ├── dao 23 | │ ├── domain 24 | │ ├── handler 25 | │ └── service.go 26 | ├── wine 27 | │ ├── dao 28 | │ ├── domain 29 | │ ├── handler 30 | │ └── service.go 31 | └── food 32 | ├── dao 33 | ├── domain 34 | ├── handler 35 | └── service.go 36 | ``` 37 | 38 | This structure is great for: 39 | - complex projects which require a well-defined structure to stay maintainable and understandable 40 | - applications which have dependencies such as databases, user interfaces or third party APIs 41 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/dao/input_parser.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "github.com/katzien/app-structure-examples/4-hexagonal-architecture/domain" 5 | "log" 6 | "os" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | func ParsePuzzleInputFile() ([]domain.Elf, error) { 12 | bytes, err := os.ReadFile("./puzzle_input") 13 | if err != nil { 14 | return nil, err 15 | } 16 | 17 | return parseRawInput(string(bytes)) 18 | } 19 | 20 | func parseRawInput(r string) ([]domain.Elf, error) { 21 | lines := strings.Split(r, "\n") 22 | elfIndex := 1 23 | calorieCount := 0 24 | 25 | list := []domain.Elf{} 26 | for _, l := range lines { 27 | if len(l) == 0 { 28 | e := domain.Elf{ 29 | Name: elfIndex, 30 | Load: domain.Calories(calorieCount), 31 | } 32 | list = append(list, e) 33 | 34 | calorieCount = 0 35 | elfIndex++ 36 | continue 37 | } 38 | 39 | c, err := strconv.Atoi(l) 40 | if err != nil { 41 | log.Printf("can't parse this calories line: %v", l) 42 | return nil, err 43 | } 44 | calorieCount += c 45 | } 46 | 47 | list = append(list, domain.Elf{ 48 | Name: elfIndex, 49 | Load: domain.Calories(calorieCount), 50 | }) 51 | 52 | return list, nil 53 | } 54 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/dao/input_parser_test.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "github.com/katzien/app-structure-examples/4-hexagonal-architecture/domain" 5 | "github.com/stretchr/testify/require" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestParseInput(t *testing.T) { 12 | t.Parallel() 13 | 14 | input := `1000 15 | 2000 16 | 3000 17 | 18 | 4000 19 | 20 | 5000 21 | 6000 22 | 23 | 7000 24 | 8000 25 | 9000 26 | 27 | 10000` 28 | 29 | list, err := parseRawInput(input) 30 | require.NoError(t, err) 31 | 32 | assert.Len(t, list, 5) 33 | assert.Equal(t, domain.Elf{Name: 1, Load: domain.Calories(6000)}, list[0]) 34 | assert.Equal(t, domain.Elf{Name: 2, Load: domain.Calories(4000)}, list[1]) 35 | assert.Equal(t, domain.Elf{Name: 3, Load: domain.Calories(11000)}, list[2]) 36 | assert.Equal(t, domain.Elf{Name: 4, Load: domain.Calories(24000)}, list[3]) 37 | assert.Equal(t, domain.Elf{Name: 5, Load: domain.Calories(10000)}, list[4]) 38 | } 39 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/domain/calories.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | import "fmt" 4 | 5 | type Calories int 6 | 7 | func (c Calories) String() string { 8 | return fmt.Sprintf("%d kcal", c) 9 | } 10 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/domain/elf.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | type Elf struct { 4 | Name int 5 | Load Calories 6 | } 7 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/domain/elves_list.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | // FindMostCalories takes a list of all elves with their calories 4 | // and returns the elf which carries the most calories. 5 | func FindMostCalories(list []Elf) Elf { 6 | var elf Elf 7 | mostCalories := Calories(0) 8 | 9 | for _, e := range list { 10 | if e.Load > mostCalories { 11 | mostCalories = e.Load 12 | elf = e 13 | } 14 | } 15 | 16 | return elf 17 | } 18 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/domain/elves_list_test.go: -------------------------------------------------------------------------------- 1 | package domain 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestFindMostCalories(t *testing.T) { 9 | t.Parallel() 10 | 11 | input := []Elf{ 12 | {Name: 0, Load: Calories(6000)}, 13 | {Name: 1, Load: Calories(4000)}, 14 | {Name: 2, Load: Calories(11000)}, 15 | {Name: 3, Load: Calories(24000)}, 16 | {Name: 4, Load: Calories(10000)}, 17 | } 18 | 19 | elf := FindMostCalories(input) 20 | assert.Equal(t, 3, elf.Name) 21 | assert.Equal(t, Calories(24000), elf.Load) 22 | } 23 | -------------------------------------------------------------------------------- /4-hexagonal-architecture/main.go: -------------------------------------------------------------------------------- 1 | package main // change this to package main to be able to run main() 2 | 3 | import ( 4 | "fmt" 5 | "github.com/katzien/app-structure-examples/4-hexagonal-architecture/dao" 6 | "github.com/katzien/app-structure-examples/4-hexagonal-architecture/domain" 7 | ) 8 | 9 | func main() { 10 | list, err := dao.ParsePuzzleInputFile() 11 | if err != nil { 12 | panic(err) 13 | } 14 | 15 | elf := domain.FindMostCalories(list) 16 | 17 | fmt.Printf("Elf %d carries %s.\n", elf.Name, elf.Load.String()) 18 | } 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Kat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # All examples implement a solution to the Advent of Code 2022 Day 1 puzzle. 2 | 3 | Here's the puzzle description (copied from [Advent of Code 2022](https://adventofcode.com/2022/day/1)): 4 | 5 | -- 6 | 7 | The jungle must be too overgrown and difficult to navigate in vehicles or access from the air; the Elves' expedition traditionally goes on foot. As your boats approach land, the Elves begin taking inventory of their supplies. One important consideration is food - in particular, the number of Calories each Elf is carrying (your puzzle input). 8 | 9 | The Elves take turns writing down the number of Calories contained by the various meals, snacks, rations, etc. that they've brought with them, one item per line. Each Elf separates their own inventory from the previous Elf's inventory (if any) by a blank line. 10 | 11 | For example, suppose the Elves finish writing their items' Calories and end up with the following list: 12 | 13 | ``` 14 | 1000 15 | 2000 16 | 3000 17 | 18 | 4000 19 | 20 | 5000 21 | 6000 22 | 23 | 7000 24 | 8000 25 | 9000 26 | 27 | 10000 28 | ``` 29 | 30 | This list represents the Calories of the food carried by five Elves: 31 | 32 | - The first Elf is carrying food with 1000, 2000, and 3000 Calories, a total of 6000 Calories. 33 | - The second Elf is carrying one food item with 4000 Calories. 34 | - The third Elf is carrying food with 5000 and 6000 Calories, a total of 11000 Calories. 35 | - The fourth Elf is carrying food with 7000, 8000, and 9000 Calories, a total of 24000 Calories. 36 | - The fifth Elf is carrying one food item with 10000 Calories. 37 | 38 | In case the Elves get hungry and need extra snacks, they need to know which Elf to ask: they'd like to know how many Calories are being carried by the Elf carrying the most Calories. In the example above, this is 24000 (carried by the fourth Elf). 39 | 40 | Find the Elf carrying the most Calories. How many total Calories is that Elf carrying? 41 | 42 | # FAQ 43 | ### Where would you put your Kubernetes manifests / Dockerfiles / database migrations / non-Go files? 44 | I usually add them to the root directory of the project, or group them in a top-level directory. E.g. 45 | ``` 46 | ├── main.go 47 | ├── README.md 48 | ├── .gitignore 49 | ├── config (e.g. database migration or schema files) 50 | ├── consumer (if event-driven) 51 | ├── dao 52 | ├── domain 53 | ├── handler 54 | ├── manifests 55 | │ ... 56 | ``` 57 | 58 | ### Do you use internal/external packages to indicate what's safe to import in other projects? 59 | Not really. If anything I would only add an `external` directory to the root of my project for this purpose (everything else being internal by default). So not: 60 | ``` 61 | ├── main.go 62 | ├── internal 63 | │ ├── dao 64 | │ ├── domain 65 | │ ├── handler 66 | │ └── service.go 67 | ├── external 68 | │ └── types.go 69 | ``` 70 | 71 | But rather: 72 | ``` 73 | ├── main.go 74 | ├── dao 75 | ├── domain 76 | ├── handler 77 | └── service.go 78 | ├── external 79 | │ └── types.go 80 | ``` 81 | 82 | I just like to keep things simple, and stick to at most one level of indentation. You lose that if your internal/external packages contain subdirectories. 83 | 84 | I also don't really like the name `external`, because Go packages are typically "things" (not adjectives). 85 | 86 | At work we actually use a `proto` package for this purpose. We use protobuf for microservice to microservice communication, and have an explicit rule that services can import only proto packages of other services (enforced by static analysis). This achieves the intent behind internal/external, but conveys a bit more meaning - `proto` contains protobuf definitions and constants which other services can use to interact with that service. 87 | 88 | ### Do you use cmd / pkg directories? 89 | No, and this is something I used to advocate in my talks on structuring Go apps! 90 | 91 | I don't use these by default anymore. I realised they make the structure more complicated without bringing much benefit, unless I needed to have multiple main.go files. But that isn't the case for me most of the time, so I prefer to have my main.go file directly at the root of the project. 92 | 93 | Pkg adds another layer of indentation for the rest of the packages, and I prefer to have a flat structure as much as possible to keep things simple. It doesn't add much benefit unless you prefer to clearly separate your Go code from any other non-Go files or directories. I guess it might help if your project tree is huge, but I tend to use microservices so rarely run into this problem. ☺️ -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/katzien/app-structure-examples 2 | 3 | go 1.19 4 | 5 | require github.com/stretchr/testify v1.8.1 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.1 // indirect 9 | github.com/pmezard/go-difflib v1.0.0 // indirect 10 | gopkg.in/yaml.v3 v3.0.1 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 5 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 6 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 7 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 8 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 9 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 10 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 11 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 12 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 13 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 14 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 15 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 16 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 17 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 18 | -------------------------------------------------------------------------------- /puzzle_input: -------------------------------------------------------------------------------- 1 | 2832 2 | 2108 3 | 3082 4 | 4328 5 | 6843 6 | 5121 7 | 2869 8 | 1366 9 | 2358 10 | 1680 11 | 4980 12 | 1161 13 | 14 | 8026 15 | 2154 16 | 4242 17 | 1023 18 | 2744 19 | 3162 20 | 4093 21 | 1150 22 | 5397 23 | 2738 24 | 5657 25 | 26 | 10954 27 | 11208 28 | 8034 29 | 1636 30 | 9430 31 | 9421 32 | 5025 33 | 34 | 3837 35 | 5938 36 | 3967 37 | 2942 38 | 2727 39 | 3623 40 | 4070 41 | 1748 42 | 1795 43 | 1687 44 | 4023 45 | 6068 46 | 2558 47 | 2570 48 | 4214 49 | 50 | 9679 51 | 2986 52 | 5168 53 | 16463 54 | 55 | 5912 56 | 6008 57 | 1259 58 | 5378 59 | 10740 60 | 1642 61 | 2617 62 | 7821 63 | 64 | 3840 65 | 5265 66 | 2104 67 | 1510 68 | 5477 69 | 2636 70 | 5920 71 | 5939 72 | 5430 73 | 4482 74 | 5603 75 | 4915 76 | 5416 77 | 5897 78 | 79 | 3932 80 | 9344 81 | 7536 82 | 4925 83 | 10088 84 | 5253 85 | 5625 86 | 6800 87 | 88 | 3928 89 | 13714 90 | 18995 91 | 3569 92 | 93 | 2424 94 | 5188 95 | 11199 96 | 6078 97 | 11525 98 | 5155 99 | 3142 100 | 101 | 2595 102 | 5893 103 | 5590 104 | 6270 105 | 6095 106 | 5279 107 | 3726 108 | 6015 109 | 3985 110 | 5455 111 | 5190 112 | 4897 113 | 6632 114 | 115 | 5046 116 | 1424 117 | 3629 118 | 6204 119 | 6187 120 | 1149 121 | 4145 122 | 6953 123 | 2958 124 | 6312 125 | 1592 126 | 4614 127 | 2859 128 | 129 | 5750 130 | 9606 131 | 11706 132 | 2629 133 | 13635 134 | 5611 135 | 136 | 2162 137 | 6014 138 | 3168 139 | 8052 140 | 10781 141 | 3762 142 | 5653 143 | 144 | 21918 145 | 14739 146 | 147 | 2431 148 | 5955 149 | 4810 150 | 7476 151 | 2529 152 | 7985 153 | 6040 154 | 5864 155 | 3459 156 | 3347 157 | 4853 158 | 159 | 4695 160 | 3911 161 | 5590 162 | 4439 163 | 4874 164 | 2251 165 | 3967 166 | 6895 167 | 5801 168 | 2720 169 | 5125 170 | 5575 171 | 2057 172 | 173 | 5642 174 | 3714 175 | 5127 176 | 5083 177 | 2925 178 | 5048 179 | 6368 180 | 5883 181 | 2287 182 | 3276 183 | 3326 184 | 2207 185 | 3377 186 | 187 | 18373 188 | 7075 189 | 12254 190 | 18539 191 | 192 | 13758 193 | 19556 194 | 23565 195 | 196 | 6463 197 | 5076 198 | 5429 199 | 3105 200 | 6201 201 | 5959 202 | 6474 203 | 5740 204 | 6997 205 | 7567 206 | 1883 207 | 208 | 2316 209 | 10793 210 | 2985 211 | 10596 212 | 6910 213 | 11957 214 | 5984 215 | 216 | 18521 217 | 7234 218 | 7943 219 | 220 | 8774 221 | 7905 222 | 4375 223 | 1788 224 | 9244 225 | 2259 226 | 4842 227 | 6313 228 | 229 | 4496 230 | 10446 231 | 6917 232 | 1113 233 | 2509 234 | 1229 235 | 2999 236 | 237 | 2158 238 | 3221 239 | 1412 240 | 1484 241 | 1768 242 | 2621 243 | 1087 244 | 1152 245 | 3625 246 | 3767 247 | 4859 248 | 1220 249 | 3745 250 | 4374 251 | 3712 252 | 253 | 4072 254 | 8998 255 | 5778 256 | 4361 257 | 6138 258 | 259 | 11068 260 | 15488 261 | 17001 262 | 16349 263 | 264 | 3493 265 | 15148 266 | 14490 267 | 9502 268 | 11101 269 | 270 | 8952 271 | 2731 272 | 10734 273 | 7581 274 | 4799 275 | 9379 276 | 5405 277 | 10345 278 | 279 | 5008 280 | 4456 281 | 3824 282 | 3025 283 | 4493 284 | 2369 285 | 1050 286 | 3368 287 | 3266 288 | 4641 289 | 5932 290 | 5774 291 | 1287 292 | 3001 293 | 2934 294 | 295 | 16879 296 | 20950 297 | 11598 298 | 299 | 11948 300 | 2932 301 | 1672 302 | 11100 303 | 304 | 24636 305 | 12299 306 | 18577 307 | 308 | 14198 309 | 24466 310 | 25429 311 | 312 | 3539 313 | 5867 314 | 2303 315 | 1372 316 | 3757 317 | 3255 318 | 4606 319 | 4703 320 | 4477 321 | 3515 322 | 5287 323 | 7330 324 | 325 | 2673 326 | 5936 327 | 6292 328 | 4183 329 | 4963 330 | 6462 331 | 4193 332 | 5588 333 | 5140 334 | 2825 335 | 4784 336 | 3210 337 | 1682 338 | 3746 339 | 340 | 12296 341 | 15184 342 | 9500 343 | 16390 344 | 345 | 2816 346 | 6984 347 | 6514 348 | 8120 349 | 8000 350 | 9203 351 | 3716 352 | 353 | 24745 354 | 15138 355 | 356 | 4456 357 | 4546 358 | 4903 359 | 2885 360 | 4578 361 | 2588 362 | 2946 363 | 6634 364 | 1414 365 | 1239 366 | 6070 367 | 4651 368 | 2749 369 | 370 | 3755 371 | 3424 372 | 3633 373 | 2325 374 | 2730 375 | 5526 376 | 6877 377 | 4528 378 | 6567 379 | 2626 380 | 6429 381 | 2464 382 | 383 | 2159 384 | 6338 385 | 2919 386 | 4039 387 | 3091 388 | 7916 389 | 2833 390 | 4192 391 | 5486 392 | 2220 393 | 5616 394 | 395 | 1025 396 | 10572 397 | 6790 398 | 3174 399 | 5986 400 | 2465 401 | 9046 402 | 1559 403 | 404 | 4652 405 | 9609 406 | 4804 407 | 5109 408 | 5301 409 | 9886 410 | 7094 411 | 412 | 1888 413 | 9582 414 | 9566 415 | 2777 416 | 1234 417 | 418 | 6231 419 | 7939 420 | 4757 421 | 3026 422 | 11324 423 | 4069 424 | 6366 425 | 426 | 5078 427 | 6127 428 | 1616 429 | 5894 430 | 3707 431 | 1031 432 | 5544 433 | 4880 434 | 6766 435 | 6411 436 | 2767 437 | 2642 438 | 1197 439 | 440 | 2954 441 | 1929 442 | 8070 443 | 6836 444 | 7396 445 | 7779 446 | 5059 447 | 5299 448 | 3101 449 | 1108 450 | 3408 451 | 452 | 23715 453 | 34978 454 | 455 | 5986 456 | 8393 457 | 3943 458 | 9746 459 | 8118 460 | 6464 461 | 4882 462 | 463 | 66377 464 | 465 | 2291 466 | 6079 467 | 3131 468 | 2006 469 | 6250 470 | 3864 471 | 5167 472 | 3150 473 | 3909 474 | 3435 475 | 2679 476 | 6801 477 | 6361 478 | 479 | 12399 480 | 2412 481 | 2223 482 | 2628 483 | 7269 484 | 485 | 6446 486 | 2771 487 | 6190 488 | 5186 489 | 5672 490 | 5414 491 | 4361 492 | 1204 493 | 1306 494 | 2448 495 | 1425 496 | 2860 497 | 3235 498 | 2123 499 | 500 | 6648 501 | 5782 502 | 2695 503 | 6432 504 | 5396 505 | 5628 506 | 5713 507 | 5889 508 | 5862 509 | 1082 510 | 4800 511 | 6132 512 | 513 | 1804 514 | 6681 515 | 3451 516 | 6039 517 | 6573 518 | 3927 519 | 5420 520 | 1443 521 | 3711 522 | 1906 523 | 5490 524 | 4212 525 | 2221 526 | 527 | 4960 528 | 3469 529 | 3779 530 | 1215 531 | 3665 532 | 6336 533 | 5876 534 | 6523 535 | 1211 536 | 1051 537 | 6900 538 | 2665 539 | 6116 540 | 541 | 5650 542 | 7059 543 | 1520 544 | 3284 545 | 10604 546 | 5219 547 | 6087 548 | 549 | 1385 550 | 3922 551 | 6315 552 | 3317 553 | 2532 554 | 1591 555 | 2191 556 | 6198 557 | 1667 558 | 2358 559 | 4424 560 | 3384 561 | 1452 562 | 1878 563 | 564 | 8968 565 | 6735 566 | 12578 567 | 11709 568 | 7573 569 | 1140 570 | 571 | 8445 572 | 2956 573 | 8682 574 | 8315 575 | 3698 576 | 7811 577 | 6875 578 | 2514 579 | 2348 580 | 581 | 19576 582 | 3115 583 | 13589 584 | 15609 585 | 586 | 43635 587 | 588 | 8805 589 | 24653 590 | 4664 591 | 592 | 6088 593 | 5967 594 | 5407 595 | 3638 596 | 9220 597 | 1047 598 | 2792 599 | 7947 600 | 9559 601 | 602 | 9635 603 | 5762 604 | 7826 605 | 4419 606 | 12047 607 | 8603 608 | 6995 609 | 610 | 6103 611 | 7299 612 | 7646 613 | 4602 614 | 5535 615 | 7703 616 | 6427 617 | 6826 618 | 1506 619 | 5826 620 | 8019 621 | 622 | 5341 623 | 3445 624 | 2020 625 | 4685 626 | 1068 627 | 4974 628 | 5251 629 | 2968 630 | 4358 631 | 4057 632 | 2686 633 | 1122 634 | 2914 635 | 3998 636 | 1247 637 | 638 | 3096 639 | 1152 640 | 4346 641 | 3685 642 | 1365 643 | 4059 644 | 2774 645 | 4958 646 | 3561 647 | 1036 648 | 4612 649 | 4404 650 | 3419 651 | 4733 652 | 3484 653 | 654 | 5167 655 | 1180 656 | 1172 657 | 5057 658 | 3974 659 | 6226 660 | 1309 661 | 4009 662 | 5230 663 | 1105 664 | 4158 665 | 2016 666 | 3786 667 | 2513 668 | 669 | 2940 670 | 1134 671 | 6443 672 | 7340 673 | 5325 674 | 3750 675 | 3839 676 | 7379 677 | 4766 678 | 4173 679 | 680 | 4547 681 | 11948 682 | 7129 683 | 6433 684 | 7101 685 | 2361 686 | 8366 687 | 688 | 1507 689 | 6017 690 | 3115 691 | 6258 692 | 6404 693 | 6000 694 | 1869 695 | 5286 696 | 1623 697 | 1410 698 | 3739 699 | 1632 700 | 2433 701 | 702 | 5846 703 | 6515 704 | 2172 705 | 6728 706 | 6626 707 | 2611 708 | 1583 709 | 2759 710 | 3192 711 | 3197 712 | 1057 713 | 5425 714 | 2712 715 | 716 | 7224 717 | 2884 718 | 2611 719 | 1784 720 | 3902 721 | 7393 722 | 5299 723 | 2389 724 | 1941 725 | 4128 726 | 5461 727 | 1015 728 | 729 | 1743 730 | 9456 731 | 8535 732 | 6753 733 | 7773 734 | 10241 735 | 5969 736 | 8666 737 | 738 | 19734 739 | 2085 740 | 9467 741 | 12261 742 | 743 | 1778 744 | 7318 745 | 2654 746 | 3489 747 | 3276 748 | 4511 749 | 2533 750 | 3292 751 | 4718 752 | 5173 753 | 2267 754 | 5451 755 | 756 | 5567 757 | 5103 758 | 1888 759 | 2210 760 | 4582 761 | 1260 762 | 1264 763 | 4326 764 | 5352 765 | 3549 766 | 5226 767 | 1875 768 | 3156 769 | 3571 770 | 771 | 1380 772 | 7048 773 | 2322 774 | 1694 775 | 4611 776 | 6541 777 | 8334 778 | 2071 779 | 1390 780 | 7593 781 | 782 | 5343 783 | 4878 784 | 1115 785 | 1400 786 | 8760 787 | 4952 788 | 5444 789 | 4012 790 | 791 | 3021 792 | 2193 793 | 6671 794 | 1502 795 | 7320 796 | 7557 797 | 4150 798 | 3959 799 | 1818 800 | 8798 801 | 802 | 19469 803 | 23032 804 | 11831 805 | 806 | 8257 807 | 5493 808 | 5583 809 | 7627 810 | 3801 811 | 3468 812 | 1742 813 | 814 | 9306 815 | 4711 816 | 6825 817 | 8310 818 | 2782 819 | 2447 820 | 10195 821 | 4287 822 | 823 | 10790 824 | 6505 825 | 15999 826 | 15093 827 | 14116 828 | 829 | 1469 830 | 2435 831 | 4534 832 | 8314 833 | 7762 834 | 2064 835 | 5315 836 | 1109 837 | 4439 838 | 839 | 28459 840 | 29638 841 | 842 | 1530 843 | 1274 844 | 5799 845 | 7684 846 | 2594 847 | 6179 848 | 1450 849 | 4017 850 | 5336 851 | 2397 852 | 7630 853 | 854 | 1467 855 | 5771 856 | 5730 857 | 2600 858 | 3958 859 | 4481 860 | 4994 861 | 2718 862 | 6763 863 | 4521 864 | 6496 865 | 866 | 3638 867 | 7722 868 | 6498 869 | 3612 870 | 7521 871 | 1310 872 | 6183 873 | 1850 874 | 6394 875 | 4763 876 | 2657 877 | 878 | 7537 879 | 4591 880 | 2179 881 | 9064 882 | 6970 883 | 2782 884 | 9339 885 | 1265 886 | 7281 887 | 888 | 3380 889 | 12388 890 | 5521 891 | 1191 892 | 8912 893 | 894 | 2776 895 | 3427 896 | 3206 897 | 2075 898 | 2589 899 | 3545 900 | 1806 901 | 2603 902 | 4079 903 | 2700 904 | 3430 905 | 1185 906 | 5708 907 | 1322 908 | 909 | 1466 910 | 4217 911 | 3529 912 | 1232 913 | 5654 914 | 2061 915 | 5435 916 | 5875 917 | 4521 918 | 4841 919 | 6114 920 | 5252 921 | 1185 922 | 5842 923 | 924 | 21001 925 | 8876 926 | 927 | 5131 928 | 5556 929 | 6014 930 | 7791 931 | 3957 932 | 8731 933 | 8053 934 | 8015 935 | 936 | 10379 937 | 3070 938 | 21154 939 | 940 | 3012 941 | 5818 942 | 1144 943 | 6315 944 | 4495 945 | 1846 946 | 7923 947 | 1340 948 | 2675 949 | 4955 950 | 3654 951 | 952 | 5014 953 | 1838 954 | 1302 955 | 4994 956 | 1105 957 | 4055 958 | 3542 959 | 6260 960 | 1219 961 | 1737 962 | 1191 963 | 6069 964 | 5293 965 | 4765 966 | 967 | 18556 968 | 13230 969 | 15065 970 | 18284 971 | 972 | 48135 973 | 974 | 9070 975 | 7739 976 | 6829 977 | 7932 978 | 8713 979 | 4312 980 | 8262 981 | 4925 982 | 2769 983 | 984 | 13528 985 | 4077 986 | 21766 987 | 988 | 6782 989 | 20020 990 | 15396 991 | 992 | 15610 993 | 4166 994 | 5153 995 | 14554 996 | 6008 997 | 998 | 5875 999 | 4131 1000 | 2371 1001 | 1381 1002 | 1793 1003 | 5487 1004 | 5816 1005 | 6051 1006 | 5595 1007 | 5412 1008 | 4800 1009 | 3069 1010 | 2332 1011 | 4360 1012 | 2380 1013 | 1014 | 3310 1015 | 5210 1016 | 13776 1017 | 3665 1018 | 2335 1019 | 6094 1020 | 1021 | 2728 1022 | 4544 1023 | 6050 1024 | 8616 1025 | 8297 1026 | 5501 1027 | 1544 1028 | 5770 1029 | 3807 1030 | 5388 1031 | 1032 | 10758 1033 | 7573 1034 | 7170 1035 | 4945 1036 | 8868 1037 | 8074 1038 | 8055 1039 | 1040 | 6053 1041 | 6804 1042 | 6870 1043 | 9779 1044 | 9992 1045 | 7935 1046 | 1047 | 25222 1048 | 8776 1049 | 10549 1050 | 1051 | 2785 1052 | 37443 1053 | 1054 | 7055 1055 | 7876 1056 | 6587 1057 | 6322 1058 | 6447 1059 | 1060 | 2403 1061 | 3529 1062 | 1514 1063 | 2202 1064 | 2622 1065 | 4484 1066 | 3216 1067 | 7798 1068 | 1135 1069 | 2120 1070 | 1624 1071 | 1072 | 12169 1073 | 8212 1074 | 13127 1075 | 11115 1076 | 7072 1077 | 3080 1078 | 1079 | 5017 1080 | 6458 1081 | 5226 1082 | 1287 1083 | 6413 1084 | 7938 1085 | 4211 1086 | 6724 1087 | 4862 1088 | 1242 1089 | 7481 1090 | 1091 | 47712 1092 | 1093 | 8432 1094 | 3562 1095 | 5349 1096 | 2961 1097 | 1171 1098 | 5888 1099 | 10533 1100 | 6771 1101 | 1102 | 31566 1103 | 13234 1104 | 1105 | 52095 1106 | 1107 | 11601 1108 | 2394 1109 | 1084 1110 | 4909 1111 | 5592 1112 | 5718 1113 | 3912 1114 | 1115 | 10963 1116 | 12196 1117 | 15697 1118 | 3599 1119 | 8635 1120 | 1121 | 22503 1122 | 4376 1123 | 1124 | 9918 1125 | 8408 1126 | 1882 1127 | 6546 1128 | 7045 1129 | 3395 1130 | 6931 1131 | 9059 1132 | 1133 | 4664 1134 | 3815 1135 | 3110 1136 | 1676 1137 | 5396 1138 | 1139 | 9459 1140 | 2435 1141 | 9466 1142 | 8929 1143 | 2587 1144 | 8181 1145 | 5385 1146 | 1703 1147 | 7383 1148 | 1149 | 1271 1150 | 6006 1151 | 4250 1152 | 2558 1153 | 4734 1154 | 1817 1155 | 4695 1156 | 5683 1157 | 6119 1158 | 5150 1159 | 1060 1160 | 3814 1161 | 6012 1162 | 3977 1163 | 1164 | 2690 1165 | 1343 1166 | 3990 1167 | 2648 1168 | 5829 1169 | 5590 1170 | 5609 1171 | 1718 1172 | 2148 1173 | 5400 1174 | 1130 1175 | 4659 1176 | 3463 1177 | 1178 | 3287 1179 | 2098 1180 | 5050 1181 | 6246 1182 | 6901 1183 | 2001 1184 | 2289 1185 | 1892 1186 | 7836 1187 | 1358 1188 | 5224 1189 | 1190 | 7024 1191 | 3331 1192 | 2742 1193 | 6134 1194 | 4850 1195 | 6971 1196 | 4798 1197 | 6270 1198 | 3375 1199 | 3678 1200 | 2791 1201 | 1202 | 2968 1203 | 7186 1204 | 7213 1205 | 1818 1206 | 3735 1207 | 6366 1208 | 1138 1209 | 5386 1210 | 2479 1211 | 3978 1212 | 6926 1213 | 1214 | 10692 1215 | 9805 1216 | 18086 1217 | 13749 1218 | 1219 | 9566 1220 | 1552 1221 | 7121 1222 | 2410 1223 | 8839 1224 | 1581 1225 | 7143 1226 | 5682 1227 | 4454 1228 | 1229 | 2580 1230 | 5217 1231 | 5391 1232 | 3347 1233 | 3384 1234 | 5377 1235 | 2047 1236 | 2465 1237 | 4622 1238 | 5743 1239 | 3015 1240 | 1305 1241 | 1960 1242 | 1243 | 15710 1244 | 1936 1245 | 1246 | 2012 1247 | 1530 1248 | 4286 1249 | 3519 1250 | 4311 1251 | 5820 1252 | 2446 1253 | 5807 1254 | 4890 1255 | 1242 1256 | 4685 1257 | 1258 | 28724 1259 | 1260 | 1094 1261 | 1190 1262 | 2500 1263 | 3617 1264 | 1286 1265 | 2430 1266 | 8633 1267 | 6728 1268 | 7392 1269 | 6037 1270 | 1271 | 7997 1272 | 8802 1273 | 4988 1274 | 6780 1275 | 5537 1276 | 7377 1277 | 1238 1278 | 5501 1279 | 1280 | 3131 1281 | 8597 1282 | 7966 1283 | 6157 1284 | 4817 1285 | 2327 1286 | 4515 1287 | 7983 1288 | 3165 1289 | 6785 1290 | 1291 | 6203 1292 | 2841 1293 | 5423 1294 | 2632 1295 | 7410 1296 | 4532 1297 | 2012 1298 | 8719 1299 | 7507 1300 | 1449 1301 | 1302 | 37282 1303 | 1304 | 3012 1305 | 2285 1306 | 4191 1307 | 2242 1308 | 2014 1309 | 3836 1310 | 1261 1311 | 1951 1312 | 4484 1313 | 5194 1314 | 1328 1315 | 1295 1316 | 5970 1317 | 5030 1318 | 3604 1319 | 1320 | 6092 1321 | 2930 1322 | 1517 1323 | 1064 1324 | 6648 1325 | 6112 1326 | 1392 1327 | 6746 1328 | 4490 1329 | 1785 1330 | 3352 1331 | 2248 1332 | 4975 1333 | 1334 | 1774 1335 | 2925 1336 | 5667 1337 | 4315 1338 | 2228 1339 | 4088 1340 | 2936 1341 | 6062 1342 | 4679 1343 | 5220 1344 | 3173 1345 | 2961 1346 | 3431 1347 | 1907 1348 | 3213 1349 | 1350 | 11417 1351 | 6055 1352 | 10378 1353 | 11585 1354 | 11495 1355 | 3286 1356 | 1357 | 4242 1358 | 2198 1359 | 1453 1360 | 2454 1361 | 2088 1362 | 1068 1363 | 3263 1364 | 2082 1365 | 4262 1366 | 3684 1367 | 3614 1368 | 1624 1369 | 1772 1370 | 3144 1371 | 2264 1372 | 1373 | 6044 1374 | 5100 1375 | 1281 1376 | 4829 1377 | 5966 1378 | 5878 1379 | 1380 | 1648 1381 | 3848 1382 | 2167 1383 | 1269 1384 | 2907 1385 | 5569 1386 | 2338 1387 | 3106 1388 | 3710 1389 | 2819 1390 | 3167 1391 | 6767 1392 | 1247 1393 | 1394 | 11542 1395 | 5319 1396 | 7390 1397 | 10247 1398 | 5825 1399 | 3701 1400 | 5173 1401 | 1402 | 24038 1403 | 13030 1404 | 12703 1405 | 1406 | 21677 1407 | 13326 1408 | 1409 | 7060 1410 | 1796 1411 | 1544 1412 | 5340 1413 | 2291 1414 | 3485 1415 | 3469 1416 | 4839 1417 | 1484 1418 | 1419 | 5894 1420 | 1537 1421 | 11507 1422 | 6994 1423 | 8819 1424 | 9523 1425 | 1286 1426 | 1427 | 2034 1428 | 6244 1429 | 4109 1430 | 1153 1431 | 3516 1432 | 1981 1433 | 5427 1434 | 6918 1435 | 5572 1436 | 6415 1437 | 6618 1438 | 1439 | 7353 1440 | 11049 1441 | 9629 1442 | 9086 1443 | 6160 1444 | 10827 1445 | 1446 | 4833 1447 | 4240 1448 | 5281 1449 | 2985 1450 | 5001 1451 | 8689 1452 | 5876 1453 | 7358 1454 | 3057 1455 | 1477 1456 | 1457 | 64086 1458 | 1459 | 5607 1460 | 1461 | 3536 1462 | 10591 1463 | 7185 1464 | 8614 1465 | 1048 1466 | 4488 1467 | 8893 1468 | 1469 | 20808 1470 | 3764 1471 | 4172 1472 | 1473 | 11061 1474 | 3485 1475 | 1476 | 2184 1477 | 4986 1478 | 6147 1479 | 1483 1480 | 4170 1481 | 7920 1482 | 3623 1483 | 4908 1484 | 2433 1485 | 8087 1486 | 5981 1487 | 1488 | 4145 1489 | 5088 1490 | 3079 1491 | 2696 1492 | 1069 1493 | 6533 1494 | 6205 1495 | 4633 1496 | 3393 1497 | 1875 1498 | 6734 1499 | 4047 1500 | 4783 1501 | 1502 | 16756 1503 | 30731 1504 | 1505 | 27320 1506 | 12665 1507 | 1508 | 2342 1509 | 1130 1510 | 2482 1511 | 1540 1512 | 7263 1513 | 6251 1514 | 3244 1515 | 7960 1516 | 7255 1517 | 5031 1518 | 5540 1519 | 1520 | 6945 1521 | 10279 1522 | 5400 1523 | 3868 1524 | 4448 1525 | 1159 1526 | 7190 1527 | 1858 1528 | 1529 | 7499 1530 | 7600 1531 | 3816 1532 | 6417 1533 | 11374 1534 | 1535 | 53260 1536 | 1537 | 10436 1538 | 7554 1539 | 7263 1540 | 7794 1541 | 2222 1542 | 10687 1543 | 3170 1544 | 1545 | 9157 1546 | 3146 1547 | 1723 1548 | 6066 1549 | 9016 1550 | 7758 1551 | 2885 1552 | 4938 1553 | 1554 | 4079 1555 | 1302 1556 | 5794 1557 | 4695 1558 | 3859 1559 | 2063 1560 | 1108 1561 | 2669 1562 | 4541 1563 | 2125 1564 | 3846 1565 | 6019 1566 | 5780 1567 | 5048 1568 | 1569 | 11772 1570 | 3333 1571 | 8185 1572 | 3786 1573 | 7493 1574 | 10737 1575 | 2954 1576 | 1577 | 5412 1578 | 4386 1579 | 2105 1580 | 4871 1581 | 1621 1582 | 2588 1583 | 6143 1584 | 1314 1585 | 4979 1586 | 3222 1587 | 1918 1588 | 4300 1589 | 1590 | 3598 1591 | 3198 1592 | 4102 1593 | 8638 1594 | 3899 1595 | 8204 1596 | 2209 1597 | 1598 | 3851 1599 | 5188 1600 | 5494 1601 | 4102 1602 | 2427 1603 | 2568 1604 | 5264 1605 | 3951 1606 | 5236 1607 | 4779 1608 | 2152 1609 | 2163 1610 | 4852 1611 | 1866 1612 | 1613 | 4900 1614 | 4865 1615 | 1946 1616 | 1585 1617 | 2073 1618 | 6066 1619 | 3482 1620 | 1118 1621 | 1250 1622 | 2125 1623 | 6795 1624 | 4522 1625 | 3602 1626 | 1627 | 1352 1628 | 6115 1629 | 7150 1630 | 6257 1631 | 7255 1632 | 3150 1633 | 3372 1634 | 4024 1635 | 3744 1636 | 1436 1637 | 4558 1638 | 5741 1639 | 1640 | 5330 1641 | 7428 1642 | 6493 1643 | 4217 1644 | 9133 1645 | 2001 1646 | 2117 1647 | 8205 1648 | 4679 1649 | 1650 | 1039 1651 | 5446 1652 | 1385 1653 | 6914 1654 | 2516 1655 | 1703 1656 | 3439 1657 | 5279 1658 | 5214 1659 | 3995 1660 | 2455 1661 | 2006 1662 | 4653 1663 | 1664 | 11735 1665 | 6890 1666 | 18785 1667 | 11174 1668 | 1669 | 6361 1670 | 4088 1671 | 8048 1672 | 2118 1673 | 6994 1674 | 3985 1675 | 7492 1676 | 2137 1677 | 7852 1678 | 7743 1679 | 5795 1680 | 1681 | 1399 1682 | 5322 1683 | 7254 1684 | 1685 | 2887 1686 | 3842 1687 | 2467 1688 | 7211 1689 | 5307 1690 | 6887 1691 | 3368 1692 | 4678 1693 | 1254 1694 | 1202 1695 | 1696 | 4740 1697 | 5746 1698 | 1742 1699 | 2749 1700 | 6503 1701 | 2949 1702 | 1161 1703 | 5671 1704 | 6057 1705 | 5157 1706 | 1619 1707 | 5947 1708 | 6338 1709 | 4537 1710 | 1711 | 1448 1712 | 1427 1713 | 15871 1714 | 4776 1715 | 10021 1716 | 1717 | 7272 1718 | 5789 1719 | 6013 1720 | 3511 1721 | 2392 1722 | 8082 1723 | 9583 1724 | 6188 1725 | 1726 | 42302 1727 | 1728 | 1943 1729 | 3178 1730 | 7626 1731 | 7150 1732 | 2064 1733 | 1486 1734 | 7344 1735 | 1988 1736 | 6079 1737 | 1738 | 7075 1739 | 1400 1740 | 4314 1741 | 5688 1742 | 4630 1743 | 6478 1744 | 1247 1745 | 5885 1746 | 6741 1747 | 6403 1748 | 3825 1749 | 1750 | 5186 1751 | 2077 1752 | 3021 1753 | 4983 1754 | 4907 1755 | 3529 1756 | 3227 1757 | 4448 1758 | 1144 1759 | 1760 | 4816 1761 | 1427 1762 | 8101 1763 | 6482 1764 | 8208 1765 | 9606 1766 | 5595 1767 | 5328 1768 | 7792 1769 | 1770 | 6090 1771 | 2627 1772 | 1141 1773 | 2740 1774 | 4856 1775 | 5727 1776 | 2102 1777 | 2985 1778 | 5365 1779 | 1041 1780 | 1036 1781 | 1636 1782 | 2345 1783 | 2379 1784 | 4654 1785 | 1786 | 7437 1787 | 9144 1788 | 4579 1789 | 1225 1790 | 7821 1791 | 6909 1792 | 1844 1793 | 6643 1794 | 5680 1795 | 1796 | 9820 1797 | 20439 1798 | 1799 | 10177 1800 | 1834 1801 | 5160 1802 | 6476 1803 | 8352 1804 | 6981 1805 | 6495 1806 | 4232 1807 | 1808 | 19764 1809 | 2091 1810 | 13751 1811 | 1812 | 9408 1813 | 21846 1814 | 23438 1815 | 1816 | 36692 1817 | 1818 | 2312 1819 | 23451 1820 | 21444 1821 | 1822 | 8577 1823 | 16088 1824 | 6638 1825 | 3195 1826 | 1827 | 8178 1828 | 2765 1829 | 5564 1830 | 3191 1831 | 4604 1832 | 1430 1833 | 4034 1834 | 6644 1835 | 4469 1836 | 3445 1837 | 1838 | 17210 1839 | 34046 1840 | 1841 | 8370 1842 | 5176 1843 | 1309 1844 | 6288 1845 | 7944 1846 | 1098 1847 | 7113 1848 | 1849 | 1468 1850 | 3241 1851 | 4149 1852 | 7521 1853 | 5759 1854 | 4483 1855 | 2993 1856 | 6307 1857 | 7456 1858 | 2687 1859 | 1646 1860 | 1861 | 5728 1862 | 1132 1863 | 6223 1864 | 4918 1865 | 5095 1866 | 4815 1867 | 5589 1868 | 4549 1869 | 1827 1870 | 2757 1871 | 2134 1872 | 3079 1873 | 4709 1874 | 1875 | 3905 1876 | 4016 1877 | 2848 1878 | 1499 1879 | 2841 1880 | 4670 1881 | 4478 1882 | 3694 1883 | 2334 1884 | 3019 1885 | 3761 1886 | 3986 1887 | 5486 1888 | 1889 | 1096 1890 | 3760 1891 | 4569 1892 | 4388 1893 | 2661 1894 | 6027 1895 | 7493 1896 | 5582 1897 | 6502 1898 | 2966 1899 | 1900 | 7501 1901 | 1109 1902 | 8955 1903 | 3136 1904 | 6744 1905 | 6849 1906 | 1916 1907 | 3971 1908 | 3396 1909 | 1910 | 1865 1911 | 1631 1912 | 1981 1913 | 1333 1914 | 1431 1915 | 5516 1916 | 7613 1917 | 1926 1918 | 3224 1919 | 4058 1920 | 1921 | 9732 1922 | 9318 1923 | 1299 1924 | 7300 1925 | 9826 1926 | 6425 1927 | 7878 1928 | 10546 1929 | 1930 | 10269 1931 | 17150 1932 | 1771 1933 | 10243 1934 | 1935 | 17664 1936 | 19265 1937 | 1710 1938 | 18754 1939 | 1940 | 3695 1941 | 4063 1942 | 1571 1943 | 6002 1944 | 3421 1945 | 2712 1946 | 5175 1947 | 3987 1948 | 2780 1949 | 5452 1950 | 2383 1951 | 4207 1952 | 6162 1953 | 5926 1954 | 1955 | 5918 1956 | 2169 1957 | 5996 1958 | 3842 1959 | 5338 1960 | 1061 1961 | 1221 1962 | 3034 1963 | 1357 1964 | 1447 1965 | 2178 1966 | 5486 1967 | 2861 1968 | 4633 1969 | 1822 1970 | 1971 | 9053 1972 | 9367 1973 | 2796 1974 | 13702 1975 | 10292 1976 | 2461 1977 | 1978 | 20214 1979 | 25924 1980 | 5012 1981 | 1982 | 6229 1983 | 3670 1984 | 9939 1985 | 6177 1986 | 5980 1987 | 9907 1988 | 9698 1989 | 1990 | 3846 1991 | 6923 1992 | 9058 1993 | 9689 1994 | 7405 1995 | 3684 1996 | 9010 1997 | 5705 1998 | 2877 1999 | 2000 | 13046 2001 | 8583 2002 | 2706 2003 | 1403 2004 | 4918 2005 | 10851 2006 | 2007 | 1349 2008 | 11562 2009 | 14857 2010 | 2260 2011 | 8315 2012 | 2013 | 1375 2014 | 3094 2015 | 3849 2016 | 8763 2017 | 7189 2018 | 2550 2019 | 5346 2020 | 1905 2021 | 3498 2022 | 1416 2023 | 2024 | 34144 2025 | 11430 2026 | 2027 | 11590 2028 | 4032 2029 | 7238 2030 | 2641 2031 | 4778 2032 | 4260 2033 | 6007 2034 | 2035 | 1226 2036 | 1934 2037 | 6034 2038 | 3159 2039 | 2234 2040 | 3509 2041 | 4759 2042 | 5837 2043 | 1789 2044 | 4726 2045 | 1075 2046 | 5543 2047 | 2774 2048 | 3144 2049 | 2050 | 8556 2051 | 1675 2052 | 12135 2053 | 10831 2054 | 10837 2055 | 2056 | 3087 2057 | 1977 2058 | 3832 2059 | 6304 2060 | 4023 2061 | 4219 2062 | 1594 2063 | 4685 2064 | 2650 2065 | 1652 2066 | 3029 2067 | 3913 2068 | 3970 2069 | 2311 2070 | 2071 | 1088 2072 | 15228 2073 | 3891 2074 | 9920 2075 | 7675 2076 | 2077 | 4758 2078 | 2544 2079 | 3198 2080 | 7038 2081 | 4561 2082 | 5105 2083 | 7469 2084 | 6070 2085 | 4917 2086 | 1288 2087 | 2099 2088 | 2257 2089 | 2090 | 10202 2091 | 1478 2092 | 1355 2093 | 10235 2094 | 9177 2095 | 7656 2096 | 10315 2097 | 5359 2098 | 2099 | 1336 2100 | 4004 2101 | 2306 2102 | 1358 2103 | 2831 2104 | 2861 2105 | 6211 2106 | 1492 2107 | 5542 2108 | 6370 2109 | 2111 2110 | 4289 2111 | 5037 2112 | 3784 2113 | 2114 | 3083 2115 | 3535 2116 | 2551 2117 | 4519 2118 | 2305 2119 | 5878 2120 | 2102 2121 | 1477 2122 | 5529 2123 | 2048 2124 | 5068 2125 | 5816 2126 | 2887 2127 | 2567 2128 | 3309 2129 | 2130 | 11079 2131 | 4417 2132 | 19925 2133 | 2134 | 3159 2135 | 14561 2136 | 24535 2137 | 2138 | 4712 2139 | 2595 2140 | 2996 2141 | 2035 2142 | 3697 2143 | 2792 2144 | 1377 2145 | 1002 2146 | 4955 2147 | 1728 2148 | 5072 2149 | 5754 2150 | 2671 2151 | 1267 2152 | 5035 2153 | 2154 | 7438 2155 | 2343 2156 | 6421 2157 | 3441 2158 | 6451 2159 | 3448 2160 | 3853 2161 | 7268 2162 | 5461 2163 | 4265 2164 | 5232 2165 | 2166 | 4224 2167 | 1229 2168 | 2945 2169 | 2152 2170 | 2899 2171 | 1055 2172 | 4692 2173 | 2627 2174 | 5771 2175 | 5807 2176 | 4868 2177 | 2069 2178 | 2179 | 7271 2180 | 1691 2181 | 1945 2182 | 1814 2183 | 8487 2184 | 7836 2185 | 11053 2186 | 2187 | 4542 2188 | 6055 2189 | 9464 2190 | 1919 2191 | 6973 2192 | 1526 2193 | 3408 2194 | 5265 2195 | 7587 2196 | 2197 | 26489 2198 | 25984 2199 | 2200 | 13254 2201 | 34865 2202 | 2203 | 3338 2204 | 2313 2205 | 1854 2206 | 1232 2207 | 4036 2208 | 2156 2209 | 3203 2210 | 3959 2211 | 4643 2212 | 4045 2213 | 2097 2214 | 5726 2215 | 3509 2216 | 3801 2217 | 2218 | 1530 2219 | 5956 2220 | 5236 2221 | 6895 2222 | 2136 2223 | 8084 2224 | 1550 2225 | 6776 2226 | 1042 2227 | 5389 2228 | 4815 2229 | 2230 | 1479 2231 | 2337 2232 | 5443 2233 | 5880 2234 | 8131 2235 | 9774 2236 | 4225 2237 | 5564 2238 | 2239 | 9111 2240 | 3248 2241 | 5761 2242 | 8147 2243 | 3285 2244 | 11468 --------------------------------------------------------------------------------