Compare commits
	
		
			No commits in common. "8b6ea615f7793d0e17434184196565a601a22a7d" and "170a116ffbeca07b319ee382ab3a852c3380aa18" have entirely different histories.
		
	
	
		
			8b6ea615f7
			...
			170a116ffb
		
	
		
					 9 changed files with 0 additions and 249 deletions
				
			
		| 
						 | 
					@ -1,75 +0,0 @@
 | 
				
			||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const digits = "0123456789"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func words() [10]string {
 | 
					 | 
				
			||||||
	return [10]string{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func firstDigit(input string) string {
 | 
					 | 
				
			||||||
	var result string
 | 
					 | 
				
			||||||
	loc := len(input)
 | 
					 | 
				
			||||||
	if index := strings.IndexAny(input, "0123456789"); index != -1 {
 | 
					 | 
				
			||||||
		loc = index
 | 
					 | 
				
			||||||
		result = string([]rune(input)[index])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for key, value := range words() {
 | 
					 | 
				
			||||||
		if index := strings.Index(input, value); index != -1 && index <= loc {
 | 
					 | 
				
			||||||
			loc = index
 | 
					 | 
				
			||||||
			result = strconv.Itoa(key)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func lastDigit(input string) string {
 | 
					 | 
				
			||||||
	var result string
 | 
					 | 
				
			||||||
	loc := -1
 | 
					 | 
				
			||||||
	if index := strings.LastIndexAny(input, "0123456789"); index != -1 {
 | 
					 | 
				
			||||||
		loc = index
 | 
					 | 
				
			||||||
		result = string([]rune(input)[index])
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for key, value := range words() {
 | 
					 | 
				
			||||||
		if index := strings.LastIndex(input, value); index != -1 && index >= loc {
 | 
					 | 
				
			||||||
			loc = index
 | 
					 | 
				
			||||||
			result = strconv.Itoa(key)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return result
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func calibration(input string) int {
 | 
					 | 
				
			||||||
	first := firstDigit(input)
 | 
					 | 
				
			||||||
	last := lastDigit(input)
 | 
					 | 
				
			||||||
	output, _ := strconv.Atoi(first + last)
 | 
					 | 
				
			||||||
	return output
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func ScanFile(file *os.File) (int, error) {
 | 
					 | 
				
			||||||
	scanner := bufio.NewScanner(file)
 | 
					 | 
				
			||||||
	sum := 0
 | 
					 | 
				
			||||||
    for scanner.Scan() {
 | 
					 | 
				
			||||||
        sum += calibration(scanner.Text())
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if err := scanner.Err(); err != nil {
 | 
					 | 
				
			||||||
        return 0, err
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
	return sum, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	sum, err := ScanFile(os.Stdin)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Fprintf(os.Stderr, "Invalid input: %s\n", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fmt.Println(sum)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,32 +0,0 @@
 | 
				
			||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestScanFile(t *testing.T) {
 | 
					 | 
				
			||||||
    cases := []struct {
 | 
					 | 
				
			||||||
        inFile string;
 | 
					 | 
				
			||||||
		want int;
 | 
					 | 
				
			||||||
    }{
 | 
					 | 
				
			||||||
        {"input1.txt", 142},
 | 
					 | 
				
			||||||
        {"input2.txt", 281},
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for _, c := range cases {
 | 
					 | 
				
			||||||
		f, err := os.Open(c.inFile)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Fatal(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		got, err := ScanFile(f)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Fatal(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if got != c.want {
 | 
					 | 
				
			||||||
			t.Errorf("ScanFile(%q) == %d, want %d", c.inFile, got, c.want)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,4 +0,0 @@
 | 
				
			||||||
1abc2
 | 
					 | 
				
			||||||
pqr3stu8vwx
 | 
					 | 
				
			||||||
a1b2c3d4e5f
 | 
					 | 
				
			||||||
treb7uchet
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,7 +0,0 @@
 | 
				
			||||||
two1nine
 | 
					 | 
				
			||||||
eightwothree
 | 
					 | 
				
			||||||
abcone2threexyz
 | 
					 | 
				
			||||||
xtwone3four
 | 
					 | 
				
			||||||
4nineeightseven2
 | 
					 | 
				
			||||||
zoneight234
 | 
					 | 
				
			||||||
7pqrstsixteen
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,82 +0,0 @@
 | 
				
			||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Game struct {
 | 
					 | 
				
			||||||
	id int
 | 
					 | 
				
			||||||
	sets []Set
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Set struct {
 | 
					 | 
				
			||||||
	red int
 | 
					 | 
				
			||||||
	green int
 | 
					 | 
				
			||||||
	blue int
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func parseGame(input string) Game {
 | 
					 | 
				
			||||||
	idStr, setsStr, _ := strings.Cut(input, ": ")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var game Game
 | 
					 | 
				
			||||||
	var err error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	game.id, err = strconv.Atoi(strings.TrimPrefix(idStr, "Game "))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i, setStr := range strings.Split(setsStr, "; ") {
 | 
					 | 
				
			||||||
		game.sets = append(game.sets, Set{})
 | 
					 | 
				
			||||||
		for _, colorStr := range strings.Split(setStr, ", ") {
 | 
					 | 
				
			||||||
			if strings.HasSuffix(colorStr, " red") {
 | 
					 | 
				
			||||||
				game.sets[i].red, err = strconv.Atoi(strings.TrimSuffix(colorStr, " red"))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if strings.HasSuffix(colorStr, " green") {
 | 
					 | 
				
			||||||
				game.sets[i].green, err = strconv.Atoi(strings.TrimSuffix(colorStr, " green"))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if strings.HasSuffix(colorStr, " blue") {
 | 
					 | 
				
			||||||
				game.sets[i].blue, err = strconv.Atoi(strings.TrimSuffix(colorStr, " blue"))
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if err != nil {
 | 
					 | 
				
			||||||
        panic("day02: invalid game format")
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return game
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func isGameValid(game Game) bool {
 | 
					 | 
				
			||||||
	for _, set := range game.sets {
 | 
					 | 
				
			||||||
		if set.red > 12 || set.green > 13 || set.blue > 14 {
 | 
					 | 
				
			||||||
			return false
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func ScanFile(file *os.File) (int, error) {
 | 
					 | 
				
			||||||
	scanner := bufio.NewScanner(file)
 | 
					 | 
				
			||||||
	sum := 0
 | 
					 | 
				
			||||||
    for scanner.Scan() {
 | 
					 | 
				
			||||||
		if game := parseGame(scanner.Text()); isGameValid(game) {
 | 
					 | 
				
			||||||
			sum += game.id
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if err := scanner.Err(); err != nil {
 | 
					 | 
				
			||||||
        return 0, err
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
	return sum, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	sum, err := ScanFile(os.Stdin)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		fmt.Fprintf(os.Stderr, "Invalid input: %s\n", err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fmt.Println(sum)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,31 +0,0 @@
 | 
				
			||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestScanFile(t *testing.T) {
 | 
					 | 
				
			||||||
    cases := []struct {
 | 
					 | 
				
			||||||
        inFile string;
 | 
					 | 
				
			||||||
		want int;
 | 
					 | 
				
			||||||
    }{
 | 
					 | 
				
			||||||
        {"input1.txt", 8},
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for _, c := range cases {
 | 
					 | 
				
			||||||
		f, err := os.Open(c.inFile)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Fatal(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		got, err := ScanFile(f)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Fatal(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
		if got != c.want {
 | 
					 | 
				
			||||||
			t.Errorf("ScanFile(%q) == %d, want %d", c.inFile, got, c.want)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,5 +0,0 @@
 | 
				
			||||||
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
 | 
					 | 
				
			||||||
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
 | 
					 | 
				
			||||||
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
 | 
					 | 
				
			||||||
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
 | 
					 | 
				
			||||||
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
										
									
									
									
								
							| 
						 | 
					@ -1,3 +0,0 @@
 | 
				
			||||||
module git.qenya.tel/qenya/aoc2023
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
go 1.23.2
 | 
					 | 
				
			||||||
							
								
								
									
										10
									
								
								shell.nix
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								shell.nix
									
										
									
									
									
								
							| 
						 | 
					@ -1,10 +0,0 @@
 | 
				
			||||||
let
 | 
					 | 
				
			||||||
  pkgs = import <nixpkgs> {};
 | 
					 | 
				
			||||||
in pkgs.mkShell {
 | 
					 | 
				
			||||||
  packages = with pkgs; [
 | 
					 | 
				
			||||||
    go
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
  shellHook = ''
 | 
					 | 
				
			||||||
    export PATH=$PATH:~/go/bin
 | 
					 | 
				
			||||||
  '';
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue