package aoc import ( "os" "io" "errors" "bufio" "strings" "strconv" ) type Field struct { Marked bool Value int } type Board struct { Fields [5][5]Field Completed bool } const ( READ_NUMBERS = 0 READ_BOARD = 1 ) func strs_to_ints(num_strs []string) []int { var numbers []int for _, num_str := range num_strs { i, _ := strconv.Atoi(num_str) numbers = append(numbers, i) } return numbers } func ReadFile(path string) ([]int, []Board, error) { file, err := os.Open(path) defer file.Close() if err != nil { return nil, nil, err } reader := bufio.NewReader(file) var state = READ_NUMBERS var numbers []int var boards []Board var cur_fields [5][5]Field var row_idx = 0 reader:for { line, err := reader.ReadString('\n') var end_of_file = errors.Is(err, io.EOF) if err != nil && !end_of_file { break } var state_change = line == "\n" || end_of_file line = strings.TrimRight(line, "\n") switch state { case READ_NUMBERS: if state_change { state = READ_BOARD continue } var num_strs = strings.Split(line, ",") numbers = strs_to_ints(num_strs) case READ_BOARD: if state_change { var board = Board{Fields: cur_fields, Completed: false} boards = append(boards, board) row_idx = 0 if end_of_file { break reader } continue } var num_strs = strings.Fields(line) for col_idx, value := range strs_to_ints(num_strs) { cur_fields[row_idx][col_idx] = Field{Value: value, Marked: false} } row_idx += 1 } } return numbers, boards, nil } func check_row(i int, board *Board) bool { for _, field := range board.Fields[i] { if !field.Marked { return false } } return true } func check_col(j int, board *Board) bool { for _, row := range board.Fields { if !row[j].Marked { return false } } return true } func MarkBoard(board *Board, number int) bool { for i, row := range board.Fields { for j, _ := range row { var field = &board.Fields[i][j] if field.Value == number { field.Marked = true if check_row(i, board) || check_col(j, board) { return true } } } } return false }