Я не видел этот номер раньше!


31

Напишите программу , которая проходит через строку без пробельных символов (можно предположить , что они являются цифры 0до 9, но ничего в том , как они должны быть обработаны не зависит от этого) , и добавляет пространства в соответствии со следующими правилами.

  1. Пусть текущий токен будет пустой строкой, а ранее выпущенные токены будут пустым набором.
  2. Перебирайте символы строки. Для каждого символа сначала добавьте символ к текущему токену. Затем, если текущий токен еще не находится в наборе ранее выпущенных токенов, добавьте текущий токен в этот набор и пусть новый текущий токен будет пустой строкой.
  3. Если по достижении конца строки текущий токен пуст, выведите ранее выпущенные токены в порядке эмиссии, разделенных пробелом. В противном случае выведите исходную строку дословно.

вход

Ввод к STDIN должен быть последовательностью цифр.

Выход

Программа должна распечатать результат, как указано в шаге 3.

образцы

Образцы входов

2015
10101010
4815162342
101010101010
3455121372425
123456789101112131415
314159265358979323846264338327950288419716939937

Пример выходов

2 0 1 5
10101010
4 8 1 5 16 2 3 42
1 0 10 101 01 010
3 4 5 51 2 1 37 24 25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3 1 4 15 9 2 6 5 35 8 97 93 23 84 62 64 33 83 27 95 0 28 841 971 69 39 937

Это код гольф, поэтому применяются стандартные правила компьютерной игры. Самая короткая программа в байтах побеждает.

(Пожалуйста, запросите любые пояснения в комментариях. Я все еще новичок в этом. Спасибо!)


10
4815162342Я вижу, что ты там сделал, брат .
Роковая

16
Предлагаемая запись OEIS: числа, которые этим процессом делятся как минимум на два сегмента.
Мартин Эндер

3
@IsmaelMiguel Шаг 5 (как и любой другой шаг) может продвигать только одну цифру за раз. Как только вы получите 1 0 10 , следующая итерация найдет 1(уже использованная), затем продвинет одну, чтобы найти 10(уже использованную), затем продвиньте одну, чтобы найти 101, которая является новой и будет «добавлена». Затем будет добавлен пробел, и вы получите новый 0, который уже использовался, но находится в конце строки. Следовательно, вывод будет 1 0 10 101 0недопустимым ( 0повторяется), и сценарий должен просто вывести входную строку. Это можно было сделать, только 1010если 101уже было использовано.
Янус Бах Жакет

3
@kasperd № 10101010 не If a unique number cannot be formed at the end of the string, then the input should be printed verbatimможет быть разделен, поэтому он печатается как есть.
edc65

1
Но когда вы войдете в шаг 5, пробел будет после 1, который будет повторяться. Таким образом, вместо этого вы перемещаетесь вправо на 5 в пространстве 5, а затем снова перемещаетесь вправо на шаге 4, снова вводите шаг 5 и создаете 101.
Питер Тейлор

Ответы:


9

Pyth, 22 байта

 faW!}=+kTYY~kdz?tkzsY

Ведущее пространство важно.


13

Retina , 68 61 байт

+`\b(\w+?)(?<!\b\1 .*)(\w+)$
$1 $2
(?=.* (.+)$(?<=\b\1 .+)) 
<empty>

<empty>пустая строка Обратите внимание на завершающий пробел в строке 3. Вы можете запустить приведенный выше код из одного файла с -sфлагом.

объяснение

+`\b(\w+?)(?<!\b\1 .*)(\w+)$
$1 $2

Этот первый шаг реализует правила с 1 по 6. Это подстановка регулярных выражений, которая применяется несколько раз, пока строка не перестанет меняться (для этого и нужно +). На каждом шаге мы добавляем один пробел в строку слева направо (следуя правилам конкурса). Регулярное выражение соответствует самой короткой строке цифр, которая не появилась в уже обработанной части строки. Мы гарантируем, что мы смотрим на префикс оставшейся строки с границей слова \bи проверяем, что мы можем достичь конца строки, не пропуская пробелы с (\w+)$. Последнее также гарантирует, что мы выполняем только одну замену за шаг.

(?=.* (.+)$(?<=\b\1 .+)) 
<empty>

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


11

Pyth, 24 23 байта

VzI!}=+kNYaY~k"";?kzjdY

Попробуйте это здесь .

VzI!}=+kNYaY~k"";?kzjdY    Implicit: z=input(), k='', Y=[], d=' '
Vz              ;          For N in z:
     =+kN                    Append N to k
  I!}    Y                   Is the above not in Y?
          aY k               Append k to Y
            ~k""             After append, reset k to ''
                 ?k        Is k truthy (i.e. not '')
                   z       Print original input
                    jdY    Otherwise print Y joined on spaces

Спасибо @FryAmTheEggman за сохранение байта: о)


@FryAmTheEggman Хороший вызов, я довольно увлекся попыткой сохранить первоначальное значение k
Sok

8

Python 3, 92 байта

i,n,*o=input(),""
for c in i:n+=c;o,n=[o+[n],o,"",n][n in o::2]
print([" ".join(o),i][n>""])

В основном версия решения @ Willem для игры в гольф.


[" ".join(o),i][n>""]
FryAmTheEggman

@FryAmTheEggman Ах, круто, я пробовал это, bool(n)но я не думал об этом n>"".
orlp

6

Python 3, 100 99 байт

o=[];n="";i=input()
for c in i:
 n+=c
 if not n in o:o.append(n);n=""
print(i if n else" ".join(o))

2
Я установил ваш счетчик байтов. Кроме того, вы должны удалить пространство из else ".
mbomb007

1
Некоторые общие гольфы Кроме того, ваш первоначальный счет был 100 байтов, я думаю.
FryAmTheEggman

Хорошо, спасибо! Я не знал, что пробел после «еще» может быть удален. Еще один день прожил, другой день узнал :)
Виллем

5

Брахилог , 91 байт

:_:_{h:0<|bhN,?hh:NrcH,?hB(l1,-1=A;BbA),?rhL:I(mH:Ar:[L]c:1&;:[H]:\"~w \"w,L:[H]c:_:Ar:1&)}

Это заставило меня осознать, что в синтаксисе нужно многое изменить ...

объяснение

:_:_              § Creates a list [Input,[],[]] 
{...}             § Define a new predicate between the brackets and call it with the previous list as input
h:0<              § If the head of the input is negative, stop
|                 § Else
bhN,              § Second element of Input is called N
?hh:NrcH,         § N concatenated with the first element of Input is H
?hB(l1,-1=A;BbA), § Remaining digits A are either -1 if there's only one digit left or all the digits but the head otherwise
?rhL:I            § List of used integers is called L
(
   mH:Ar:[L]c:1&  § If H is already in L, call the predicate with input [A,H,L]
   ;              § Else
   :[H]:\"~w \"w, § Print H followed by a space
   L:[H]c:_:Ar:1& § Call the predicate with input [A,[],M] where M is L with H appended to it
)

4

CJam, 26 байтов

LLq{+_a2$&{a+L}|}/:X+X!S**

Проверьте это здесь.

объяснение

L        e# Push an empty array to keep track if the previous segments.
L        e# Push an empty array to build the current segment.
q{       e# For each character in the input...
  +      e#   Add it to the current segment.
  _a2$&  e#   Duplicate and check if it's already in the segment list.
  {      e#   If not...
    a+L  e#     Add it to the list and push a new empty array for the next segment.
  }|
}/
:X+      e# Store the trailing segment in X and add it's *characters* to the list.
         e# For valid splittings, this trailing segment will be empty, so that the
         e# list remains unchanged.
X!       e# Push X again and take the logical NOT.
S*       e# Get that many spaces, i.e. 1 for valid segments and 0 otherwise.
*        e# Join the list with this string between elements.

3

JavaScript (ES6), 109

Мой формат вывода не совсем совпадает с форматом вывода в вопросе (есть пробел). Я не вижу в этом недостатка, поскольку формат вывода не указан (просто программа должна печатать число после числа ... )

Попробуйте запустить приведенный ниже фрагмент в браузере, совместимом с EcmaScript 6. Разработано с Firefox, протестировано и работает на последней версии Chrome.

/* Test: redirect console.log */ console.log=x=>O.innerHTML+=x+'\n';

F=s=>{for(z=s,b=l=o=' ';s[+l];)~o.search(b+(n=s.slice(0,++l)+b))||(s=s.slice(l),o+=n,l=0);console.log(s?z:o)}

/* Test cases */
test = [
  '2015',
,'10101010'
,'4815162342'
,'101010101010'
,'3455121372425'
,'123456789101112131415'
,'11312123133'
,'314159265358979323846264338327950288419716939937']

test.forEach(t=>{console.log('\n'+t);F(t)})
<pre id=O></pre>


2

GNU sed, 83 77 73 71 байт

(Наберите один дополнительный, потому что нам требуется -rфлаг)

h
s/./&_/
:
/(\b[^ ]+).*\b\1_/{
s/_(.)/\1_/
t
g
}
s/_(.)/ \1_/
t
s/_//

Внутренний цикл проверяет повторяющуюся последовательность и добавляет символы по мере необходимости, пока после разделителя не появится уникальный номер _. Внешний цикл движется _вдоль.

Расширенная, аннотированная версия:

#!/bin/sed -rf

# Stash original in hold space
h

# Add separator
s/./&_/

:
# If current candidate is a duplicate, ...
/(\b[^ ]+).*\b\1_/{
#  ...then attempt to lengthen it ...
s/_(.)/\1_/
# ... and repeat if we succeeded, ...
t
# ... otherwise, restore original string
g
}
# Insert a space, and move our separator along
s/_(.)/ \1_/
t

# Remove the separator if we still have it
s/_//

Вы можете объединить оба tв одном.
Пользователь112638726

Также /((\b[^ ]+).*\b\2)_/{можно переписать как /(\b[^ ]+).*\b\1_/{, без причин для 2 групп захвата.
Пользователь112638726

Нет проблем :), вам нужно изменить ссылку на \1хотя!
Пользователь112638726

1

Рубин, 57 + 1 = 58 байт

s=''
l={}
$_.chars{|c|l[s<<c]||=s=''}
l[s]||$_=l.keys*' '

Использует флаг командной строки -p(или plесли ваш ввод имеет завершающий перевод строки). Использует несколько свойств словарей Ruby Hash: вы можете безопасно изменять строку, использованную для определения ключа, без изменения ключа (что не работает для других изменяемых типов), .keysвозвращает ключи в том порядке, в котором они были вставлены, и []||=оператор обеспечивает краткий способ ветвления того, существует ли данный ключ.



1

PHP - 148 байт

Крутой вызов, очень весело!

$x=fgets(STDIN);$w=array();$k='';$l='';for($i=0;$i<strlen($x);$i++){$k.=$x[$i];if(!isset($w[$k])){$l.=$k.' ';$w[$k]=1;$k='';}}echo strlen($k)?$x:$l;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.