Nie widziałem wcześniej tego numeru!

31

Napisz program, który przechodzi przez ciąg znaków non-białych (można założyć, że są cyfry 0do 9, ale nie w sposób, w jaki mają być przetwarzane zależy od tego) i dodaje spacje zgodnie z następującymi zasadami.

  1. Niech bieżący token będzie pustym ciągiem, a poprzednio emitowane tokeny będą pustym zestawem.
  2. Iteruj po znakach łańcucha. Dla każdej postaci najpierw dodaj postać do bieżącego tokena. Następnie, jeśli bieżący token nie znajduje się już w zestawie wcześniej emitowanych tokenów, dodaj bieżący token do tego zestawu i niech nowy bieżący token będzie pustym ciągiem.
  3. Jeśli po osiągnięciu końca łańcucha bieżący token jest pusty, wyślij poprzednio wyemitowane tokeny w kolejności emisji, oddzielając je spacją. W przeciwnym razie wypisz oryginalny ciąg znaków dosłownie.

Wkład

Dane wejściowe do STDIN powinny być ciągiem cyfr.

Wydajność

Program powinien wydrukować wynik, jak określono w kroku 3.

Próbki

Przykładowe dane wejściowe

2015
10101010
4815162342
101010101010
3455121372425
123456789101112131415
314159265358979323846264338327950288419716939937

Przykładowe wyniki

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

To jest kod golfowy, więc obowiązują standardowe zasady CG. Najkrótszy program w bajtach wygrywa.

(Poproś o wyjaśnienia w komentarzach. Nadal jestem nowy. Dzięki!)

Arktur
źródło
10
4815162342Widzę, co tam zrobiłeś, bracie .
Fatalize
16
Proponowany wpis OEIS: liczby, które w tym procesie są podzielone na co najmniej dwa segmenty.
Martin Ender
3
@ IsmaelMiguel Krok 5 (jak każdy inny krok) może przesunąć tylko jedną cyfrę na raz. Gdy już to zrobisz 1 0 10 , pojawi się następna iteracja 1(już używana), następnie przejdź do jednej 10(już używana), a następnie przejdź do jednej 101, która jest nowa i zostanie dodana. Dodałoby to spację i dostałbyś nowy 0, który był już używany, ale znajduje się tutaj na końcu łańcucha. Dlatego wynik byłby 1 0 10 101 0niepoprawny ( 0jest powtarzany), a skrypt musi po prostu wyprowadzić ciąg wejściowy. Mógłby to zrobić tylko, 1010jeśli 101był już używany.
Janus Bahs Jacquet
3
@kasperd nr 10101010 If a unique number cannot be formed at the end of the string, then the input should be printed verbatimnie można podzielić, więc jest drukowany w niezmienionej postaci.
edc65
1
Ale po wejściu do kroku 5 spacja będzie następować po 1, co będzie powtórzeniem. Zamiast tego poruszasz się w prawo na polu 5, a następnie ponownie w prawo w kroku 4, a następnie ponownie wchodzisz do kroku 5 i tworzysz 101.
Peter Taylor

Odpowiedzi:

9

Pyth, 22 bajty

 faW!}=+kTYY~kdz?tkzsY

Wiodąca przestrzeń jest ważna.

orlp
źródło
13

Siatkówka , 68 61 bajtów

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

<empty>jest pustą linią. Zwróć uwagę na końcowe miejsce w linii 3. Możesz uruchomić powyższy kod z jednego pliku z -sflagą.

Wyjaśnienie

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

Ten pierwszy krok implementuje reguły od 1 do 6. Jest to substytucja wyrażeń regularnych, która jest stosowana wielokrotnie, aż łańcuch przestanie się zmieniać (po to +jest). W każdym kroku dodajemy pojedynczą spację do łańcucha od lewej do prawej (zgodnie z regułami wyzwania). Wyrażenie regularne dopasowuje najkrótszy ciąg cyfr, który nie pojawił się w już przetworzonej części ciągu. Zapewniamy, że patrzymy na prefiks pozostałego łańcucha z granicą słowa \bi sprawdzamy, czy możemy dotrzeć do końca łańcucha bez przekazywania spacji (\w+)$. Ten ostatni zapewnia również, że wykonujemy tylko jedną wymianę na krok.

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

Odpowiada to dowolnej spacji (znajdującej się na końcu wyrażenia regularnego), pod warunkiem, że ostatni segment łańcucha jest taki sam jak każdy inny segment łańcucha i zastępuje je pustym ciągiem. Oznacza to, że cofamy pierwszy krok, jeśli spowodował niepoprawny końcowy segment, wdrażając zasadę 7.

Martin Ender
źródło
11

Pyth 24 23 bajty

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

Wypróbuj tutaj .

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

Dzięki @FryAmTheEggman za zapisanie bajtu: o)

Sok
źródło
@FryAmTheEggman Dobry telefon, bardzo mnie przyłapano na próbach zachowania oryginalnej wartości k
Sok
8

Python 3, 92 bajty

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>""])

Zasadniczo mocno golfowa wersja rozwiązania @ Willema.

orlp
źródło
[" ".join(o),i][n>""]
FryAmTheEggman
@FryAmTheEggman Ah fajnie, próbowałem tego, bool(n)ale nie myślałem n>"".
orlp
6

Python 3, 100 99 bajtów

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))
Willem
źródło
2
Poprawiłem liczbę bajtów. Powinieneś także usunąć spację else ".
mbomb007
1
Niektóre popularne gry w golfa Także twój oryginalny wynik to 100 bajtów.
FryAmTheEggman
Fajne dzięki! Nie wiedziałem, że spacja po „innym” może zostać usunięta. Kolejny dzień przeżył, kolejny dzień się nauczył :)
Willem
5

Brachylog , 91 bajtów

:_:_{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&)}

Uświadomiłem sobie, że w składni jest wiele rzeczy, które muszę zmienić ...

Wyjaśnienie

:_:_              § 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
)
Fatalizować
źródło
4

CJam, 26 bajtów

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

Sprawdź to tutaj.

Wyjaśnienie

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.
Martin Ender
źródło
3

JavaScript (ES6), 109

Mój format wyjściowy nie jest dokładnie taki sam jak próbek wyjściowych w questioin (istnieje spacja wiodąca). Nie uważam tego za wadę, ponieważ format wyjściowy nie jest określony (po prostu program powinien wydrukować liczbę po liczbie ... )

Przetestuj poniższy fragment kodu w przeglądarce zgodnej z EcmaScript 6. Opracowany w przeglądarce Firefox, przetestowany i działający na najnowszym 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>

edc65
źródło
2

GNU sed, 83 77 73 71 bajtów

(Zdobądź jeden dodatkowy, ponieważ wymagamy -rflagi)

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

Wewnętrzna pętla sprawdza powtarzalność sekwencji i dodaje znaki w razie potrzeby, aż po separatorze pojawi się unikalna liczba _. Pętla zewnętrzna porusza się _wzdłuż.

Rozszerzona wersja z adnotacjami:

#!/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/_//
Toby Speight
źródło
Możesz połączyć oba tw jeden.
User112638726,
Również /((\b[^ ]+).*\b\2)_/{może być zapisane jako /(\b[^ ]+).*\b\1_/{, bez powodu, dla 2 grup przechwytujących.
User112638726,
Nie ma problemu :), musisz jednak zmienić odniesienie do \1!
User112638726,
1

Rubinowy, 57 + 1 = 58 bajtów

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

Używa flagi wiersza polecenia -p(lub pljeśli dane wejściowe mają końcowy znak nowej linii). Wykorzystuje kilka cech słowników Ruby Hash: możesz bezpiecznie mutować łańcuch użyty do zdefiniowania klucza bez zmiany klucza (co nie działa dla innych typów zmiennych), .keyszwraca klucze w kolejności, w której zostały wstawione, a []||=operator zapewnia zwięzły sposób rozgałęziania, czy dany klucz już tam jest.

histocrat
źródło
1

Haskell, 105 bajtów

f czy to.

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""[]
Leif Willerts
źródło
1

PHP - 148 bajtów

Fajne wyzwanie, dużo zabawy!

$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;

źródło