package main import ( "bufio" "fmt" "io" "log" "math" "os" "strings" ) type Seat string func half(chain string, size int, lower rune, upper rune) int { rowPart := chain[0:int(math.Log2(float64(size)))] half := size / 2 row := 0 for _, c := range rowPart { switch c { case lower: case upper: row += half default: panic("wrong letter") } half /= 2 } return row } func (s Seat) Row() int { return half(string(s[0:7]), 128, 'F', 'B') } func (s Seat) Col() int { return half(string(s[7:10]), 8, 'L', 'R') } func (s Seat) ID() int { return (s.Row() * 8) + s.Col() } func (s Seat) String() string { return fmt.Sprintf("row %d, col %d, ID %d", s.Row(), s.Col(), s.ID()) } func main() { // I'm lazy and need this done quick seats := map[int]Seat{} f, err := os.Open("input") if err != nil { panic(err) } r := bufio.NewReader(f) for { line, err := r.ReadString('\n') if err == io.EOF { break } if err != nil { panic(err) } line = strings.TrimSpace(line) seat := Seat(line) seatID := seat.ID() seats[seatID] = seat } // skip row 0 and row 127 for seatID := 8; seatID < (128-1)*8; seatID++ { // has ID + 1 and ID - 1? if _, exists := seats[seatID]; !exists { if _, hasSeatIDPlus1 := seats[seatID+1]; hasSeatIDPlus1 { if _, hasSeatIDMinus1 := seats[seatID-1]; hasSeatIDMinus1 { log.Printf("Matching seat ID: %d", seatID) } } } } }