mirror of
				https://github.com/onyx-and-iris/aoc2023.git
				synced 2025-10-31 21:01:50 +00:00 
			
		
		
		
	day-4
This commit is contained in:
		
							parent
							
								
									714558f3c1
								
							
						
					
					
						commit
						8aa073b5ad
					
				
							
								
								
									
										5
									
								
								day-4/go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								day-4/go.mod
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| module github.com/onyx-and-iris/aoc2023/day-4 | ||||
| 
 | ||||
| go 1.20 | ||||
| 
 | ||||
| require github.com/go-playground/assert v1.2.1 | ||||
							
								
								
									
										2
									
								
								day-4/go.sum
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								day-4/go.sum
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| github.com/go-playground/assert v1.2.1 h1:ad06XqC+TOv0nJWnbULSlh3ehp5uLuQEojZY5Tq8RgI= | ||||
| github.com/go-playground/assert v1.2.1/go.mod h1:Lgy+k19nOB/wQG/fVSQ7rra5qYugmytMQqvQ2dgjWn8= | ||||
							
								
								
									
										61
									
								
								day-4/one.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								day-4/one.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"regexp" | ||||
| ) | ||||
| 
 | ||||
| type M map[string]interface{} | ||||
| 
 | ||||
| var allCards []M | ||||
| 
 | ||||
| var _regex_winning_numbers = regexp.MustCompile( | ||||
| 	`^Card (?P<card>[\s\d]+):\s` + | ||||
| 		`(?P<winning>[0-9\s]+)\s` + | ||||
| 		`\|\s` + | ||||
| 		`(?P<mynums>[0-9\s]+)$`) | ||||
| 
 | ||||
| var _regex_nums = regexp.MustCompile("[0-9]+") | ||||
| 
 | ||||
| // compareLists returns the number of matching elements between winning and mynums | ||||
| func compareLists(winningStr string, mynumsStr string) (int, error) { | ||||
| 	x, err := numStrToArr(winningStr, []int{}) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	winning := x | ||||
| 	x, err = numStrToArr(mynumsStr, []int{}) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	mynums := x | ||||
| 
 | ||||
| 	n := 0 | ||||
| 	for _, num := range mynums { | ||||
| 		if contains(winning, num) { | ||||
| 			n += 1 | ||||
| 		} | ||||
| 	} | ||||
| 	return n, nil | ||||
| } | ||||
| 
 | ||||
| // one computes points based on matching numbers | ||||
| func one(lines []string) (int, error) { | ||||
| 	for _, line := range lines { | ||||
| 		parseAllCards(line) | ||||
| 	} | ||||
| 	cards = make([]Card, len(lines)) | ||||
| 
 | ||||
| 	sum := 0 | ||||
| 	for x, card := range allCards { | ||||
| 		m, err := compareLists(card["winning"].(string), card["mynums"].(string)) | ||||
| 		if err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 		cards[x].matches = m | ||||
| 		if cards[x].matches > 0 { | ||||
| 			sum += (pow(2, cards[x].matches-1)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return sum, nil | ||||
| } | ||||
							
								
								
									
										25
									
								
								day-4/one_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								day-4/one_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/go-playground/assert/v2" | ||||
| ) | ||||
| 
 | ||||
| func TestCompareLists(t *testing.T) { | ||||
| 	//t.Skip("skipping test") | ||||
| 	t.Run("Should find 4 matches", func(t *testing.T) { | ||||
| 		res, _ := compareLists("41 48 83 86 17", "83 86  6 31 17  9 48 53") | ||||
| 		assert.Equal(t, 4, res) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("Should find 2 matches", func(t *testing.T) { | ||||
| 		res, _ := compareLists(" 1 21 53 59 44 ", "69 82 63 72 16 21 14  1") | ||||
| 		assert.Equal(t, 2, res) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("Should find 0 matches", func(t *testing.T) { | ||||
| 		res, _ := compareLists("87 83 26 28 32", "88 30 70 12 93 22 82 36") | ||||
| 		assert.Equal(t, 0, res) | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										5
									
								
								day-4/run.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								day-4/run.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,5 @@ | ||||
| #!/usr/bin/env bash | ||||
| 
 | ||||
| INPUT="input.txt" | ||||
| 
 | ||||
| cat $INPUT | go run . | ||||
							
								
								
									
										22
									
								
								day-4/solution.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								day-4/solution.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	lines := readlines() | ||||
| 
 | ||||
| 	ans, err := one(lines) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	fmt.Printf("solution one: %d\n", ans) | ||||
| 
 | ||||
| 	ans, err = two(lines) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	fmt.Printf("solution two: %d\n", ans) | ||||
| } | ||||
							
								
								
									
										27
									
								
								day-4/two.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								day-4/two.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| package main | ||||
| 
 | ||||
| // Cards represents a single card. | ||||
| // it tracks its matching numbers and occurrences | ||||
| type Card struct { | ||||
| 	matches     int | ||||
| 	occurrences int | ||||
| } | ||||
| 
 | ||||
| var cards = []Card{} | ||||
| 
 | ||||
| // two returns the total number of occurrences for all cards | ||||
| func two(lines []string) (int, error) { | ||||
| 	var sum = 0 | ||||
| 
 | ||||
| 	for i := range cards { | ||||
| 		cards[i].occurrences++ | ||||
| 
 | ||||
| 		for j := i + 1; j <= i+cards[i].matches; j++ { | ||||
| 			cards[j].occurrences += cards[i].occurrences | ||||
| 		} | ||||
| 
 | ||||
| 		sum += cards[i].occurrences | ||||
| 	} | ||||
| 
 | ||||
| 	return sum, nil | ||||
| } | ||||
							
								
								
									
										63
									
								
								day-4/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								day-4/util.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"log" | ||||
| 	"math" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| ) | ||||
| 
 | ||||
| // readlines reads lines from stdin. | ||||
| // Then it returns them as an array of strings | ||||
| func readlines() []string { | ||||
| 	lines := []string{} | ||||
| 
 | ||||
| 	scanner := bufio.NewScanner(os.Stdin) | ||||
| 	for scanner.Scan() { | ||||
| 		lines = append(lines, scanner.Text()) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := scanner.Err(); err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	return lines | ||||
| } | ||||
| 
 | ||||
| func parseAllCards(line string) { | ||||
| 	groups := M{} | ||||
| 	res := _regex_winning_numbers.FindStringSubmatch(line) | ||||
| 	names := _regex_winning_numbers.SubexpNames() | ||||
| 	for i := range res { | ||||
| 		groups[names[i]] = res[i] | ||||
| 	} | ||||
| 	allCards = append(allCards, groups) | ||||
| } | ||||
| 
 | ||||
| // numStrToArr converts a string of numbers or an array of numbers | ||||
| func numStrToArr(nums string, arr []int) ([]int, error) { | ||||
| 	for _, num := range _regex_nums.FindAllString(nums, -1) { | ||||
| 		n, err := strconv.Atoi(num) | ||||
| 		if err != nil { | ||||
| 			return []int{}, err | ||||
| 		} | ||||
| 		arr = append(arr, n) | ||||
| 	} | ||||
| 	return arr, nil | ||||
| } | ||||
| 
 | ||||
| // contains returns true if an slice of elements contains a given element | ||||
| func contains[T comparable](elems []T, v T) bool { | ||||
| 	for _, s := range elems { | ||||
| 		if v == s { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // pow returns the value of x to the n | ||||
| func pow(x, n int) int { | ||||
| 	return int(math.Pow(float64(x), float64(n))) | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user