Попробуем ещё раз сократить заголовки для статей в ленте новостного сайта. Давайте сделаем программу, которая сокращает длинный заголовок до требуемой длины и завершает его многоточием ...
, если это требуется.
Формат ввода
Вводится натуральное число L — необходимая длина заголовка.
Вводится натуральное число N — количество строк в заголовке новости.
В каждой из последующих N строк записано по одной строке заголовка.
Формат вывода:
Сокращённый заголовок.
Примечание
Многоточие учитывается при подсчёте длины заголовка.
Символ перевода строки при подсчёте длины не учитывается.
Пример
Ввод
144
5
Энтузиаст написал программу для управления громкостью с помощью жестов, чтоб не вставать с дивана
Благодаря ей он может регулировать громкость,
показывая расстояние между большим и указательным пальцами.
Для этого ему понадобилась веб-камера, знания Python и
библиотека для работы с компьютерным зрением.
Вывод
Энтузиаст написал программу для управления громкостью с помощью жестов, чтоб не вставать с дивана
Благодаря ей он может регулировать громкость...
Ввод
121
5
Энтузиаст написал программу для управления громкостью с помощью жестов, чтоб не вставать с дивана
Благодаря ей он может регулировать громкость,
показывая расстояние между большим и указательным пальцами.
Для этого ему понадобилась веб-камера, знания Python и
библиотека для работы с компьютерным зрением.
Вывод
Энтузиаст написал программу для управления громкостью с помощью жестов, чтоб не вставать с дивана
Благодаря ей он может...
Решение
Довольно сложная задача. Особенно ситуации, когда последняя строка, после обрезания меньше трех символов.
Существует несколько способов решения задачи:
Например, можно сложить все строки в одну большую и запомнить позиции всех знаков переноса строки, после чего, если длина строки больше заданной, просто обрезать до нужной длины и заменить последние три буквы на точки. Остается только восстановить положение переносов и вы получите ответ. Это можно сделать за два прохода, но в решебнике представлен менее оптимальный вариант, дающий возможность потренироваться в использовании поиска и вставке символа в строку.
Можно пойти другим путем – добавлять строки в список, каждый раз увеличивая счетчик общей длины текста. Если длина списка превысила лимит, то нужно позаботится о том, что лимит сократится на 3 знака, которые потребуются для размещения трех точек. По окончании ввода, удаляем последний элемент списка до тех пор пока общая длина всех строк за исключением последней не будет укладываться в лимит.
Если это произошло, значит мы нашли последнюю значимую строку. и дальше будем работать с ней. Тут возможно два варианта развития событий: длина оставшихся строк полностью умещается в лимит и длина все еще больше.
Если длина оказалась больше, надо обрезать последнюю строчку. Осталось дописать три точки и вывести правильный ответ.
Задача покрыта тестами не очень качественно и поэтому можно сдать неправильный, с точки зрения постановки задачи ответ.
Он будет показан последним.
Возможно, авторы имели в виду похожий вариант решения и не рассмотрели некоторые комбинации входных данных на которых он не работает. В любом случае, не стоит на него ориентироваться, как на абсолютно правильный.
По состоянию на лето 2024 года известно 4 разных варианта неправильных решений, каждое из которых неправильно в своем определенном случае, и тем не менее успешно проходит все тесты.
Например, если ввести
10
2
12345
123
То правильный ответ должен быть
12345
123
Потому, что заголовок умещается в отведенное пространство целиком.
тем не менее Яндекс согласится и на такой ответ:
12345
12...
Один из неправильных вариантов решения, проходящий тесты будет показан последним.
Посмотреть код
Решение
# Вариант с изъятием переносов строк, обрезкой и добавлением переносов обратно
length = int(input())
newline = '\n'
header = ''
newlines = []
for _ in range(stings_number := int(input())):
header += input() + newline
header.strip('\n')
for pos in range(len(header)):
if header[pos] == newline:
newlines.append(pos)
header = header.replace(newline, "")
if len(header) > length:
header = header[:length - 3] + '...'
for pos in newlines:
if (header[-3:] != '...') or (length - pos >= 4):
header = header[:pos] + newline + header[pos:]
length += 1
print(header)
Решение
# Вариант с определением наличия "хвоста" и контроля его длины
limit = int(input())
new_line = '\n'
header = []
length = 0
for _ in range(int(input())):
string = input()
header.append(string)
length += len(string)
if length > limit:
limit -= 3
while header and length - len(header[-1]) >= limit:
length -= len(header[-1])
header.pop()
if header:
if length > limit:
header[-1] = header[-1][:-(length - limit)]
header[-1] += '...'
else:
header.append('...')
while header and not header[-1]:
header.pop()
print('\n'.join(header))
Решение
# Вариант с посимвользным накоплением результата
limit = int(input())
header = ''
total = 0
# накопление данных
for _ in range(int(input())):
string = input()
total += len(string)
header += string + '\n'
result = ''
symbols = 0
dots = total > limit # проверка необходимости точек
# формирование сырого заголовка, удовлетворяющего требованиям длины
for char in header:
if symbols < limit:
if char != '\n':
symbols += 1
result += char
else:
break
if dots: # если нужно поставить точки
pos = len(result) - 1
to_cut = 3
# удаление лишних точек и переводов строк
while pos and to_cut:
if result[pos] != '\n':
to_cut -= 1
pos -= 1
# удаление оставшихся ненужных переводов строк перед точками (тест 22)
while pos and result[pos] == '\n':
pos -= 1
result = result[:pos + 1] + '...'
print(result)
Решение
# Вариант дающий ошибки при строгом тестировании, но тем не менее способный пройти тесты хэндбука
length = int(input())
lines = []
for _ in range(int(input())):
lines.append(input())
for line in lines:
if length > 3:
if len(line) >= length - 3:
line = line[:length - 3] + "..."
else:
if length == 4:
line = line + "..."
print(line)
length -= len(line)