Я ще цього не бачив!


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

Це кодовий гольф, тому застосовуються стандартні правила CG. Виграє найкоротша програма в байтах.

(Будь ласка, вимагайте будь-яких роз’яснень у коментарях. Я все ще нова в цьому. Дякую!)


10
4815162342Я бачу, що ти там робив, братане .
Фаталізувати

16
Запропонований запис OEIS: числа, які розбиваються принаймні на два сегменти за допомогою цього процесу.
Мартін Ендер

3
@IsmaelMiguel Крок 5 (як і будь-який інший крок) може просунути лише одну цифру за один раз. Після того, як ви отримаєте 1 0 10 , наступна ітерація знайде 1(вже використана), потім просуньте одну, щоб знайти 10(вже використану), а потім просуньте одну, щоб знайти 101, яка є новою і буде "додана". Потім буде додано пробіл, і ви потрапите до нового 0, який уже використано, але тут знаходиться в кінці рядка. Отже, вихід буде 1 0 10 101 0недійсним ( 0повторюється), і сценарій повинен просто вивести рядок введення. Це можна зробити лише за 1010умови, що 101його вже використовували.
Жакус Бахс Жак

3
@kasperd No If a unique number cannot be formed at the end of the string, then the input should be printed verbatim10101010 не можна розділити, щоб воно було надруковано як є.
edc65

1
Але коли ви введете крок 5, пробіл буде після 1, що буде повторенням. Отже, замість цього ви рухаєтеся правою у пробілі 5, а потім знову рухаєтесь правою на кроці 4, і знову вводите крок 5 і створюєте 101.
Пітер Тейлор

Відповіді:


9

Піт, 22 байти

 faW!}=+kTYY~kdz?tkzsY

Провідний простір важливий.


13

Сітківка , 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 за збереження байта: o)


@FryAmTheEggman Хороший дзвінок, я отримав досить спійманий в спробі зберегти первісне значення Д.К.
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>""])

По суті, сильно гольф-версія рішення @ Віллема.


[" ".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

Класна подяка! Я не знав, що простір після "else" можна видалити. Ще один день прожив, ще один день дізнався :)
Віллем

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

Ruby, 57 + 1 = 58 байт

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

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


1

Haskell, 105 байт

f робить це.

e""s""=unwords s
e t s""=concat s++t
e t s(c:r)|t&c`elem`s=e(t&c)s r|0<1=e""(s&(t&c))r
a&b=a++[b]
f=e""[]

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.