def day23(): cup_circle = [4, 8, 7, 9, 1, 2, 3, 6, 5] index_current_cup = 0 current_cup = cup_circle[index_current_cup] for _ in range(100): (cup_circle, index_current_cup, current_cup) = cup_round(cup_circle, index_current_cup, current_cup) index_cup_1 = cup_circle.index(1) solution_part_1 = "" for i in range(1, len(cup_circle)): solution_part_1 += str(cup_circle[(index_cup_1 + i) % len(cup_circle)]) print("Solution part1:", solution_part_1) timing.log("Part 1 finished!") cup_circle = [4, 8, 7, 9, 1, 2, 3, 6, 5] cup_circle.extend(range(len(cup_circle) + 1, 1000001)) (current_cup, cup_map) = create_linked_list_and_map(cup_circle) for _ in range(10000000): current_cup = run_cup_round(current_cup, cup_map) solution_part_2 = cup_map[1].next_cup.cup * cup_map[1].next_cup.next_cup.cup print("Solution part2:", solution_part_2)
def day8(): instructions = [] with open(os.path.join(sys.path[0], "inputs/input_day8.txt"), "r") as file: for line in file: (command, number) = line.split(" ") instructions.append((command, number)) (solution_part1, initial_loop_of_instructions) = find_loop_or_end(instructions) print("Solution part1: " + str(solution_part1)) timing.log("Part 1 finished!") for (changed_instruction, (command, number)) in initial_loop_of_instructions: if command in ["jmp", "nop"]: if command == "jmp": instructions[changed_instruction] = ( "nop", instructions[changed_instruction][1]) else: instructions[changed_instruction] = ( "jmp", instructions[changed_instruction][1]) (acc, loop_if_any) = find_loop_or_end(instructions) if not loop_if_any: print("Solution part2: " + str(acc)) break instructions[changed_instruction] = ( command, instructions[changed_instruction][1])
def day15(): numbers = {6: 0, 13: 1, 1: 2, 15: 3, 2: 4, 0: 5} last_number = 0 for index in range(len(numbers), 2019): if last_number in numbers: last_number_index = numbers.get(last_number) numbers[last_number] = index last_number = index - last_number_index else: numbers[last_number] = index last_number = 0 print("Solution part1: ", last_number) timing.log("Part 1 finished!") numbers = {6: 0, 13: 1, 1: 2, 15: 3, 2: 4, 0: 5} last_number = 0 for index in range(len(numbers), 29999999): if last_number in numbers: last_number_index = numbers.get(last_number) numbers[last_number] = index last_number = index - last_number_index else: numbers[last_number] = index last_number = 0 print("Solution part2: ", last_number)
def day7(): bag_contents = {} containers_for_bag = {} with open(os.path.join(sys.path[0], "inputs/input_day7.txt"), "r") as file: for line in file: (bag, contents) = line.rstrip().strip(".").split(" bags contain ") contents = [ ( value.split(" ")[0], value[len(value.split(" ")[0]) + 1::].replace(" bags", "").replace(" bag", "") ) for value in contents.split(", ") ] bag_contents[bag] = contents for (amount, container) in contents: if "no" != amount: if container in containers_for_bag: if bag not in containers_for_bag[container]: containers_for_bag[container].append(bag) else: containers_for_bag[container] = [bag] print("Solution part1: " + str(len(bags_that_can_contain_given_bag("shiny gold", containers_for_bag)))) timing.log("Part 1 finished!") print("Solution part2: " + str(bags_inside_given_bag("shiny gold", bag_contents)))
def day22(): with open(os.path.join(sys.path[0], "inputs/input_day22.txt"), "r") as file: (initial_deck_player_1, initial_deck_player_2) = file.read().rstrip().split("\n\n") initial_deck_player_1 = deque([int(card) for card in initial_deck_player_1.rstrip().split("\n")[1:]]) initial_deck_player_2 = deque([int(card) for card in initial_deck_player_2.rstrip().split("\n")[1:]]) print("Solution part1:", calculate_score(play_regular_game(initial_deck_player_1.copy(), initial_deck_player_2.copy()))) timing.log("Part 1 finished!") print("Solution part2:", calculate_score(play_recursive_game(initial_deck_player_1.copy(), initial_deck_player_2.copy())[1]))
def day19(): rule_map = {} with open(os.path.join(sys.path[0], "inputs/input_day19.txt"), "r") as file: (rules, messages) = file.read().split("\n\n") for rule in rules.rstrip().split("\n"): (rule_id, sub_rules) = rule.rstrip().split(": ") rule_map[int(rule_id)] = [[ sub_rule_element.strip("\"") for sub_rule_element in sub_rule.split(" ") ] for sub_rule in sub_rules.split(" | ")] valid_messages = 0 for message in messages.rstrip().split("\n"): message = message.rstrip() valid_to_index = is_input_valid(message, rule_map, 0, 0) if valid_to_index == (len(message)): valid_messages += 1 print("Solution part1: ", valid_messages) timing.log("Part 1 finished!") valid_messages = 0 for message in messages.rstrip().split("\n"): message = message.rstrip() forty_two_looped = 0 forty_two_success = True valid_to_index = 0 while forty_two_success: new_index = is_input_valid(message, rule_map, valid_to_index, 42) if new_index: valid_to_index = new_index forty_two_looped += 1 else: forty_two_success = False thirty_one_looped = 0 thirty_one_success = True while thirty_one_success: new_index = is_input_valid(message, rule_map, valid_to_index, 31) if new_index: valid_to_index = new_index thirty_one_looped += 1 else: thirty_one_success = False if forty_two_looped > thirty_one_looped > 0 and valid_to_index == len( message): valid_messages += 1 print("Solution part2: ", valid_messages)
def day9(): numbers_parsed = [] with open(os.path.join(sys.path[0], "inputs/input_day9.txt"), "r") as file: for line in file: number_to_parse = int(line.rstrip()) if len(numbers_parsed) >= 25: found_match = False for first_number in range(1, 25): for second_number in range(first_number + 1, 26): if numbers_parsed[ len(numbers_parsed) - first_number] + numbers_parsed[ len(numbers_parsed) - second_number] == number_to_parse: found_match = True break if found_match: break if not found_match: invalid_number = number_to_parse break numbers_parsed.append(number_to_parse) print("Solution part1: " + str(invalid_number)) timing.log("Part 1 finished!") start_range_index = 0 current_sum = numbers_parsed[0] for end_range_index in range(1, len(numbers_parsed)): new_number = numbers_parsed[end_range_index] new_sum = current_sum + new_number while new_sum > invalid_number: old_number = numbers_parsed[start_range_index] new_sum -= old_number start_range_index += 1 if new_sum == invalid_number: list_of_numbers = numbers_parsed[ start_range_index:end_range_index + 1] smallest_number = min(list_of_numbers) largest_number = max(list_of_numbers) result = smallest_number + largest_number break current_sum = new_sum print("Solution part2: " + str(result))
def day24(): floor_map = set() paths = [] with open(os.path.join(sys.path[0], "inputs/input_day24.txt"), "r") as file: for path in file: instructions = [] x = y = 0 path = path.rstrip() path_iter = iter(path) instruction = next(path_iter, None) while instruction: if instruction in ["n", "s"]: instruction += next(path_iter) instructions.append(instruction) (x, y) = coords_from_instruction(x, y, instruction) instruction = next(path_iter, None) if (x, y) in floor_map: floor_map.remove((x, y)) else: floor_map.add((x, y)) paths.append(instructions) print("Solution part1:", len(floor_map)) timing.log("Part 1 finished!") for _ in range(100): new_floor = set() white_tiles_parsed = set() for (x, y) in floor_map: (black_tile_count, neighbours) = get_neighbours(x, y, floor_map) if 0 < black_tile_count <= 2: new_floor.add((x, y)) for neighbour in neighbours: if neighbour not in floor_map and neighbour not in white_tiles_parsed: (black_tile_count, _) = get_neighbours(neighbour[0], neighbour[1], floor_map) if black_tile_count == 2: new_floor.add(neighbour) white_tiles_parsed.add(neighbour) floor_map = new_floor print("Solution part2:", len(floor_map))
def day13(): bus_schedules = [] bus_ids = [] bus_indexes = {} with open(os.path.join(sys.path[0], "inputs/input_day13.txt"), "r") as file: lines = file.readlines() earliest_timestamp = int(lines[0].rstrip()) closest_schedule = 0 smallest_waiting_time = 0 index = 0 for bus_schedule in lines[1].rstrip().split(","): if bus_schedule != "x": bus_schedule = int(bus_schedule) bus_schedules.append((index, bus_schedule)) bus_ids.append(bus_schedule) bus_indexes[bus_schedule] = bus_schedule - index closest_timestamp = find_closest_timestamp_above_given_timestamp( bus_schedule, earliest_timestamp) waiting_time = closest_timestamp - earliest_timestamp if closest_schedule == 0 or waiting_time < smallest_waiting_time: smallest_waiting_time = waiting_time closest_schedule = bus_schedule index += 1 print("Solution part1: " + str(closest_schedule * smallest_waiting_time)) timing.log("Part 1 finished!") bus_ids.sort(reverse=True) current_value = bus_indexes[bus_ids[0]] increment = bus_ids[0] for index in range(1, len(bus_ids)): while current_value % bus_ids[index] != bus_indexes[ bus_ids[index]] % bus_ids[index]: current_value += increment increment *= bus_ids[index] print("Solution part2: ", current_value)
def day14(): memory = {} memory_part_2 = {} mask = "" with open(os.path.join(sys.path[0], "inputs/input_day14.txt"), "r") as file: for line in file: (command, value) = line.rstrip().split(" = ") if command == "mask": mask = value elif "mem" in command: mem_index = int(command[command.index("[") + 1:command.index("]")]) mem_index_binary = '{0:036b}'.format(mem_index) mem_value = '{0:036b}'.format(int(value)) fixed_mem_value = "" for mem_value_index in range(len(mem_value)): if mask[mem_value_index] != "X": fixed_mem_value += mask[mem_value_index] else: fixed_mem_value += mem_value[mem_value_index] memory[mem_index] = fixed_mem_value write_to_address(mem_index_binary, mask, 0, memory_part_2, int(value)) solution_part_1 = 0 for value in memory.values(): solution_part_1 += int(value, base=2) print("Solution part1: ", solution_part_1) timing.log("Part 1 finished!") solution_part_2 = get_all_values_from_memory(memory_part_2) print("Solution part2: ", solution_part_2)
def day11(): seats = [] with open(os.path.join(sys.path[0], "inputs/input_day11.txt"), "r") as file: for line in file: row_values = [] row = line.rstrip() row_length = len(row) for seat in row: row_values.append(seat) seats.append(row_values) old_seat_map = copy.deepcopy(seats) new_seat_map = copy.deepcopy(seats) seat_changed_status = True while seat_changed_status: occupied_seats = 0 seat_changed_status = False for row in range(len(old_seat_map)): for seat in range(row_length): if old_seat_map[row][seat] != '.': adjacent_occupied = count_adjacent_occupied((seat, row), old_seat_map) if old_seat_map[row][seat] == '#' and adjacent_occupied > 3: new_seat_map[row][seat] = "L" seat_changed_status = True elif old_seat_map[row][ seat] == 'L' and adjacent_occupied == 0: new_seat_map[row][seat] = '#' seat_changed_status = True else: new_seat_map[row][seat] = old_seat_map[row][seat] if new_seat_map[row][seat] == '#': occupied_seats += 1 old_seat_map = copy.deepcopy(new_seat_map) print("Solution part1: " + str(occupied_seats)) timing.log("Part 1 finished!") old_seat_map = copy.deepcopy(seats) new_seat_map = copy.deepcopy(seats) seat_changed_status = True while seat_changed_status: occupied_seats = 0 seat_changed_status = False for row in range(len(old_seat_map)): for seat in range(row_length): if old_seat_map[row][seat] != '.': adjacent_occupied = count_nearest_occupied((seat, row), old_seat_map) if old_seat_map[row][seat] == '#' and adjacent_occupied > 4: new_seat_map[row][seat] = "L" seat_changed_status = True elif old_seat_map[row][ seat] == 'L' and adjacent_occupied == 0: new_seat_map[row][seat] = '#' seat_changed_status = True else: new_seat_map[row][seat] = old_seat_map[row][seat] if new_seat_map[row][seat] == '#': occupied_seats += 1 old_seat_map = copy.deepcopy(new_seat_map) print("Solution part2: " + str(occupied_seats))
from assignments import day14 from assignments import day15 from assignments import day16 from assignments import day17 from assignments import day18 from assignments import day19 from assignments import day20 from assignments import day21 from assignments import day22 from assignments import day23 from assignments import day24 from assignments import day25 day1.day1() timing.log("Day 1 finished!") timing.log("Starting day 2!") day2.day2() timing.log("Day 2 finished!") timing.log("Starting day 3!") day3.day3() timing.log("Day 3 finished!") timing.log("Starting day 4!") day4.day4() timing.log("Day 4 finished!")
def day17(): dimension_map = {} four_dimension_map = {} with open(os.path.join(sys.path[0], "inputs/input_day17.txt"), "r") as file: y = 0 for line in file: x = 0 for box in line.rstrip(): if box == "#": dimension_map[(x, y, 0)] = "#" four_dimension_map[(x, y, 0, 0)] = "#" x += 1 y += 1 for _ in range(6): next_iteration = {} memo = set() for (coordinates, box) in dimension_map.items(): (boxes, neighbours) = get_neighbours(dimension_map, coordinates) new_box = parse_box_value(box, boxes) if new_box == "#": next_iteration[coordinates] = new_box memo.add(coordinates) for neighbour in neighbours: if neighbour not in memo: (boxes, _) = get_neighbours(dimension_map, neighbour) neighbour_box = "." if neighbour in dimension_map: neighbour_box = dimension_map[neighbour] new_neighbour_box = parse_box_value(neighbour_box, boxes) if new_neighbour_box == "#": next_iteration[neighbour] = new_neighbour_box memo.add(neighbour) dimension_map = copy.deepcopy(next_iteration) print("Solution part1: ", len(dimension_map)) timing.log("Part 1 finished!") for _ in range(6): next_iteration = {} memo = set() for (coordinates, box) in four_dimension_map.items(): (boxes, neighbours) = get_4d_neighbours(four_dimension_map, coordinates) new_box = parse_box_value(box, boxes) if new_box == "#": next_iteration[coordinates] = new_box memo.add(coordinates) for neighbour in neighbours: if neighbour not in memo: (boxes, _) = get_4d_neighbours(four_dimension_map, neighbour) neighbour_box = "." if neighbour in four_dimension_map: neighbour_box = four_dimension_map[neighbour] new_neighbour_box = parse_box_value(neighbour_box, boxes) if new_neighbour_box == "#": next_iteration[neighbour] = new_neighbour_box memo.add(neighbour) four_dimension_map = copy.deepcopy(next_iteration) print("Solution part2: ", len(four_dimension_map))
def day16(): rule_map = {} range_list = [] invalid_fields = [] valid_tickets = [] with open(os.path.join(sys.path[0], "inputs/input_day16.txt"), "r") as file: (rules, my_ticket, tickets) = file.read().split("\n\n") for rule in rules.rstrip().split("\n"): (command, ranges) = rule.rstrip().split(": ") rule_map[command] = [ tuple([int(bound) for bound in range_rule.split("-")]) for range_rule in ranges.split(" or ") ] range_list.extend(rule_map[command]) my_ticket = [ int(value) for value in my_ticket.rstrip().split("\n")[1].rstrip().split(",") ] valid_tickets.append(my_ticket) for ticket in tickets.rstrip().split("\n")[1:]: valid_ticket = True for value in ticket.rstrip().split(","): value = int(value) invalid = True for (lower_end, upper_end) in range_list: if lower_end <= value <= upper_end: invalid = False break if invalid: invalid_fields.append(value) valid_ticket = False if valid_ticket: valid_tickets.append( [int(value) for value in ticket.rstrip().split(",")]) print("Solution part1: ", sum(invalid_fields)) timing.log("Part 1 finished!") valid_index_for_rule = {} not_valid_index_for_rule = {} for ticket in valid_tickets: for ticket_index in range(len(ticket)): ticket_value = ticket[ticket_index] for field_name in rule_map.keys(): valid_for_field = False for (lower_end, upper_end) in rule_map[field_name]: if lower_end <= ticket_value <= upper_end: valid_for_field = True if valid_for_field and ( field_name not in not_valid_index_for_rule or ticket_index not in not_valid_index_for_rule[field_name]): if field_name in valid_index_for_rule: valid_index_for_rule[field_name].add(ticket_index) else: valid_index_for_rule[field_name] = {ticket_index} elif not valid_for_field: if field_name in valid_index_for_rule and ticket_index in valid_index_for_rule[ field_name]: valid_index_for_rule[field_name].remove(ticket_index) if field_name in not_valid_index_for_rule: not_valid_index_for_rule[field_name].add(ticket_index) else: not_valid_index_for_rule[field_name] = {ticket_index} valid_index_for_rule_sorted_list = list(valid_index_for_rule.items()) valid_index_for_rule_sorted_list.sort(key=sorting) departure_fields = [] solution_part_2 = 1 known_indexes = [] while len(departure_fields) < 6: for (field_name, indexes) in valid_index_for_rule_sorted_list: filtered_indexes = [ index for index in indexes if index not in known_indexes ] if len(filtered_indexes) == 1: known_indexes.append(filtered_indexes[0]) if field_name.startswith("departure"): departure_fields.append(filtered_indexes[0]) solution_part_2 *= my_ticket[filtered_indexes[0]] print("Solution part2: ", solution_part_2)
def day1(): part1() timing.log("Part 1 finished!") part2()
def day20(): images = {} image_borders = {} images_from_border = {} images_from_reverse_border = {} with open(os.path.join(sys.path[0], "inputs/input_day20.txt"), "r") as file: for image in file.read().rstrip().split("\n\n"): image_lines = image.rstrip().split("\n") image_id = int(image_lines[0][5:].strip(":")) image_lines = image_lines[1:] north_border_pixels = image_lines[0] north_border = parse_binary_from_border(north_border_pixels) north_border_reverse = parse_binary_from_border( north_border_pixels[::-1]) add_to_images_from_border_map(images_from_border, north_border, image_id) add_to_images_from_border_map(images_from_reverse_border, north_border_reverse, image_id) east_border_pixels = "".join( [pixels[-1] for pixels in image_lines]) east_border = parse_binary_from_border(east_border_pixels) east_border_reverse = parse_binary_from_border( east_border_pixels[::-1]) add_to_images_from_border_map(images_from_border, east_border, image_id) add_to_images_from_border_map(images_from_reverse_border, east_border_reverse, image_id) south_border_pixels = image_lines[-1] south_border = parse_binary_from_border(south_border_pixels[::-1]) south_border_reverse = parse_binary_from_border( south_border_pixels) add_to_images_from_border_map(images_from_border, south_border, image_id) add_to_images_from_border_map(images_from_reverse_border, south_border_reverse, image_id) west_border_pixels = "".join( [pixels[0] for pixels in image_lines[::-1]]) west_border = parse_binary_from_border(west_border_pixels) west_border_reverse = parse_binary_from_border( west_border_pixels[::-1]) add_to_images_from_border_map(images_from_border, west_border, image_id) add_to_images_from_border_map(images_from_reverse_border, west_border_reverse, image_id) pixels = [[pixel for pixel in pixel_row] for pixel_row in image_lines] images[image_id] = Picture(image_id, (north_border, north_border_reverse), (east_border, east_border_reverse), (south_border, south_border_reverse), (west_border, west_border_reverse), pixels) image_borders[image_id] = { "N": (north_border, north_border_reverse), "E": (east_border, east_border_reverse), "S": (south_border, south_border_reverse), "W": (west_border, west_border_reverse) } total_amount_of_images = len(image_borders) directions = {"N": 0, "E": 1, "S": 2, "W": 3} directions_other_way = {0: "N", 1: "E", 2: "S", 3: "W"} direction_x = {"N": 0, "E": 1, "S": 0, "W": -1} direction_y = {"N": -1, "E": 0, "S": 1, "W": 0} opposite_direction = {"N": "S", "E": "W", "S": "N", "W": "E"} open_borders = {} full_image = {} full_picture_length = int(math.sqrt(len(images))) for (image_id, picture) in images.items(): borders_matched = [] for i in range(4): (border, _) = picture.border_from_direction(directions_other_way[i]) if len(images_from_border[border] ) == 2 or border in images_from_reverse_border: borders_matched.append(i) if len(borders_matched) == 2: rotation = (borders_matched[0] - borders_matched[1] + 4) % 4 if rotation == 1: left_most_border = borders_matched[1] elif rotation == 3: left_most_border = borders_matched[0] picture.rotate((1 - left_most_border + 4) % 4) open_borders = { (0, 0, "N"): picture.border_from_direction("N"), (0, 0, "E"): picture.border_from_direction("E"), (0, 0, "S"): picture.border_from_direction("S"), (0, 0, "W"): picture.border_from_direction("W") } full_image = {(0, 0): picture} break while len(full_image) != total_amount_of_images: for (border_id, border) in open_borders.items(): (x, y, direction) = border_id image_to_match_border_x = x + direction_x[direction] image_to_match_border_y = y + direction_y[direction] matching_images = 0 if 0 <= image_to_match_border_x < full_picture_length and 0 <= image_to_match_border_y < full_picture_length: matching_border_found = False for image_to_match in images.values(): if image_to_match not in full_image.values(): if image_to_match.direction_that_matches(border[0]): all_directions_match = True for direction_matcher in directions.keys(): if ( image_to_match_border_x + direction_x[direction_matcher], image_to_match_border_y + direction_y[direction_matcher], opposite_direction[direction_matcher] ) in open_borders and not image_to_match.direction_that_matches( open_borders[ (image_to_match_border_x + direction_x[direction_matcher], image_to_match_border_y + direction_y[direction_matcher], opposite_direction[ direction_matcher])][0]): all_directions_match = False break if all_directions_match: matching_image = image_to_match matching_images += 1 if matching_images == 1: matching_image.transmute_to_match(direction, border[0]) full_image[(image_to_match_border_x, image_to_match_border_y)] = matching_image matching_border_found = True break if matching_border_found: for direction in directions.keys(): opposing_border_x = image_to_match_border_x + direction_x[ direction] opposing_border_y = image_to_match_border_y + direction_y[ direction] opposing_border = (opposing_border_x, opposing_border_y, opposite_direction[direction]) if opposing_border in open_borders: del open_borders[opposing_border] elif 0 <= opposing_border_x < full_picture_length and 0 <= opposing_border_y < full_picture_length: open_borders[( image_to_match_border_x, image_to_match_border_y, direction )] = matching_image.border_from_direction(direction) solution_part1 = full_image[(0, 0)].picture_id * full_image[ (0, full_picture_length - 1)].picture_id * full_image[ (full_picture_length - 1, 0)].picture_id * full_image[ (full_picture_length - 1, full_picture_length - 1)].picture_id print("Solution part1: ", solution_part1) timing.log("Part 1 finished!") pixels = [] for picture_y in range(full_picture_length): for picture_x in range(full_picture_length): if picture_x == 0: pixels.extend(full_image[(picture_x, picture_y)].pixels) else: pixels_from_picture = full_image[(picture_x, picture_y)].pixels for pixel_y in range(len(pixels_from_picture)): pixels[(picture_y * len(pixels_from_picture)) + pixel_y].extend(pixels_from_picture[pixel_y]) full_picture = Picture(1, (0, 0), (0, 0), (0, 0), (0, 0), pixels) nessy = [(0, 1), (1, 2), (4, 2), (5, 1), (6, 1), (7, 2), (10, 2), (11, 1), (12, 1), (13, 2), (16, 2), (17, 1), (18, 0), (18, 1), (19, 1)] full_picture_length = len(full_picture.pixels_with_borders) nessy_orientation = False rotation_count = 0 flipped_x = False flipped_y = False nessys_found = 0 while not nessy_orientation: modified_picture = copy.deepcopy(full_picture.pixels_with_borders) for y in range(full_picture_length - 2): for x in range(full_picture_length - 19): nessy_found = True for nessy_coord in nessy: if full_picture.pixels_with_borders[y + nessy_coord[1]][ x + nessy_coord[0]] != "#": nessy_found = False break if nessy_found: nessys_found += 1 nessy_orientation = True for nessy_coord in nessy: modified_picture[y + nessy_coord[1]][x + nessy_coord[0]] = "O" if not nessy_orientation: if rotation_count == 3 and not flipped_x: full_picture.flip_x() rotation_count = 0 flipped_x = True elif rotation_count == 3 and not flipped_y: full_picture.flip_y() rotation_count = 0 flipped_y = True elif rotation_count == 3: break else: full_picture.rotate(1) rotation_count += 1 rough_water_count = 0 for y in range(full_picture_length): for x in range(full_picture_length): if modified_picture[y][x] == "#": rough_water_count += 1 print("Solution part2: ", rough_water_count)