package main import ( "fmt" "io/ioutil" "log" "os" "strings" ) func CalculateChecksum(img []int, width, height int) int { // Find layer least0 := 999999 var leastLayer int layers := len(img) / (width * height) for l := 0; l < layers; l++ { num0 := 0 offset := l * (width * height) for y := 0; y < height; y++ { i := offset + (y * width) for x := 0; x < width; x++ { if img[i+x] == 0 { num0++ } } } if num0 < least0 { least0 = num0 leastLayer = l } } // Count 1s and 2s var ones, twos int offset := leastLayer * (width * height) for y := 0; y < height; y++ { i := offset + (y * width) for x := 0; x < width; x++ { if img[i+x] == 1 { ones++ } else if img[i+x] == 2 { twos++ } } } return ones * twos } func FlattenImage(img []int, width, height int) []int { result := make([]int, width*height) layers := len(img) / (width * height) for l := layers - 1; l >= 0; l-- { offset := l * (width * height) for y := 0; y < height; y++ { i := offset + (y * width) for x := 0; x < width; x++ { if img[i+x] != 2 { result[i+x-offset] = img[i+x] } } } } return result } func main() { input, err := os.Open("input.txt") if err != nil { log.Fatal(fmt.Errorf("could not open input file: %w", err)) } defer input.Close() raw, err := ioutil.ReadAll(input) if err != nil { log.Fatal(fmt.Errorf("error while reading input: %w", err)) } raw = []byte(strings.TrimSpace(string(raw))) img := make([]int, len(raw)) for i := range raw { img[i] = int(raw[i] - 48) } result := CalculateChecksum(img, 25, 6) fmt.Printf("Part 1: %d\n", result) flattened := FlattenImage(img, 25, 6) fmt.Println("Part 2:") for y := 0; y < 6; y++ { i := (y * 25) for x := 0; x < 25; x++ { var r rune if flattened[i+x] == 0 { r = ' ' } else { r = '*' } fmt.Printf("%c", r) } fmt.Println() } }