Логическая ошибка в последовательности 011212201 вопроса

Я пытаюсь решить следующую задачу:

Пример последовательности 011212201220200112... строится следующим образом:

Первый элемент последовательности равен 0.

Для каждой итерации повторите следующее действие: возьмите копию всей текущей последовательности, замените 0 на 1, 1 на 2 и 2 на 0 и поместите ее в конец текущей последовательности. Например. 0 -> 01 -> 0112 -> 01121220 -> ...

Создайте алгоритм, который определяет, какое число находится на N-й позиции в последовательности (с использованием индексации, отсчитываемой от 0).

Вход

Ваша программа должна читать строки из стандартного ввода. Каждая строка содержит целое число N такое, что 0 <= N <= 3000000000.

Выход

Выведите число, которое находится на N-й позиции в последовательности.

Я увидел логику и реализовал ее следующим образом:

def find_nth_element(N):
    result = 0
    while N > 0:
        N -= 1  
        result = (result + 1) % 3 if N % 2 == 1 else result
        N //= 2
    return result

import sys
for line in sys.stdin:
    N = int(line.strip())
    print(find_nth_element(N))

Однако тестовые примеры с этим не справились.

Например, когда входное значение равно 11, ожидаемый результат — 0, но мой код возвращает 1.

Я думал, что уловил необходимую логику. Где моя ошибка?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
96
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Логика многократного деления данного ввода на 2 действительно правильная, но ошибка в N -= 1.

Если число, которое нужно разделить на 2, нечетное, то целочисленное деление предполагает игнорирование 1, которая делает делимое нечетным, но:

  1. В этом нет необходимости, если в вашем распоряжении есть оператор целочисленного деления (//), который вы используете
  2. Даже если вы вычтете эту 1, это должно произойти только тогда, когда число нечетное, и это должно произойти только непосредственно перед делением, а не до того, как вы проверите четность, чтобы адаптировать результат.

В любом случае, чтобы исправить вашу попытку, вам просто нужно удалить этот оператор:

N -= 1

Другие замечания

Еще несколько замечаний по поводу этого алгоритма:

1. Сокращение кода

По сути, алгоритм добавляет единицу к результату (модуль 3) на каждую единицу в двоичном представлении N. Таким образом, вы можете использовать собственный метод bit_count, чтобы подсчитать их все:

def find_nth_element(N):
    return N.bit_count() % 3

2. Тестирование вашего решения

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

def gen():
    lst = [0]
    i = 0
    while True:
        if i >= len(lst):
            lst += [(i + 1) % 3 for i in lst]
        yield lst[i]
        i += 1

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

for n, expected in enumerate(gen()):
    res = find_nth_element(n)
    if res != expected:
        print("wrong result for n = ", n)
        break
    if n > 1000:
        print("The first 1000 inputs were verified")
        break

Приятного кодирования!

Другие вопросы по теме