package main import ( "bufio" "fmt" "os" "sort" "time" ) func main() { start := time.Now() partOne() duration := time.Since(start) partTwo() duration2 := time.Since(start) fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration) } type boardingPass struct { passID string row int seat int id int } func parsePassID(s string) (int, int) { bottom := 0 top := 127 left := 0 right := 7 for _, r := range s { switch { case r == 'F': top = ((top - bottom - 1) / 2) + bottom case r == 'B': bottom = (top + bottom + 1) / 2 case r == 'L': right = ((right - left - 1) / 2) + left case r == 'R': left = (left + right + 1) / 2 } } return top, left } // Instead of zones or groups, this airline uses binary space partitioning to seat people. // A seat might be specified like FBFBBFFRLR, where F means "front", B means "back", L means "left", and R means "right". // Every seat also has a unique seat ID: multiply the row by 8, then add the column. // Here are some other boarding passes: // BFFFBBFRRR: row 70, column 7, seat ID 567. // FFFBBBFRRR: row 14, column 7, seat ID 119. // BBFFBBFRLL: row 102, column 4, seat ID 820. // As a sanity check, look through your list of boarding passes. What is the highest seat ID on a boarding pass? func partOne() { f, _ := os.Open("input") reader := bufio.NewReader(f) scanner := bufio.NewScanner(reader) maxID := 0 for scanner.Scan() { line := scanner.Text() row, column := parsePassID(line) if (row*8)+column > maxID { maxID = (row * 8) + column } } fmt.Println(maxID) } // It's a completely full flight, so your seat should be the only missing boarding pass in your list. // However, there's a catch: some of the seats at the very front and back of the plane don't exist on this aircraft, so they'll be missing from your list as well. // Your seat wasn't at the very front or back, though; the seats with IDs +1 and -1 from yours will be in your list. func partTwo() { f, _ := os.Open("input") reader := bufio.NewReader(f) scanner := bufio.NewScanner(reader) passes := []boardingPass{} for scanner.Scan() { line := scanner.Text() row, column := parsePassID(line) passes = append(passes, boardingPass{ passID: line, row: row, seat: column, id: (row * 8) + column, }) } sort.Slice(passes, func(i, j int) bool { return passes[i].id < passes[j].id }) for i, s := range passes { if i != 0 && passes[i-1].id != s.id-1 { fmt.Println(s.id - 1) } } }