github.com/agrigoryan/aoc_2023_go@v0.0.0-20231216221323-4ace361ec685/day11/d11p1.go (about)

     1  package day11
     2  
     3  import (
     4  	"strings"
     5  )
     6  
     7  type pos struct {
     8  	r, c int
     9  }
    10  
    11  func abs(i int) int {
    12  	if i < 0 {
    13  		return -i
    14  	} else {
    15  		return i
    16  	}
    17  }
    18  
    19  func isBetween(x, a, b int) bool {
    20  	min := a
    21  	max := b
    22  	if a > b {
    23  		min = b
    24  		max = a
    25  	}
    26  	return min < x && x < max
    27  }
    28  
    29  func calcSumDistance(input string, expAmount int) int {
    30  	lines := strings.Split(input, "\n")
    31  	expColumns := []int{}
    32  	expRows := []int{}
    33  	galaxies := []pos{}
    34  
    35  	for row, line := range lines {
    36  		shouldExpand := true
    37  		for col, rune := range line {
    38  			if rune != '.' {
    39  				shouldExpand = false
    40  				galaxies = append(galaxies, pos{
    41  					r: row,
    42  					c: col,
    43  				})
    44  			}
    45  		}
    46  		if shouldExpand {
    47  			expRows = append(expRows, row)
    48  		}
    49  	}
    50  
    51  	for col := 0; col < len(lines[0]); col++ {
    52  		shouldExpand := true
    53  		for _, line := range lines {
    54  			if line[col] != '.' {
    55  				shouldExpand = false
    56  				break
    57  			}
    58  		}
    59  		if shouldExpand {
    60  			expColumns = append(expColumns, col)
    61  		}
    62  	}
    63  
    64  	sum := 0
    65  	for i := 0; i < len(galaxies); i++ {
    66  		ga := galaxies[i]
    67  		for j := i; j < len(galaxies); j++ {
    68  			gb := galaxies[j]
    69  			d := abs(ga.c-gb.c) + abs(ga.r-gb.r)
    70  			for _, row := range expRows {
    71  				if isBetween(row, ga.r, gb.r) {
    72  					d += expAmount
    73  				}
    74  			}
    75  			for _, col := range expColumns {
    76  				if isBetween(col, ga.c, gb.c) {
    77  					d += expAmount
    78  				}
    79  			}
    80  			sum += d
    81  		}
    82  	}
    83  
    84  	return sum
    85  }
    86  
    87  func d11p1(input string) int {
    88  	return calcSumDistance(input, 1)
    89  }