К содержанию

Подтема 2 из 5

Дописывание цифр

Что происходит с числом, когда к его записи дописывают цифры справа или слева.

Дописывание справа

Что получится, если к двоичной записи 11 = 1011 дописать справа 01? А если первые две цифры заменить или посчитать сумму цифр? Задание 5 состоит из таких действий.

Каждое действие с записью — это строка программы и понятное изменение числа: дописанная справа цифра сдвигает старые цифры. Здесь — дописывание; срезы, замены и сумма цифр — в подтеме 3. Функция to_base из подтемы 1 нам ещё понадобится.

Сдвиг разрядов

Дописанная справа цифра сдвигает все старые цифры на разряд влево. В десятичной системе 37 → 374. Что произошло с числом? 374 = 37 · 10 + 4. Все исходные цифры сдвинулись на один разряд влево. Их вклад увеличился в десять раз. В освободившийся разряд единиц поставили 4.

В двоичной системе 1011₂ → 10110₂. Поскольку 1011₂ = 11, получаем R = 11 · 2 + 0 = 22. Если дописать единицу, 1011₂ → 10111₂, то R = 11 · 2 + 1 = 23.

Каждая старая цифра переехала в соседний разряд слева, её вес удвоился: 11 превратилось в 22. Дописанная единица встала в разряд единиц, поэтому R = 22 + 1 = 23.

Дописали 0 — число удвоилось, дописали 1 — удвоилось и выросло на 1.

Тонкости:общее правило

Общее правило: R = qN + d, где d — дописанная цифра. У неё обязательно должно выполняться 0 ≤ d < q.

В двоичной системе возможны только два варианта: дописали 0 — R = 2N, дописали 1 — R = 2N + 1. Это не отдельные формулы для заучивания: они следуют из весов разрядов.

Несколько цифр

Если справа дописывают несколько цифр, важны и их значение, и их количество.

Например, к 1011₂ = 11 дописываем 01: 1011₂ → 101101₂. Дописали две цифры: старое число умножилось на 4, и к нему прибавилось значение блока — 44 + 1 = 45.

Блок из двух цифр сдвигает старые цифры на два разряда: вес каждой вырос в 4 раза, 11 стало 44. Блок 01 стоит в двух младших разрядах и добавляет своё значение 1.

Особенно внимательно обращайся с нулями в начале дописываемого блока. У блоков 1, 01, 001 одинаковое числовое значение — 1. Но разная длина:

1
R = 2N + 1один разряд: N · 2¹
01
R = 4N + 1два разряда: N · 2²
001
R = 8N + 1три разряда: N · 2³

Например, для N = 11: 11 · 8 + 1 = 89. И действительно, 1011₂ → 1011001₂ = 89.

Нули в начале отдельного блока нельзя выкидывать, если условие требует дописать именно этот блок.

Тонкости:общее правило

Если к записи N в системе с основанием q справа дописывают блок из k цифр со значением A, то R = N · qᵏ + A: каждый сдвиг на один разряд умножает число на q, сдвиг на k разрядов — на qᵏ.

Дописывание слева

Если дописать цифры слева, их вес зависит от длины прежней записи. Пусть N = 11 = 1011₂. Дописали слева 10: 1011 → 101011. Исходные цифры остались на своих местах. Новый блок оказался левее четырёх исходных разрядов. Поэтому R = 10₂ · 2⁴ + 11 = 2 · 16 + 11 = 43.

Слева старые цифры не двигаются и сохраняют вес: 11 остаётся 11. Блок 10 встал над четырьмя разрядами, его вес — 2⁴ = 16, отсюда 2 · 16 + 11 = 43.
Тонкости:общее правило

Общее правило: R = A · qᴸ + N, где A — значение дописанного слева блока, L — длина записи, перед которой этот блок ставят. Сравни:

ДействиеФормула
Справа дописать k цифр со значением AN · qᵏ + A
Слева дописать блок со значением AA · qᴸ + N

Например, если слева дописывается одна единица: R = qᴸ + N. Здесь степень зависит от длины исходной записи. При переходе к следующей длине она меняется.

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

Соединение строк

В программе дописывание — это соединение строк. Дописать справа 01 — s = s + '01', слева 10 — s = '10' + s. Скопировать в конец последние две цифры — s = s + s[-2:]: s[-2:] берёт два последних символа. Так любая команда условия становится одной строкой программы.

Блок по условию

Чаще всего блок выбирают по условию на N. Например: если N чётное, слева дописать 1, а справа 0; если нечётное — слева 11, а справа 1.

Проверим руками на двух входах. 6 = 110₂, оно чётное: 1 + 110 + 0 = 11100. Справа одна цифра, поэтому старое число удвоилось: 12. Слева единица встала над четырьмя разрядами: 2⁴ = 16. R = 16 + 12 = 28. Число 7 = 111₂ нечётное: 11 + 111 + 1 = 111111, R = 63.

В программе выбор ветви — с else, а чётность — остаток n % 2. Запусти её по шагам и посмотри, какую ветвь проходит каждый вызов:

def transform(n):    s = bin(n)[2:]    if n % 2 == 0:        s = '1' + s + '0'    else:        s = '11' + s + '1'    return int(s, 2)  print(transform(6))print(transform(7))
28 63

Для чётного 6 выполняется строка 4 и пропускается строка 6, для нечётного 7 — наоборот. Посмотрим на результаты подряд:

for n in range(4, 9):    print(n, transform(n))
4 24 5 59 6 28 7 63 8 48

Обрати внимание: при N = 8 результат меньше, чем при N = 7. Результат не обязан расти вместе с N, если ветви дописывают разные блоки. Как с этим жить при поиске ответа, разберём в подтеме 4.

Дописать результат

Дописать результат вычисления — не всегда значит применить str. Предположим, алгоритм требует:

  1. найти остаток от деления N на 3;
  2. умножить его на 7;
  3. перевести произведение в троичную систему;
  4. дописать эту запись справа.

Если остаток равен 2, то 2 · 7 = 14. Но дописывать нужно не 14, а троичную запись: 14₁₀ = 112₃.

n = 14s = to_base(n, 3)extra = n % 3 * 7print(s + to_base(extra, 3))print(s + str(extra))
112112 11214

Первая строка правильная: дописана троичная запись 112. Вторая неправильная: str(14) даёт десятичную строку '14'. Более того, цифра 4 вообще недопустима в троичной записи.

Применять str можно, когда дописывается одна допустимая цифра нужной системы, например str(n % 2). Например, остаток от деления на 2 — это 0 или 1.

Каждый раз задавай себе вопрос: я дописываю одну цифру или запись некоторого числа в указанной системе?

Итого

  • Дописать справастарые цифры сдвигаются: одна двоичная цифра — число удвоилось, две — умножилось на 4
  • Блок 01 и 001длина блока важна вместе с нулями в его начале
  • Дописать слевастарые цифры не двигаются, блок встаёт над ними
  • Блок по условиюif и else по условию на N; результат может не расти вместе с N
  • Записанное числодописывают его запись в нужной системе, а не str

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
К записи 11 = 1011 дописали справа 0, затем 1. Чему равно R?
ОтветСкрыть ответ
Ответ
45: 1011 → 10110 = 22 → 101101 = 45 — число удвоилось, потом удвоилось и выросло на 1.
Вопрос 2
Почему s + str(2 * 4) не годится, если к двоичной записи нужно дописать двоичную запись произведения?
ОтветСкрыть ответ
Ответ
str(8) даёт десятичное '8', а нужна двоичная запись 1000: s + bin(2 * 4)[2:].
Вопрос 3
К записи 13 = 1101 дописали слева 1. Чему равно R?
ОтветСкрыть ответ
Ответ
29: 11101 — новая единица встала над четырьмя разрядами, её вес 16, и 16 + 13 = 29.
Вопрос 4
Блоки 1 и 001 имеют одно значение. Дают ли они одинаковое R?
ОтветСкрыть ответ
Ответ
Нет: 001 сдвигает старые цифры на три разряда, а 1 — на один. Для N = 11 получится 89 и 23.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Дописать справа 001

К двоичной записи числа 11 дописали справа 001. Какое число получилось?

Введите число.

Троичный блок 12

К троичной записи числа 7 дописали справа 12. Какое число получилось?

Введите число.

Дописать слева 10

К двоичной записи числа 13 дописали слева 10. Какое число получилось?

Введите число.

Дописать запись другого числа

К двоичной записи числа 6 дописали справа двоичную запись числа 5. Найди результат формулой и проверь программой.

Введите число.

Блоки по чётности, R > 200

На вход алгоритма подаётся натуральное число N. Строится двоичная запись N. Если N чётное, слева к ней дописывается 1, а справа — 0; если нечётное, слева дописывается 11, а справа — 1. Полученная запись — двоичная запись числа R. Укажи наименьшее N, для которого R больше 200.

Введите число.

Троичный алгоритм, R > 500

На вход алгоритма подаётся натуральное число N. Строится троичная запись N. Если N делится на 3, справа к ней дописываются две последние троичные цифры этой записи; иначе остаток от деления N на 3 умножается на 8, переводится в троичную систему и дописывается справа. Полученная запись — троичная запись числа R. Укажи наименьшее N, для которого R больше 500.

Введите число.