--- Day 1: Sonar Sweep ---

Click here, to go to the challenge.

Python

in_list = [int(i_str) for i_str in day1_input.strip().split("\n")]

def part_one(input):
  return len([x for i,x in enumerate(input) if i > 0 and x > input[i-1] ])

def part_two(input):
  last_win = sys.maxsize
  i = 0
  c = 0
  while i < len(input)-2:
    win = sum([input[i],input[i+1],input[i+2]])
    if win > last_win:
      c+=1
    last_win = win
    i+= 1
  return c

print("Part 1: ", part_one(in_list))
print("Part 2: ", part_two(in_list))

--- Day 2: Dive! ---

Click here, to go to the challenge.

Python

in_list = [(li[0],int(li[1])) for li in [i_str.split(" ")
                      for i_str in day2_input.strip().split("\n")]]

def part_one(input):
  down = sum(j for i, j in in_list if i == 'down')
  up = sum(j for i, j in in_list if i == 'up')
  horizontal = sum(j for i, j in in_list if i == 'forward')
  return (down - up) * horizontal

def part_two(input):
  aim = 0
  horizontal = 0
  depth = 0
  for com in input:
    aim += com[1] if com[0] == 'down' else - com[1] if com[0] == 'up' else 0
    depth += (com[1] * aim ) if com[0] == 'forward' else 0
    horizontal += com[1] if com[0] == 'forward' else 0
  return horizontal*depth

print("Part 1: ", part_one(in_list))
print("Part 2: ", part_two(in_list))

--- Day 3: Binary Diagnostic ---

Click here, to go to the challenge.

Java

public abstract class Day03 {

    public static final String realInput = InputFetcher.getInput(2021, 3);

    public static long partOne(String inStr) {
        StringBuilder gamma = new StringBuilder();
        StringBuilder epsilon = new StringBuilder();
        int[][] input = prepareInput(inStr);
        for (int i = 0; i < input[0].length; i++) {
            int zero = 0, one = 0;
            for (int[] ints : input) {
                if (ints[i] == 0) zero += 1;
                else one += 1;
            }
            gamma.append(zero > one ? 0 : 1);
            epsilon.append(zero > one ? 1 : 0);
        }
        return Long.parseLong(gamma.toString(), 2) * Long.parseLong(epsilon.toString(), 2);
    }

    public static long partTwo(String inStr) {
        return filterForGasLeve("oxygen", inStr) * filterForGasLeve("co2", inStr);
    }

    private static long filterForGasLeve(String gas, String inStr) {
        List<int[]> input = Arrays.asList(prepareInput(inStr));
        for (int i = 0; i < input.get(0).length; i++) {
            int zero = 0, one = 0;
            for (int[] ints : input) {
                if (ints[i] == 0) zero += 1;
                else one += 1;
            }
            final int checker = gas.equals("oxygen") ? (one >= zero ? 1 : 0) : (zero <= one ? 0 : 1);
            final int finalI = i;
            input = input.stream().filter(arr -> arr[finalI] == checker).collect(Collectors.toList());
            if (input.size() == 1) break;
        }
        return Long.parseLong(
                Arrays.stream(input.get(0))
                        .mapToObj(String::valueOf)
                        .collect(Collectors.joining()),2
        );
    }

    private static int[][] prepareInput(String inStr) {
        return Arrays.stream(inStr.split("\n"))
                .map(str -> Arrays.stream(str.split(""))
                        .mapToInt(Integer::parseInt)
                        .toArray()).toArray(int[][]::new);
    }
}

--- Day 4: Giant Squid ---

Click here, to go to the challenge.

Java

public abstract class Day04 {

    @Getter
    @AllArgsConstructor
    private static class BingoInput {
        private List<Integer> calls;
        private List<int[][]> boards;
    }

    @Getter
    @NoArgsConstructor
    private static class BingoOutput {
        private final List<List<Integer>> callsForNow = new ArrayList<>();
        private final List<int[][]> winnerBoards = new ArrayList<>();
    }

    public static final String realInput = InputFetcher.getInput(2021, 4);

    public static long partOne(String inStr) {
        BingoInput bingoInput = prepareInput(inStr);
        BingoOutput out = playBingo(bingoInput);
        return (long) out.getCallsForNow().get(0).get(out.getCallsForNow().get(0).size() - 1) *
                Arrays.stream(out.getWinnerBoards().get(0))
                        .flatMapToInt(IntStream::of)
                        .filter(pos -> !out.getCallsForNow().get(0).contains(pos))
                        .sum();
    }

    public static long partTwo(String inStr) {
        BingoInput bingoInput = prepareInput(inStr);
        BingoOutput out = playBingo(bingoInput);
        int last = out.getCallsForNow().size() - 1;
        return (long) out.getCallsForNow().get(last).get(out.getCallsForNow().get(last).size() - 1) *
                Arrays.stream(out.getWinnerBoards().get(last))
                        .flatMapToInt(IntStream::of)
                        .filter(pos -> !out.getCallsForNow().get(last).contains(pos))
                        .sum();
    }

    private static BingoOutput playBingo(BingoInput bingoInput) {
        BingoOutput out = new BingoOutput();
        for (int round = 0; round < bingoInput.calls.size(); round++) {
            List<Integer> callsForNow = bingoInput.calls.subList(0, round);
            bingoInput.boards.forEach(board -> {
                        for (int idx = 0; idx < board.length; idx++) {
                            final int finalIdx = idx;
                            if (callsForNow.containsAll(Arrays.stream(board[finalIdx])
                                    .boxed()
                                    .collect(Collectors.toList())) ||
                                    callsForNow.containsAll(Arrays.stream(board)
                                            .mapToInt(ints -> ints[finalIdx])
                                            .boxed()
                                            .collect(Collectors.toList()))) {
                                out.getCallsForNow().add(new ArrayList<>(callsForNow));
                                out.getWinnerBoards().add(board);
                            }
                        }
                    });
            bingoInput.boards.removeAll(out.getWinnerBoards());
        }
        return out;
    }

    private static BingoInput prepareInput(String inStr) {
        String[] inBlocks = inStr.split("\n\n");
        return new BingoInput(Arrays.stream(inBlocks[0].split(","))
                .mapToInt(Integer::parseInt)
                .boxed()
                .collect(Collectors.toList()),
                Arrays.stream(inBlocks)
                        .skip(1)
                        .map(block -> Arrays.stream(block.split("\n"))
                                .map(str -> Arrays.stream(str.trim().split("\\s+"))
                                        .mapToInt(Integer::parseInt)
                                        .toArray())
                                .toArray(int[][]::new))
                        .collect(Collectors.toList()));
    }
}

--- Day 9: Smoke Basin ---

Click here, to go to the challenge.

Java

public abstract class Day09 {

    public static final String inputString = InputFetcher.getInput(2021, 9);

    public static long partOne(String inStr) {
        long out = 0;
        int[][] map = generateInput(inStr);
        for (int[] cord : getLowsCords(map)) {
            out += map[cord[1]][cord[0]] + 1;
        }
        return out;
    }

    public static long partTwo(String inStr) {
        int[][] map = generateInput(inStr);
        List<int[]> cords = getLowsCords(map);
        return cords
                .stream()
                .map(cord -> flood(9, cord[0], cord[1], map))
                .sorted(Comparator.reverseOrder())
                .limit(3)
                .reduce(1, (a, b) -> a * b);
    }

    private static int flood(int border, int x, int y, int[][] map) {
        int out = 0;
        if (map[y][x] != border) {
            out++;
            map[y][x] = border;
            if (x - 1 > -1) out += flood(border, x - 1, y, map);
            if (x + 1 < map[y].length) out += flood(border, x + 1, y, map);
            if (y - 1 > -1) out += flood(border, x, y - 1, map);
            if (y + 1 < map.length) out += flood(border, x, y + 1, map);
        }
        return out;
    }

    private static List<int[]> getLowsCords(int[][] map) {
        List<int[]> out = new ArrayList<>();
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[i].length; j++) {
                if ((i - 1 < 0 || map[i - 1][j] > map[i][j]) &&
                        (j - 1 < 0 || map[i][j - 1] > map[i][j]) &&
                        (i + 1 == map.length || map[i + 1][j] > map[i][j]) &&
                        (j + 1 == map[i].length || map[i][j + 1] > map[i][j])) {
                    out.add(new int[]{j, i});
                }
            }
        }
        return out;
    }

    private static int[][] generateInput(String inStr) {
        return Arrays
                .stream(inStr.split("\n"))
                .map(str -> Arrays
                        .stream(str.split(""))
                        .mapToInt(Integer::parseInt)
                        .toArray()).toArray(int[][]::new);
    }
}

--- Day 10: Syntax Scoring ---

Click here, to go to the challenge.

Java

public abstract class Day10 {

    public static final String realInput = InputFetcher.getInput(2021, 10);

    private static final Map<Character, Integer> errorPoints = Map.of(
            ')', 3,
            ']', 57,
            '}', 1197,
            '>', 25137
    );
    private static final Map<Character, Integer> closePoints = Map.of(
            ')', 1,
            ']', 2,
            '}', 3,
            '>', 4
    );
    private static final List<Character> openings = Arrays.asList('(', '{', '[', '<');
    private static final List<Character> closings = Arrays.asList(')', '}', ']', '>');

    public static long partOne(String inStr) {
        long out = 0;
        for (char[] input : prepareInput(inStr)) {
            List<Character> opens = new ArrayList<>();
            for (Character c : input) {
                if (openings.contains(c))
                    opens.add(c);
                else if (closings.contains(c)) {
                    if (opens.get(opens.size() - 1).compareTo(openings.get(closings.indexOf(c))) == 0) {
                        opens.remove(opens.size() - 1);
                    } else {
                        out += errorPoints.get(c);
                        break;
                    }
                }
            }
        }
        return out;
    }

    public static long partTwo(String inStr) {
        List<Long> scores = new ArrayList<>();
        for (char[] input : prepareInput(inStr)) {
            List<Character> opens = new ArrayList<>();
            for (int i = 0; i < input.length; i++) {
                char c = input[i];
                if (openings.contains(c)) opens.add(c);
                else if (closings.contains(c)) {
                    if (opens.get(opens.size() - 1).compareTo(openings.get(closings.indexOf(c))) == 0) {
                        opens.remove(opens.size() - 1);
                    } else break;
                }
                if (i == input.length - 1 && opens.size() > 0) {
                    long lineScore = 0;
                    Collections.reverse(opens);
                    for (Character open : opens) {
                        lineScore = lineScore * 5 + closePoints.get(closings.get(openings.indexOf(open)));
                    }
                    scores.add(lineScore);
                }
            }
        }
        return scores.stream().sorted().collect(Collectors.toList()).get((scores.size() - 1) / 2);
    }

    private static List<char[]> prepareInput(String inStr) {
        return Arrays.stream(inStr.split("\n"))
                .map(String::toCharArray)
                .collect(Collectors.toList());
    }
}