Архив рубрики: Новости

Advent of Code 2022: Day 6

Решение для шестого дня получилось коротким, простым, универсальным (применительно к загадке).

И, я уверен, — глубоко неоптимальным при этом :). Зато — алгоритмически это было, пожалуй, проще загадок всех предыдущих дней.

Но оно сработало, что полностью соответствует духу викторины. Для первой части загадки markerSize = 4, для части два — markerSize = 14.

static void day6(String puzzleInputUri) throws IOException, InterruptedException {
    int markerSize = 14;
    Set<Byte> buffer = new HashSet<>();
    byte[] message = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofByteArray()).body();
    for (int i = 0; i < message.length - markerSize; i++) {
        for (int j = i; j < i + markerSize; j++) {
            buffer.add(message[j]);
        }
        if (buffer.size() == markerSize) {
            System.out.println(i + markerSize);
            break;
        }
        buffer.clear();
    }
}
Исходные данные: https://adventofcode.com/2022/day/6/input

Advent of Code 2022: Day 5

Добрался до пятого дня AoC. Вообще, по ощущениям, сами алгоритмы пока становятся проще от задачи к задаче. А вот пред-обработка исходных данных начинает требовать времени.

Начальное состояние склада просто захардкодил, слегка покрутив в Calc (для бо́льшего удобства копипаста). В конце заметки приведу некоторые подробности.

Поскольку мутируются стеки ящиков «на месте» — для корректного решения второй части приходится использовать копию начального состояния склада.

static void day5(String puzzleInputUri) throws IOException, InterruptedException {
/*
                [V]     [C]     [M]
[V]     [J]     [N]     [H]     [V]
[R] [F] [N]     [W]     [Z]     [N]
[H] [R] [D]     [Q] [M] [L]     [B]
[B] [C] [H] [V] [R] [C] [G]     [R]
[G] [G] [F] [S] [D] [H] [B] [R] [S]
[D] [N] [S] [D] [H] [G] [J] [J] [G]
[W] [J] [L] [J] [S] [P] [F] [S] [L]
 1   2   3   4   5   6   7   8   9
*/
    Stack<String> stack1 = new Stack<>();
    stack1.addAll(List.of("W","D","G","B","H","R","V"));
    Stack<String> stack2 = new Stack<>();
    stack2.addAll(List.of("J","N","G","C","R","F"));
    Stack<String> stack3 = new Stack<>();
    stack3.addAll(List.of("L","S","F","H","D","N","J"));
    Stack<String> stack4 = new Stack<>();
    stack4.addAll(List.of("J","D","S","V"));
    Stack<String> stack5 = new Stack<>();
    stack5.addAll(List.of("V","S","H","D","R","Q","W","N","V"));
    Stack<String> stack6 = new Stack<>();
    stack6.addAll(List.of("P","G","H","C","M"));
    Stack<String> stack7 = new Stack<>();
    stack7.addAll(List.of("C","F","J","B","G","L","Z","H","C"));
    Stack<String> stack8 = new Stack<>();
    stack8.addAll(List.of("S","J","R"));
    Stack<String> stack9 = new Stack<>();
    stack9.addAll(List.of("M","L","G","S","R","B","N","V","M"));

    Map<Integer, Stack<String>> wareHousePartOne = new TreeMap<>(Map.of(
        1, stack1, 2, stack2, 3, stack3, 4, stack4,
        5, stack5, 6, stack6, 7, stack7, 8, stack8,
        9, stack9
    ));

    Map<Integer, Stack<String>> wareHousePartTwo = new TreeMap<>();
    wareHousePartOne.forEach((stackN, stack) -> {
        var wh2Stack = new Stack<String>();
        wh2Stack.addAll(stack);
        wareHousePartTwo.put(stackN, wh2Stack);
    });

    client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .dropWhile(s -> !s.contains("move"))
        .map(s -> s.split(" "))
        .forEach(action -> {
            int count = Integer.parseInt(action[1]);
            int fromStack = Integer.parseInt(action[3]);
            int toStack = Integer.parseInt(action[5]);
            for (int i = 0; i < count; i++) {
                String crate = wareHousePartOne.get(fromStack).pop();
                wareHousePartOne.get(toStack).push(crate);
            }
        });
    StringBuilder upperCrates = new StringBuilder();
    wareHousePartOne.values().forEach(stack -> upperCrates.append(stack.pop()));
    System.out.println(upperCrates);

    client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .dropWhile(s -> !s.contains("move"))
        .map(s -> s.split(" "))
        .forEach(action -> {
            int count = Integer.parseInt(action[1]);
            int fromStack = Integer.parseInt(action[3]);
            int toStack = Integer.parseInt(action[5]);
            List<String> cratesBuffer = new ArrayList<>();
            for (int i = 0; i < count; i++) {
                cratesBuffer.add(wareHousePartTwo.get(fromStack).pop());
            }
            Collections.reverse(cratesBuffer);
            cratesBuffer.forEach(crate -> wareHousePartTwo.get(toStack).push(crate));
        });
    StringBuilder upperCratesPartTwo = new StringBuilder();
    wareHousePartTwo.values().forEach(stack -> upperCratesPartTwo.append(stack.pop()));
    System.out.println(upperCratesPartTwo);
}

Либо — просто между вызовами для решения разных частей — поменять внутрянку перестановки ящиков:

List<String> cratesBuffer = new ArrayList<>();
for (int i = 0; i < count; i++) {
    cratesBuffer.add(wareHouse.get(fromStack).pop());
}
Collections.reverse(cratesBuffer);
cratesBuffer.forEach(crate -> wareHouse.get(toStack).push(crate));
Исходные данные: https://adventofcode.com/2022/day/5/input
Читать далее Advent of Code 2022: Day 5

Advent of Code 2022: Day 4

Задачка, предложенная на четвёртом дне, снова показалась проще предыдущей. Если так пойдёт и дальше — можно успеть нагнать календарь и начать двигаться размеренно, по штуке в день.

Получилось так, что решается она практически целиком — копипастом решения первой половины во вторую (за исключением последнего .map. На циклах можно и не копипастить, пожалуй, но уже сделано так.

Главное — есть верный ответ!

static void day4(String puzzleInputUri) throws IOException, InterruptedException {
    var resultPartOne = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .map(pair -> pair.split(","))
        .map(tasks -> {
            String[] taskOneBounds = tasks[0].split("-");
            String[] taskTwoBounds = tasks[1].split("-");
            return Map.entry(
                Map.entry(Integer.parseInt(taskOneBounds[0]), Integer.parseInt(taskOneBounds[1])),
                Map.entry(Integer.parseInt(taskTwoBounds[0]), Integer.parseInt(taskTwoBounds[1]))
            );
        })
        .map(tasks -> Map.entry(
            IntStream.rangeClosed(tasks.getKey().getKey(), tasks.getKey().getValue()).boxed().collect(Collectors.toSet()),
            IntStream.rangeClosed(tasks.getValue().getKey(), tasks.getValue().getValue()).boxed().collect(Collectors.toSet())
        ))
        .map(tasks -> {
            var task1 = new HashSet<>(tasks.getKey());
            var task2 = new HashSet<>(tasks.getValue());
            task1.removeAll(task2);
            tasks.getValue().removeAll(tasks.getKey());
            return task1.isEmpty() || tasks.getValue().isEmpty();
        })
        .filter(included -> included)
        .count();
    System.out.println(resultPartOne);

    var resultPartTwo = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .map(pair -> pair.split(","))
        .map(tasks -> {
            String[] taskOneBounds = tasks[0].split("-");
            String[] taskTwoBounds = tasks[1].split("-");
            return Map.entry(
                Map.entry(Integer.parseInt(taskOneBounds[0]), Integer.parseInt(taskOneBounds[1])),
                Map.entry(Integer.parseInt(taskTwoBounds[0]), Integer.parseInt(taskTwoBounds[1]))
            );
        })
        .map(tasks -> Map.entry(
            IntStream.rangeClosed(tasks.getKey().getKey(), tasks.getKey().getValue()).boxed().collect(Collectors.toSet()),
            IntStream.rangeClosed(tasks.getValue().getKey(), tasks.getValue().getValue()).boxed().collect(Collectors.toSet())
        ))
        .map(tasks -> tasks.getKey().stream().anyMatch(taskN -> tasks.getValue().contains(taskN))
            || tasks.getValue().stream().anyMatch(taskN -> tasks.getKey().contains(taskN))
        )
        .filter(cross -> cross)
        .count();
    System.out.println(resultPartTwo);
}
Исходные данные: https://adventofcode.com/2022/day/4/input

Advent of Code 2022: Day 3

Первая часть задачки из третьего дня оказалась неожиданно простой в решении. По ощущениям — проще заданий дня второго.

А вот во второй пришлось вернуться к корням 🙂 Через стрим получался этакий монстроузорный коллектор для группировки по три строки, что ну его на фиг. Через циклы тоже не конфетка, но тут этого и не нужно. Ответ — есть!

static void day3(String puzzleInputUri) throws IOException, InterruptedException {
    int lowerCaseOffset = 96;
    int upperCaseOffset = 38;

    var resultPartOne = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines())
        .body()
        .map(backpack -> Map.entry(
            Arrays.stream(backpack.substring(0, backpack.length() / 2)
                .split("")).collect(Collectors.toSet()),
            Arrays.stream(backpack.substring(backpack.length() / 2)
                .split("")).collect(Collectors.toSet())
        ))
        .map(pockets -> {
            pockets.getKey().retainAll(pockets.getValue());
            return pockets.getKey();
        })
        .flatMap(Collection::stream)
        .mapToInt(item -> {
            int charCode = item.codePointAt(0);
            return Character.isUpperCase(charCode)
                ? charCode - upperCaseOffset
                : charCode - lowerCaseOffset;
        })
        .sum();
    System.out.println(resultPartOne);

    List<String> src = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines())
        .body().collect(Collectors.toList());
    Integer resultPartTwo = 0;
    Map<String, Integer> groupOfThree = new HashMap<>();
    for (String backpack : src) {
        if (!groupOfThree.containsValue(3)) {
            for (String item : Arrays.stream(backpack.split("")).collect(Collectors.toSet())) {
                groupOfThree.merge(item, 1, Integer::sum);
            }
        }
        if (groupOfThree.containsValue(3)) {
            resultPartTwo += groupOfThree.entrySet().stream()
                .filter(e -> e.getValue() == 3)
                .map(Entry::getKey)
                .mapToInt(item -> {
                    int charCode = item.codePointAt(0);
                    return Character.isUpperCase(charCode)
                        ? charCode - upperCaseOffset
                        : charCode - lowerCaseOffset;
                })
                .sum();
            groupOfThree = new HashMap<>();
        }
    }
    System.out.println(resultPartTwo);
}
Исходные данные: https://adventofcode.com/2022/day/3/input

Advent of Code 2022: Day 2

Задачка второго дня оказалась повариативней, пришлось искать отдельные решения для первой и второй частей.

Тем не менее — они были найдены, а ответы — получены. Как обычно — решение в виде функции запускается в jshell.

static void day2(String puzzleInputUri) throws IOException, InterruptedException {
/*
rock: A, X
scissors: C, Z
paper:  B, Y
*/
    Map<String, Integer> choiceCosts = Map.of("X", 1, "Y", 2, "Z", 3);
    Map<Integer, Set<String>> strategyCosts = Map.of(
        6, Set.of("A Y", "C X", "B Z"), //win
        3, Set.of("A X", "C Z", "B Y"), //draw
        0, Set.of("A Z", "C Y", "B X") //lose
    );
    Map<String, Set<String>> strategyMappingPartTwo = Map.of(
        "X", strategyCosts.get(0), //lose
        "Y", strategyCosts.get(3), //draw
        "Z", strategyCosts.get(6) //win
    );

    int totalPartOne = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .map(round -> Map.entry(round,
            strategyCosts.entrySet().stream().mapToInt(entry -> entry.getValue().contains(round) ? entry.getKey() : 0).sum())
        )
        .mapToInt(roundWithCost -> {
            String choice = roundWithCost.getKey().split(" ")[1];
            return roundWithCost.getValue() + choiceCosts.get(choice);
        })
        .sum();
    System.out.println(totalPartOne);

    int totalPartTwo = client.send(request.uri((URI.create(puzzleInputUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .map(round -> round.split(" "))
        .map(choiceAndStrategy -> strategyMappingPartTwo.get(choiceAndStrategy[1]).stream()
            .filter(strategies -> strategies.contains(choiceAndStrategy[0]))
            .findAny()
        )
        .flatMap(Optional::stream)
        .mapToInt(round -> {
            int cost = strategyCosts.entrySet().stream().mapToInt(entry -> entry.getValue().contains(round) ? entry.getKey() : 0).sum();
            return cost + choiceCosts.get(round.split(" ")[1]);
        })
        .sum();
    System.out.println(totalPartTwo);
}
Исходные данные: https://adventofcode.com/2022/day/2/input

P.S. Как же, оказывается, тяжело воспринимается «на слух» непривычный порядок — вместо «камень/ножницы/бумага» в условиях описывается Rock Paper Scissors​ — несколько раз путался при мапинге стратегий, пока комментарий в «правильном» порядке не написал 😀

Advent of Code 2022: Day 1

Итак, простое решение для первого дня Advent of Code 2022 года. Запускается из консоли jshell.

Т.к. лень было что-то специальное изобретать для работы с данными задачи (да и формат AoC этого не предполагает) — сразу решил сложить всё в сортированную коллекцию.

Это пригодилось для второй части задачи — оказалось достаточным просто просуммировать три наибольшие цифры на калькуляторе — и ответ готов!

static void day1(String problemUri) throws IOException, InterruptedException {
    List<List<String>> initial = new ArrayList<>();
    initial.add(new ArrayList<>());
    var result = client.send(request.uri((URI.create(problemUri))).build(), HttpResponse.BodyHandlers.ofLines()).body()
        .reduce(initial, (sublist, element) -> {
            if (element.isBlank()) {
                sublist.add(new ArrayList<>());
            } else {
                sublist.get(sublist.size() - 1).add(element);
            }
            return sublist;
        }, (list1, list2) -> emptyList());

    TreeSet<Integer> calories = new TreeSet<>();
    for (var stringList : result) {
        calories.add(stringList.stream()
            .mapToInt(Integer::parseInt)
            .sum()
        );
    }

    System.out.println(calories);
}
Исходные данные: https://adventofcode.com/2022/day/1/input

Выбираем кондиционер для жаркого лета

Перед выбором кондиционера для своей квартиры — заранее определитесь с такими ключевыми моментами как:

  • бюджет
  • площадь помещения
  • место, которое возможно отдать под установку
  • необходимые функции агрегата

Бюджет является основополагающим моментом при выборе кондиционера. Если вы предполагаете потратить на кондиционер небольшую сумму, то тогда оконный моноблок — именно ваш вариант. Кондиционер устанавливают в стену или оконный проем, поэтому надо учитывать стоимость пробивания стены или замены окна. Даже не глядя на то, что кондиционеры оконного типа отходят постепенно в небытие, сейчас на рынке есть модели довольно известных производителей. К тому же, если позволяет бюджет, то лучше купить мультисплит- или сплит-систему.

Место кондиционера в помещении — еще один важный фактор при выборе. Поверхность, на которую будет установлен внутренний блок устройства, должна быть гладкой и прочной. Краски купить лучше заранее, чтобы после монтажа можно было оперативно восстановить отделку. Место должно быть доступным для соединяющего трубопровода и кабеля питания. К тому же, сервисное обслуживание лучше проводить в удобно доступном месте. Не стоит устанавливать кондиционер вблизи источников тепла, в противном случае температурные датчики кондиционера будут работать неправильно. Определившись с местом для кондиционера, вы можете подобрать необходимый внутренней блок: полочный, напольный, настенный или универсальный. Если позволяет планировка помещений, то при выборе мультисплит-системы, вы можете купить для каждой комнаты индивидуальный блок.

Площадь помещения, которое должен обслуживать кондиционер, напрямую влияет на его характеристики. Мощность кондиционера полностью зависит от площади — к примеру, для настенного кондиционера она рассчитывается так: один киловатт мощности на каждые 10 м2. площади помещения. Кроме функции охлаждения воздуха, современные кондиционеры могут нагревать его, осушать и очищать. Стоит задуматься, необходимы ли они вам? Каждая дополнительная функция делает агрегат дороже.

Качественные сервера для IT сферы

Новые, уникальные по своим мощностям сервера, предназначенные для IT сферы

IT сфера на сегодняшний день, является, пожалуй, наиболее бурно и быстро развивающейся отраслью, в которой все стремятся работать. Естественно, что в таком живом, кишащем и бурлящем мире будет спрос не только на непосредственных исполнителей работы, чаще всего программистов в данном случае, но еще и на агрегаты, связанные со сферой. Опять же, в случае с IT речь идет про сервера.

Пожалуй, главной и самой передовой компанией, предоставляющей оптимальные по соотношению цена-качество продукты, является компания под названием Hewlett Packard Enterprise, или, как более понятно в сокращении, HP.

Недавно организация обновила свою самую известную линейку, выпустив сервера ProLiant Gen10. Данное решение стало весьма знаковым во всем цифровом мире, главным образом потому, что в сервера были внедрены инновационные и масштабные процессы под названием Intel® Xeon® Scalable, которые намного более производительны в пересчете на одно ядро в сравнении с предыдущей своей версией. По итогу у сервера серьезно повысилась общая эффективность и возросла производительность, он банально стал быстрее и мощнее. узнать подробнее о них и их характеристиках можно по ссылке.

Помимо мощности в компании проработали и такой элемент, как безопасность. В новостях постоянно мелькают события, в которых у той или иной, иногда даже очень крупной и известной компании, попросту своровали все данные, взломав ее сервера. В HP понимают всю важность сохранения высочайшего уровня безопасности, а потому в своем новом решении этому элементу уделено большое внимание. 

В частности, все сервера поставляются с многочисленными компонентами, которые и обеспечивают надежный уровень безопасности. Например, таким компонентов можно назвать подсистему под названием HPE iLO 5, которая ответственна за множество операций по защите, например, за предотвращение несанкционированного вторжения в пространство компании. Сама по себе система имеет отличные характеристики. К ней в помощь идут многочисленные утилиты, встроенные средства и инструменты, позволяющие также защитить сервер, сберечь все данные, находящиеся на нем.

Сервера уже в продаже и приобрести их может абсолютно любой желающий. Стоимость одного сервера при этом начинается от 80 тысяч рублей и кончается более чем 400 000 рублей. Как говорится — на любой вкус и кошелёк.

Оформление туристической страховки

Для того, чтобы осуществить путешествие за границу, понадобится страховка, оформить которую можно онлайн в пару кликов. В компании Тинькоф туристическая страховка оформляется дистанционно, что позволит сэкономить бюджет.

Особенности туристической страховки: о чем стоит знать

Стоимость страховки будет зависеть от следующих критериев:

  • возраста;
  • выбранной страны;
  • длительности путешествия;
  • количества услуг, которые будут в страховке.

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

Чтобы можно было узнать предварительную стоимость туристической страховки, необходимо воспользоваться онлайн-калькулятором. Для туриста покупка страховки – это повод не беспокоиться о возможных тратах на лечение, о потере багажа, а также других различных ситуациях, в которые можно будет попасть.

Туристическая страховка позволит быть под защитой во время пребывания в другой стране, с ней любой турист будет чувствовать себя намного увереннее.

Если вдруг во время путешествия произойдет что-то незапланированное, что потребует медицинской помощи, в таком случае нужно обратиться к специалистам, которые подберут в кратчайшие сроки подходящее заведение, в котором смогут организовать приём специалиста.

Оформление туристической страховки в пару кликов онлайн от Тинькоф

В группе компаний Тинькоф можно воспользоваться данной услугой на выгодных условиях. Нужно только заполнить заявку и выбрать все подходящие опции. Оплатить страховку можно банковской картой, а готовая страховка будет отправлена в электронном виде на почту.

К дополнительным опциям относятся страхование таких рисков, как: отмена поездки, гражданская ответственность, страхование документов и багажа, страхование фото и видео- инвентаря. В том случае, если возникнет страховой случай, необходимо связаться со специалистами компании Тинькоф.

Чтобы можно было больше узнать про страховку для путешествий, стоит обратиться за консультированием к сотрудникам, которые ответят на все интересующие вопросы. У туристической страховки нет скрытых платежей, а также различных дополнительных лимитов.

Можно выбрать страховку на любую страну, различный тип отдыха, период длительности полиса, на различную страховую сумму. Каждому клиенту компании Тинькоф гарантируется возмещение средств на медицинскую помощь.

Зачем Help Desk нужен компании

Чтобы можно было автоматизировать процессы выполнения различных задач в компании, стоит обратить внимание на программу Help Desk.

Программа хелпдеск это — возможность повысить эффективность работы, решать различные задачи в компании в максимально короткие сроки и с высокой эффективностью

Особенности программы Help Desk

Данная программа идеально подходит для:

  • IT-службы;
  • Выездной бригады инженеров;
  • Системных администраторов, и не только.

Чтобы можно было решить ту или иную задачу в компании, необходимо просто оставить заявку в программе Help Desk. К преимуществам стоит отнести простой и понятный интерфейс программы, в котором легко найти нужную задачу, посмотреть, кто её создал, узнать статус выполнения задачи, подкорректировать её при необходимости.

Каждому из сотрудников компании можно будет создать аккаунт, через который будет осуществляться работа с программой Help Desk.

Почему стоит выбрать Help Desk 

Программа Help Desk отличается следующими характеристиками:

  • Возможностью автоматического распределения заявок;
  • Наличием мобильного приложения для Android и iOS;
  • Присутствием возможности оформления отчетов;
  • Функционалом проведения учета затрат, оборудования.

За счет большого количества функций программа Help Desk пользуется большим спросом среди различных компаний, где приходится решать много задач. Чтобы понять, подходит ли данная программа для фирмы, стоит попробовать бесплатный режим, который позволит оценить интерфейс и все богатые возможности.

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

Благодаря программе Help Desk можно собрать большое количество информации, которая в дальнейшем будет анализироваться специалистами, чтобы найти узкие места в работе компании и устранить их для повышения эффективности.

Специалисты сервиса OkDesk проведут, при необходимости, консультирование, ответят на все интересующие вопросы относительно программы, расскажут про её преимущества и особенности. Чтобы получить программу для её внедрения в компанию, необходимо просто оставить заявку, которая будет в кратчайшие сроки обработана специалистами сервиса OkDesk. С данной программой производительность компании будет заметно улучшена.