Advent of Code 2023: Day 2: Cube Conundrum

Страшный, длинный, мучительный парсинг ввода…Хотелось бы, конечно, иметь возможность сделать по-перловому, что-то типа: echo -e "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green\nGame 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue" | perl -wlne '@matches = $_ =~ /(?:\G(?!\A)|^Game) (\S+)/g; print join("=",@matches)'

Немного почистить после, или сразу докрутить регулярку, чтобы не захватывала разделители. Сложить в хэш. И закончить кучей циклов в итоге 🙁

С другой стороны – и возня с java Matcher не вдохновляла, и описывать структуру в виде POJO – для чисто скриптового решения – зачем.

split – дёшево и сердито, fastpath бонусом. К счастью – ввод был одинаков для обеих частей загадки.

// Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green static void day2(String puzzleInputUri) throws IOException, InterruptedException { Map<String, Integer> bagOfCubes = Map.of("red", 12, "green", 13, "blue", 14); var games = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body() .map(game -> game.split(":", 2)) .map(idAndResults -> Map.entry( idAndResults[0].split(" ", 2)[1], // game id idAndResults[1] // results string )) .map(idAndResults -> Map.entry(idAndResults.getKey(), idAndResults.getValue().split(";"))) .map(idAndResults -> { List<Map<String, Integer>> parsedResults = new ArrayList<>(); for (String s : idAndResults.getValue()) { Map<String, Integer> cubesCount = new HashMap<>(); for (String s1 : s.split(",")) { String[] cubeCount = s1.trim().split(" ", 2); cubesCount.put(cubeCount[1].trim(), Integer.parseInt(cubeCount[0].trim())); } parsedResults.add(cubesCount); } return Map.entry(idAndResults.getKey(), parsedResults); }) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); var answer1 = games.entrySet().stream() .filter(idAndResults -> idAndResults.getValue().stream() .flatMap(it -> it.entrySet().stream()) .noneMatch(result -> result.getValue() > bagOfCubes.get(result.getKey())) ) .mapToInt(idAndResults -> Integer.parseInt(idAndResults.getKey())) .sum(); var answer2 = games.entrySet().stream() .map(idAndResults -> Map.entry( idAndResults.getKey(), idAndResults.getValue().stream() .reduce((m1, m2) -> { Map<String, Integer> minRequired = new HashMap<>(); bagOfCubes.keySet().forEach(cube -> minRequired.put(cube, Math.max(m1.getOrDefault(cube, 0), m2.getOrDefault(cube, 0)) )); return minRequired; }).orElseThrow() ) ) .mapToInt(idAndMinRequired -> idAndMinRequired.getValue().values().stream() .reduce((v1, v2) -> v1 * v2).orElseThrow() // v != 0 ? v : 1 ) .sum(); System.out.println(answer1); System.out.println(answer2); }

Вид этой портянки мне не особо мил, особенно for внутри (mapMulti взамен?). Но и как-то значимо “облагородить” её не удалось с ходу – получалась куча менее понятных map, происходящее в которых сложно осознать уже через пару десятков минут.

А часики тикают, задачи требуют решений – и пора двигаться дальше!

849849 показов
2323 открытия
Начать дискуссию