Проблема 8-го дня AoC (Java)

#java

#java

Вопрос:

Я пытался решить рождественскую проблему программирования, которую вы можете прочитать здесь: появление 8-го дня кода

Я использовал Java для решения этой проблемы, поэтому у меня есть следующая функция, в которой list содержится одно действие входного файла для каждого индекса:

 public int calculate_P1() {
    boolean[] config = new boolean[list.size()];
    int acc=0;

    for (int i = 0; i < list.size(); i  ) {

        if (list.get(i).substring(0, 3).equals("nop")) {
            if (config[i] == true) break;
            config[i] = true;
            continue;
        }

        if (list.get(i).substring(0, 3).equals("acc")) {
            if (config[i] == true) break;
            config[i] = true;

            if (list.get(i).charAt(4) == ' ') acc  = Integer.parseInt(list.get(i).substring(5));
            if (list.get(i).charAt(4) == '-') acc -= Integer.parseInt(list.get(i).substring(5));
            continue;
        }

        if (list.get(i).substring(0, 3).equals("jmp")) {
            if (config[i] == true) break;
            config[i] = true;

            if (list.get(i).charAt(4) == ' ') i  = (Integer.parseInt(list.get(i).substring(5)));
            if (list.get(i).charAt(4) == '-') i -= (Integer.parseInt(list.get(i).substring(5)));

            i--;
        }
    }

    return acc;
}
 

Это правильно решает ввод примера, но входной файл намного длиннее, и я получаю 261 результат, хотя он должен быть 1179 … Что я делаю не так?

Комментарии:

1. @dbl это уменьшает i на 1 😉

2. Таким образом, уменьшение не было проблемой, но это было как-то связано … изменение всего тела последнего оператора if для i = Integer.parseInt(list.get(i).substring(4)) - 1; решения проблемы, и я получаю правильный ответ. GL с P2.

3. @dbl это было так, исправьте сейчас! большое спасибо

4. Я использовал тот же подход для P1, хотя мой цикл в два раза короче вашего фрагмента. Для P2 я закончил с рекурсией 🙂 В моем цикле было две переменные драйвера i amp; step , где i был изменен i =step , и step был assingend в соответствии с первыми 3 буквами — инструкцией (или, в моем случае, ключом из Map<String, Integer> , хотя). Вот почему у меня не было уменьшения… Поэтому мне было легко перейти к рекурсивному (замене step assingments на selfcalls). GL с P2.

5. В этом случае я не использовал рекурсию, но функция, которая постоянно меняла «nop» на «jmp» и вычисляла, является ли это бесконечным циклом или нет, пока я не получил ответ, казалась проще для моего уровня программирования: P. Однако вчерашняя проблема с сумками определенно нуждалась в некоторой рекурсии! GL о следующих проблемах!

Ответ №1:

Проблема заключается в этих двух утверждениях для jmp :

         if (list.get(i).charAt(4) == ' ') i  = (Integer.parseInt(list.get(i).substring(5)));
        if (list.get(i).charAt(4) == '-') i -= (Integer.parseInt(list.get(i).substring(5)));
 

Если оператор jmp 443 (первый оператор перехода в моем вводе), первая строка уже изменяется i , а затем второй if больше не проверяет операнд jmp 443 оператора, он проверяет операнд цели перехода.

С моим вводом инструкция для первой цели перехода является acc -1 , что означает, что второй оператор if тоже вычисляется, что означает, что новое i вычисляется неправильно.

Лучшим решением является использование if / else if комбинации:

         if (list.get(i).charAt(4) == ' ') 
            i  = (Integer.parseInt(list.get(i).substring(5)));
        else if (list.get(i).charAt(4) == '-') 
            i -= (Integer.parseInt(list.get(i).substring(5)));
 

Однако самое простое решение — позволить Integer.parseInt() позаботиться о и - подписать:

         i  = Integer.parseInt(list.get(i).substring(4));
 

(это также может быть применено к регистру «acc» …)

Комментарии:

1. Или просто замените весь этот if-else-if на i = Integer.parseInt(list.get(i).substring(4)); . parseInt может анализировать префиксы ‘ ‘ и ‘-‘