Add: add solutions for first day

This commit is contained in:
Kirill Samoylenkov 2025-12-01 21:11:36 +05:00
parent b33c5b3f96
commit 34ac3971f0
5 changed files with 4194 additions and 0 deletions

101
python/src/1-day/README.md Normal file
View file

@ -0,0 +1,101 @@
# День 1: Секретный вход
## Вступление
* У эльфов есть хорошие и плохие новости.
* Хорошая новость заключается в том, что они открыли для себя проектный менеджмент! Это дало им инструменты, необходимые для предотвращения обычной рождественской чрезвычайной ситуации. Например, теперь они знают, что украшения Северного полюса нужно закончить в ближайшее время, чтобы другие важные задачи могли начаться вовремя.
* Плохая новость заключается в том, что они поняли, что у них есть другая чрезвычайная ситуация: согласно их плану использования ресурсов, ни у кого из них не осталось времени на украшение Северного полюса!
* Чтобы спасти Рождество, эльфам нужно, чтобы вы закончили украшать Северный полюс до 12 декабря.
* Собирайте звезды, решая головоломки. Каждый день будет доступно две головоломки; вторая головоломка открывается после того, как вы решите первую. За каждую головоломку вы получаете одну звезду. Удачи!
## Первая часть
### Описание задачи
* Вы прибываете к секретному входу в базу на Северном полюсе, готовые приступить к украшению. К сожалению, пароль, похоже, был изменен, и вы не можете войти. Документ, приклеенный к стене, объясняет:
* «В связи с новыми протоколами безопасности пароль заблокирован в сейфе внизу. Новую комбинацию см. в приложенном документе».
* На сейфе есть циферблат, на котором находится только стрелка; вокруг циферблата расположены цифры от 0 до 99 в порядке возрастания. Когда вы поворачиваете циферблат, он издает небольшой щелчок при достижении каждой цифры.
* Прилагаемый документ (ваша входная информация для головоломки) содержит последовательность поворотов, по одному на строку, которые подсказывают, как открыть сейф. Поворот начинается с буквы L или R, которая указывает, должен ли поворот быть влево (к меньшим числам) или вправо (к большим числам). Затем следует значение расстояния, которое указывает, на сколько щелчков следует повернуть циферблат в этом направлении.
* Таким образом, если циферблат указывает на 11, поворот R8 приведет к тому, что циферблат укажет на 19. После этого поворот L19 приведет к тому, что он укажет на 0.
* Поскольку циферблат представляет собой круг, поворот циферблата влево от 0 на один щелчок приводит к тому, что он укажет на 99. Аналогично, поворот циферблата вправо от 99 на один щелчок приводит к тому, что он укажет на 0.
* Таким образом, если циферблат указывает на 5, поворот L10 приведет к тому, что он укажет на 95. После этого поворот R5 приведет к тому, что он укажет на 0.
* Циферблат начинает с указания на 50.
* Вы могли бы следовать инструкциям, но недавний обязательный официальный семинар по безопасности секретного входа на Северный полюс научил вас, что сейф на самом деле является ловушкой. Настоящий пароль — это количество раз, когда циферблат остается на отметке 0 после любого поворота в последовательности.
if test_step < 0:
total_zero_cnt += abs(test_step) // 100 + 1
elif test_step == 0:
total_zero_cnt += 1
* Например, предположим, что в приложенном документе содержатся следующие повороты:
```
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82
```
* После выполнения этих поворотов стрелка будет двигаться следующим образом:
```
Стрелка начинает движение, указывая на 50.
Стрелка поворачивается на L68, указывая на 82.
Стрелка поворачивается на L30, указывая на 52.
Стрелка поворачивается на R48, указывая на 0.
Стрелка поворачивается на L5, указывая на 95.
Циферблат поворачивается на R60, чтобы указать на 55.
Циферблат поворачивается на L55, чтобы указать на 0.
Циферблат поворачивается на L1, чтобы указать на 99.
Циферблат поворачивается на L99, чтобы указать на 0.
Циферблат поворачивается на R14, чтобы указать на 14.
Циферблат поворачивается на L82, чтобы указать на 32.
```
* Поскольку в ходе этого процесса стрелка указывает на 0 в общей сложности три раза, пароль в этом примере равен 3.
* Проанализируйте повороты в приложенном документе. Каков фактический пароль для открытия двери?
### Решение
1. Начинаем с `current_step = 50` и `total_zero_cnt = 0`.
2. Последовательно получаем каждый шаг из документа.
3. Преобразуем `L` в `-`, а `R` в `+` для числа.
4. Прибавляем полученное число к `current_step`
5. Находим остаток `current_step` при делении на 100.
6. Если `current_step` равен 0, то прибавляем 1 к `total_zero_cnt`
### Ответ
`969`
## Вторая часть
### Описание задачи
* Правила поменялись, теперь пароль - кол-во раз, когда циферблат щелкает на 0.
### Решение
* Всё описано в коде `solution2.py`
### Ответ
`5887`

4042
python/src/1-day/input.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
total_zero_cnt = 0
current_step = 50
with open("./src/1-day/input.txt", "r") as file:
for step in file:
current_step += int(step[1:]) if (step[0] == "R") else -int(step[1:])
current_step %= 100
total_zero_cnt += int(current_step == 0)
print(total_zero_cnt)

View file

@ -0,0 +1,31 @@
# Кол-во нулей для пароля
total_zero_cnt = 0
# Текущее значение стрелки на циферблате
current_step = 50
with open("./src/1-day/input.txt", "r") as file:
for step in file:
# Получаем значение, на которое надо сдвинуть цифербрал
next_step = int(step[1:]) if step[0] == "R" else -int(step[1:])
# Сохраняем значение, где должна оказаться стрелка циферблата
# как будто он просто прямая с числами.
next_current_step = current_step + next_step
# Прибавляем к кол-ву нулей кол-во проделанных полных проворотов циферблата
total_zero_cnt += abs(next_current_step) // 100
# Если полученное значение на прямой <= нулю,
# то это значит, что стрелка либо была на нуле изначально,
# либо она пересекла ноль (ушла дальше/осталась на нем, не имеет значения).
# Убираем с помощью `and current_step != 0` вероятность первого сценария
# И прибавляем в таком случае еще 1 нуль, который стрелка пересекла.
if next_current_step <= 0 and current_step != 0:
total_zero_cnt += 1
# Как и в предыдущем решении считаем реальное значение стрелки
current_step = next_current_step % 100
print(f"{total_zero_cnt=}")

View file

@ -0,0 +1,10 @@
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82