나는 전에 그 숫자를 보지 못했다!


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 항목 :이 프로세스에 의해 최소한 두 개의 세그먼트로 분할되는 숫자.
Martin Ender

3
@IsmaelMiguel 5 단계 (다른 단계와 동일)는 한 번에 한 자리 만 진행할 수 있습니다 . 일단 가져 오면 1 0 10 다음 반복은 1(이미 사용됨) 찾은 다음 하나를 찾아 10(이미 사용됨) 찾은 다음 하나를 찾음 101으로 이동하여 새롭고 '추가'됩니다. 그런 다음 공백을 추가하면 0이미 사용되었지만 문자열 끝에 있는 new를 얻을 수 있습니다. 따라서 출력 1 0 10 101 0은 유효하지 0않으며 ( 반복됨) 스크립트는 입력 문자열 만 출력해야합니다. 이미 사용 된 1010경우 에만 만들 수 101있습니다.
Janus Bahs Jacquet

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

Pyth, 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

피스, 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 좋은 전화, 나는 k의 원래 가치를 보존하려고 노력에 꽤 걸렸다
Sok

8

파이썬 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

파이썬 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

Brachylog , 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

자바 스크립트 (ES6), 109

내 출력 형식은 questioin의 출력 샘플과 정확히 동일하지 않습니다 (선행 공간이 있음). 출력 형식이 지정되지 않았기 때문에 결함으로 보지 않습니다 ( 프로그램은 숫자 다음에 숫자를 인쇄해야합니다 ... )

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플래그 가 필요하기 때문에 1 점 추가 )

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

또한 2 개의 캡처 그룹에 대한 이유없이 /((\b[^ ]+).*\b\2)_/{로 다시 작성할 수 있습니다 /(\b[^ ]+).*\b\1_/{.
112638726 September

문제 없습니다 :), \1하지만 참조를 변경해야합니다 !
112638726

1

루비, 57 + 1 = 58 바이트

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

명령 행 플래그를 사용합니다 -p(또는 pl입력에 후행 줄 바꿈이있는 경우). Ruby Hash 사전의 여러 특성을 활용합니다. 키를 변경하지 않고 키를 정의하는 데 사용한 문자열을 안전하게 변경할 수 있습니다 (다른 변경 가능한 유형에서는 작동하지 않음). .keys삽입 된 순서대로 키를 반환하며 []||=연산자 주어진 키가 이미 있는지에 대한 간결한 분기 방법을 제공합니다.


1

하스켈, 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;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.