Фон
Інцидент є досить незвичною мовою програмування, оскільки його перелік лексем не заздалегідь визначений, а виводиться із вхідних даних. Таким чином, маркування програми для інцидентів може бути досить важким, особливо якщо ви хочете зробити це ефективно. Це завдання полягає в тому, щоб зробити це самостійно.
Завдання
Вашій програмі буде надано рядок як вхід. Ось алгоритм, який Incident використовує для його маркування:
- Визначте всі рядки, які виникають як підрядку вводу рівно трьома способами (тобто є точно три входження цього рядка у вхід).
- Відмовтеся від будь-якого з цих рядків , які є підрядками інший такого рядка (наприклад , для введення
ababab
, єдиними залишилася рядок будеab
, чи неa
чиb
, тому щоa
іb
обидва підрядкаab
). - Відмовтеся від будь-яких рядків, які перекриваються вхідними даними. (Наприклад,
aaaa
міститься рівно три примірникиaa
, але ці копії перекриваються на другому та третьому символах, тому вони будуть відкинуті. Так само, уabababa
, є три копіїab
та три копіїba
, але другий-шостий символи є кожним у перекриття aab
і aba
, тому і те,ab
іba
було б відкинуто). - Будь-які рядки, які залишаються на цьому етапі, - це лексеми, які використовує програма. Токенізуйте оригінальний вхід у послідовність цих лексем (у зв'язку з відкиданням на попередньому етапі це буде лише один спосіб зробити це). Будь-які символи вхідних даних, які не входять до жодного маркера, трактуються як коментарі та відкидаються.
Ваша програма повинна взяти рядок як вхідний файл і повернути відповідне маркерування рядка (список жетонів, кожен з яких виражається у вигляді рядків) як вихід. Крім того, це потрібно зробити хоча б помірно ефективно; конкретно, програма повинна запускатися в квадратичний час ("O (n²)") або краще. (До речі, майже напевно можливо пройти швидше, ніж квадратичний, але це не найшвидший алгоритм , тому сміливо використовуйте найпростіший алгоритм, який ви можете знайти, що відповідає рамкам складності.)
Роз'яснення
- Хоча програми інцидентів теоретично можуть містити будь-який із 256 октетів, для цієї програми прийнятно для вашої програми обробляти лише входи, сформовані з друкованого ASCII (включаючи пробіл), а також новий рядок та вкладку. (Усі відомі програми інцидентів обмежуються цим підмножиною). Зауважте, що пробіл / нова лінія / вкладка не є спеціальними і можуть з’являтися посередині лексем; Інцидент трактує всі 256 октетів як непрозорі.
- Визначенням "квадратичного часу" є "якщо розмір вводу подвоїться, програма буде працювати повільніше, не більше ніж константа плюс коефіцієнт 4", тобто якщо t ( x ) - це максимальний час, який ваша програма займає обробляти вхід розміром x , тоді повинна бути деяка константа k така, що t (2 x ) <4 t ( x ) + k для всіх x . Майте на увазі, що для порівняння рядків потрібен час, пропорційний довжині струн.
- Ваша програма теоретично повинна мати можливість обробляти вхідні програми будь-якої тривалості, якщо вона працює в (можливо, гіпотетичному) варіанті вашої мови, що має необмежену пам’ять і використовує необмежені цілі числа (це нормально, якщо програма не може досягти цієї мети при виконанні на практиці через цілі числа мови чи пам'ять насправді є кінцево великими). Ви можете припустити (з метою обчислення складності), що цілі числа, що не перевищують довжину введення, можна порівнювати за постійний час (хоча майте на увазі, що якщо ви використовуєте більші значення, наприклад, за рахунок перетворення введення в а одне ціле число, вони займуть тривалий час, щоб порівняти пропорційно кількості цифр, які вони мають).
- Ви можете використовувати будь-який алгоритм, який вписується в межі складності, навіть якщо він не виконує ті ж кроки, що й алгоритм, розміщений вище, доки він дає ті самі результати.
- Ця головоломка стосується токенізації введення, а не насправді про форматування результату. Якщо найприродніший спосіб виведення списку на вашій мові передбачає неоднозначний формат (наприклад, розділений новою лінією, коли рядки містять буквальні нові рядки або без роздільників між рядками), не хвилюйтеся з приводу того, що результат закінчується неоднозначним ( поки список фактично побудований). Можливо, ви хочете зробити другу версію свого подання, яка дає однозначний вихід, щоб допомогти у тестуванні, але оригінальна версія - це версія, яка враховується для підрахунку балів.
Тестовий випадок
Для наступного введення рядка:
aaabcbcbcdefdfefedghijghighjkllkklmmmmonono-nonppqpq-pqprsrsrstststuvuvu
Ваша програма повинна створити такий вихідний список:
a a a bc bc bc d e f d f e f e d gh gh gh k l l k k l pq pq pq u u u
Стан перемоги
Це код-гольф , тому виграє найкоротша дійсна (тобто правильна поведінка введення / виведення та досить швидка для виконання) програма, виміряна в байтах.