Shifty Eyes Shifting I's

50

Chłopaki ASCII o zmiennookim wzroku lubią zmieniać ASCII Ii:

>_> <_< >_< <_>

Biorąc pod uwagę szereg zmiennokształtnych, rozstawionych lub oddzielnych linii, przesuń Iibok na bok, opuść ścianę i wyprostuj niebo:

Ii

Najkrótszy manewr wygrywa nagrodę.

Powiedz co

Napisz program lub funkcję, która pobiera ciąg dowolnej listy tych czterech emotikonów ASCII, oddzielonych spacją lub znakiem nowej linii (z opcjonalnym znakiem nowej linii):

>_>
<_<
>_<
<_>

Na przykład dane wejściowe mogą być

>_> >_> <_>

lub

>_>
>_>
<_>

(Metoda, którą wspierasz, zależy od ciebie.)

Każdy emotikon wykonuje inną akcję na znakach Ii i, które zawsze zaczynają się tak:

Ii
  • >_>przesuwa Isię w prawo o jeden, jeśli to możliwe, a następnie przesuwa iw prawo o jeden.
  • <_<przesuwa Isię w lewo o jeden, jeśli to możliwe, a następnie przesuwa iw lewo o jeden, jeśli to możliwe.
  • >_<przesuwa Isię w prawo o jeden, jeśli to możliwe, a następnie przesuwa iw lewo o jeden, jeśli to możliwe.
  • <_>przesuwa Isię w lewo o jeden, jeśli to możliwe, a następnie przesuwa iw prawo o jeden.

Inie można go przesunąć w lewo, jeśli znajduje się na lewej krawędzi linii (tak jak jest na początku), i nie można go przesunąć w prawo, jeśli ijest bezpośrednio w prawo (jak to jest na początku).

inie można go przesunąć w lewo, jeśli Ijest bezpośrednio w lewo (jak to jest początkowo), ale zawsze można przesunąć w prawo.

Pamiętaj, że przy tych regułach Izawsze pozostanie po lewej stronie ii Iprzedtem próbuje się przenieść iwszystkie emotikony.

Twój program lub funkcja musi wydrukować lub zwrócić ciąg ostatniego Iiwiersza po zastosowaniu wszystkich przesunięć w podanej kolejności, używając spacji ( ) lub kropek ( .) dla pustej przestrzeni. Końcowe spacje lub kropki oraz pojedyncza nowa linia są opcjonalnie dozwolone w danych wyjściowych. Nie mieszaj spacji i kropek.

Na przykład dane wejściowe

>_>
>_>
<_>

ma moc wyjściową

I...i

ponieważ zmiany obowiązują jak

start  |Ii
>_>    |I.i 
>_>    |.I.i
<_>    |I...i

Najkrótszy kod w bajtach wygrywa. Tiebreaker jest wyżej głosowaną odpowiedzią.

Przypadki testowe

#[id number]
[space separated input]
[output]

Używanie .dla jasności.

#0
[empty string]
Ii

#1
>_>
I.i

#2
<_<
Ii

#3
>_<
Ii

#4
<_>
I.i

#5
>_> >_>
.I.i

#6
>_> <_<
Ii

#7
>_> >_<
.Ii

#8
>_> <_>
I..i

#9
<_< >_>
I.i

#10
<_< <_<
Ii

#11
<_< >_<
Ii

#12
<_< <_>
I.i

#13
>_< >_>
I.i

#14
>_< <_<
Ii

#15
>_< >_<
Ii

#16
>_< <_>
I.i

#17
<_> >_>
.I.i

#18
<_> <_<
Ii

#19
<_> >_<
.Ii

#20
<_> <_>
I..i

#21
>_> >_> <_>
I...i

#22
<_> >_> >_> >_> <_> <_<
.I...i

#23
<_> >_> >_> >_> <_> <_< >_< <_< >_<
..Ii

#24
>_> >_< >_> >_> >_> >_> >_> >_> <_> <_> <_<
...I.....i
Hobby Calvina
źródło
Więc kropki są opcjonalne, zamiast tego mogą być spacje?
Rɪᴋᴇʀ
Czy w wyniku są dozwolone końcowe spacje?
mbomb007
Czy dane wejściowe mogą być tablicą znaków 2D, z każdym zmiennym facetem na linii?
Luis Mendo,
2
@RikerW - Tak. mbomb - Tak, wspomniano. Don - Nie
Calvin's Hobbies
15
Zobacz, jak Shifty Eyes stają się językiem ezoterycznym ...
kot

Odpowiedzi:

3

CJam, 33 bajty

0Xq2%{'=-_3$+[2$W]-,*@+}/S*'i+'It

Używa tego samego algorytmu, co moja odpowiedź w języku Python , z wyjątkiem indeksowania 0. Głównie:

  • Spójrz tylko na strzałki na wejściu, konwertując <na -1 i >na 1
  • Zastosuj aktualizację tylko wtedy, gdy nie przeniesie nas do pozycji -1 i nie przeniesie nas do pozycji drugiego znaku
  • Ponieważ strzałki zmieniają się między aplikowaniem Ii aplikowaniem do i, zmieniamy pozycję, którą aktualizujemy po każdej strzale

Dzięki @ MartinBüttner za grę w golfa na poziomie wyjściowym, startując 5 bajtów.

Wypróbuj online | Zestaw testowy

0X                 Initialise the two positions a = 0, b = 1
q2%                Read input and take every second char, leaving just the arrows

{ ... }/           For each arrow in the input...
  '=-              Subtract '=, leaving -1 for '< and 1 for '>
  _3$+             Duplicate and add a. Stack looks like [a b diff a+diff]
  [2$W]-           Perform setwise subtraction, [a+diff] - [b -1]
                   The result is empty list if a+diff is either b or -1, else [a+diff]
  ,                Length, yielding 0 or 1 respectively
                   0 means we don't want to update the char, 1 means we do
  *                Multiply diff by this result
  @+               Add to a. Stack now looks like [b a'] where a' is a updated

                   After the above loop, the stack ends with [(I position) (i position)]

S*                 Create (i position) many spaces
'i+                Stick an 'i at the end - this is the right place due to 0-indexing
'It                Set (I position) to 'I
Sp3000
źródło
21

Perl, 59 56 54 bajtów

Obejmuje +1 dla -p

Uruchom z wejściem na STDIN, np perl -p shifty.pl <<< ">_> <_< >_< <_>"

shifty.pl:

s%^|<|(>)%y/iI/Ii/or$_=Ii;$1?s/i |i$/ i/:s/ i/i /%reg

Wyjaśnienie

Instrukcje zastępców strunowe sterowania do ii I, a reguła jest taka sama dla obu z nich, jeśli je sformułować jako:

  • < Przesuń się w lewo, jeśli jest miejsce po lewej stronie
  • > Przesuń się w prawo, jeśli po prawej stronie znajduje się spacja lub koniec łańcucha

Zamienię zamianę ii Iciąg docelowy na każdym kroku, więc muszę tylko zastosować regułę do jednej litery. To jesty/iI/Ii/

Będę chodził po łańcuchu kontrolnym, szukając <i >używając podstawienia, które zwykle jest najkrótszym sposobem w Perlu, do przetworzenia czegoś znak po znaku. Aby uniknąć konieczności pisania $var =~, chcę ciąg kontrolny w zmiennej domyślnej perla $_. I ja też chcę w łatwy sposób odróżnić <od >. Wszystko to można osiągnąć za pomocą

s%<|(>)%  code using $1 to distinguish < from > %eg

Ciąg docelowy również chcę manipulować przy użyciu podstawień iz tego samego powodu też tego chcę $_. $_bycie dwiema rzeczami naraz wydaje się niemożliwe.

Mogę jednak zjeść ciasto i zjeść je, ponieważ $_wnętrze ciała substytucji nie musi pozostać takie samo jak $_substytucja. Gdy Perl zaczął podstawiać ciąg, ciąg nie zmieni się, nawet jeśli zmienisz zmienną, z której pierwotnie pochodzi. Możesz więc zrobić coś takiego:

s%<|(>)% change $_ here without disturbing the running substitution %eg

Chcę zastąpić oryginał $_początkowym "Ii"tylko za pierwszym razem, gdy wykonywane jest ciało substytucji (w przeciwnym razie ciągle resetuję ciąg docelowy). Zastąpienie to musi jednak nastąpić również dla pustego ciągu kontrolnego, więc nawet dla pustego ciągu kontrolnego ciało musi zostać wykonane co najmniej raz. Aby upewnić się, że podstacja działa przez dłuższy czas na początku łańcucha kontrolnego (nawet w przypadku pustych łańcuchów kontrolnych), zmieniam podstawienie na:

s%^|<|(>)% change $_ here without disturbing the running substitution %eg

Uruchomię y/iI/Ii/jako pierwszą rzecz w kodzie zastępczym. Chociaż $_nadal jest łańcuchem kontrolnym, nie będzie go jeszcze zawierał Ii, więc jeśli transliteracja wskazuje, że nic się nie zmieniło, inicjuje się mój wyzwalacz $_:

y/iI/Ii/or$_=Ii

Teraz mogę zaimplementować faktyczne przesunięcie liter. Ponieważ zaczynam od zamiany, wszystkie ruchy powinny być wykonywane dalej i, nie I. Jeśli $1jest ustawiony, przejdź iw prawo:

s/i |i$/ i/

Jeśli $1nie jest ustawiony, przejdź iw lewo

s/ i/i /

Zauważ, że na początku łańcucha kontrolnego, gdy pasuję ^ $1, nie zostanie ustawiony, więc próbuje on przejść iw lewo na początkowym ciągu Ii. To nie zadziała, ponieważ nie ma tam miejsca, więc ciąg początkowy pozostaje niezakłócony (dlatego zamiast tego umieściłem ()wokół )><

Pozostaje tylko jeden problem: pod koniec zewnętrznego podstawienia $_jest ustawiony wynik zewnętrznego podstawienia, niezależnie od tego, co zrobiłeś $_wewnątrz ciała substytucji. Tak więc łańcuch docelowy z odpowiednim rozmieszczeniem ii Igubi się. W starszych perlach byłaby to fatalna wada. Nowsze perle mają jednak rmodyfikator, co oznacza: „wykonaj kopię oryginalnego łańcucha, dokonaj na nim podstawienia i zwróć wynikowy ciąg (zamiast liczby dopasowań)”. Kiedy używam tego tutaj, wynik jest taki, że zmodyfikowany ciąg poleceń zostaje odrzucony, podczas gdy oryginał $_nie jest zakłócany przez perla i pozostawiony po podstawieniu. Jednak niepokojące, co robię, $_wciąż trwa po tym, jak Perl został $_sam. Więc na koniec$_ będzie właściwym ciągiem docelowym.

Ta -popcja zapewnia, że ​​oryginalny ciąg jest w $_środku, a także drukuje końcowy $_.

Ton Hospel
źródło
1
Początkowy ciąg to Iinie iI.
user48538
2
@ zyabin101 Dodatkowe ^dopasowanie oznacza, że ​​muszę je zamienić. Tak więc odwrotna inicjalizacja jest poprawna.
Ton Hospel
10

LittleLua - 178 bajtów

r()l=sw(I)o=1 D='.'f q=1,#l do i l[q]:s(1,1)=='>'t i z+1~=o t z=z+1 e else i z-1>0 t z=z-1 e e i l[q]:s(3)=='>'t o=o+1 else i o-1~=z t o=o-1 e e e p(D:r(z).."I"..D:r(o-z-1)..'i')

Proste wdrożenie.

Nie golfowany:

r()                             --call for input
l=sw(I)                         --Split input by spaces
o=1                             --Hold i position (z holds I position)
D='.'                           --Redundant character
f q=1,#l do                     --Foreach table entry
    i l[q]:s(1,1)=='>' t        --If the first eye points right
        i z+1~=o t z=z+1 e      --Verify no collision and move the I
    else
        i z-1>0 t z=z-1 e       --If it points left.. .same...
    e                           --yatta yatta...
    i l[q]:s(3)=='>' t
        o=o+1
    else
        i o-1~=z t o=o-1 e
    e
e
p(D:r(z).."I"..D:r(o-z-1)..'i')--String repeats to print correct characters.

Co to jest LittleLua?

LittleLua jest w toku. Próbuję wyrównać szanse pomiędzy moim wybranym językiem dla tych wyzwań a językami ezoterycznymi, które często mają niezwykle potężne wbudowane funkcje.

LittleLua to interpreter Lua 5.3.6 z dodatkowym modułem (LittleLua.Lua), a także nazwami funkcji i modułów zmniejszonymi. Te zmiany będą się rozwijać w ciągu następnego dnia lub dwóch, dopóki nie będę zadowolony, ale w tej chwili kilka największych zmian między LittleLua a standardowym tłumaczem Lua to:

Funkcje i moduły są zmniejszone:

io.read() -> r() (Value stored in built in variable "I")
string -> s
string.sub -> s.s or stringvalue:s
etc.

Wbudowane zmienne

LittleLua ma kilka wbudowanych zmiennych, które zmniejszają niektóre zadania:

z=0
o=10
h1="Hello, World!"
h2="Hello, World"
h3="hello, world"
h4=hello, world!"
etc.

Wbudowane funkcje

Obecnie przygnębiająco mała lista, ale oto ona:

d(N) -> Prints NxN identity matrix
sw(str) -> Splits string at spaces and returns table of results
sc(str) -> Splits string at commas and returns table of results
sd(str) -> Removes white space from a string (not including tabs)
ss(str,n) -> Swap N characters from beginning and end of string
sr(str,n) -> Swap N characters from beginning and end of string retaining order
sd(str) -> Split string into array of characters
co(ta) -> Concatenate table with no delimiter
co(ta, delim) -> Concatenate table with delimiter: delim
Skyl3r
źródło
Czy to gra w golfa Lua?
Downgoat
3
Tak! Oczywiście (mam nadzieję) trwająca praca. Czułem, że jestem trochę w niekorzystnej sytuacji, ponieważ inne języki mogą przyjmować dane wejściowe, sortować je, przycinać, dzielić i pośrednio zwracać je za pomocą kilku znaków, więc dostałem źródło lua i hakowałem na chwilę. Ta konkretna wersja została ukończona przed rozpoczęciem tego wyzwania, co jest niefortunne. Wiesz, co mówią, masz doświadczenie natychmiast po tym, jak go potrzebujesz.
Skyl3r
Głupie pytanie - weź, powiedz $i użyj tego zamiast endlub e- A-Za-zznaki bez słów nie potrzebują wokół nich spacji, prawda? Że golić bajt za end/e
kot
Tak, starałem się, żeby to zadziałało. Po prostu zastępując token znakiem innym niż alfanumeryczny, zgłasza błąd. Nie
kopałem
1
Ci golfed ifsię i, oszczędzając jeden bajt za użytku, a enddo e, oszczędzając dwa, ale zostawili elsew spokoju? Nawet w tym prostym programie (5 ifsi 2 elses) marnujesz więcej bajtów, elseniż oszczędzasz if. (Zakładam, że to planowana poprawa?)
Darrel Hoffman
8

Siatkówka ,101 86

$
¶Ii
(`^¶

s`^>(.*)I( )?
$1$2I
s`^<(.*?)( )?I
$1I$2
s`^_>(.*)i
$1 i
s`^_<(.*?) ?i
$1i

Wypróbuj online

Zaoszczędź 15 bajtów dzięki daavko!

Wprowadza dane oddzielone znakiem nowej linii i dane wyjściowe, a oczy oddzielone są spacjami.

Wyjaśnienie:

Wyjaśnię jak krok po kroku. Wszystkie te etapy znajdują się w trybie wymiany Retiny. Oznacza to, że pierwszy wiersz jest wyrażeniem regularnym, a drugi wiersz jest łańcuchem zastępczym.

$
¶Ii

Dodaj inicjał Iina końcu danych wejściowych.

(`^ ¶

Strzałka wsteczna oddziela scenę od opcji. Znak opcji (wskazuje, że ten etap jest początkiem pętli etapów, które należy wykonywać wielokrotnie, aż do zakończenia pełnego cyklu bez zmiany danych wejściowych. Ponieważ ten otwarty nawias nigdy nie jest zamknięty, wszystkie pozostałe etapy są częścią tej pętli.

Rzeczywisty etap jest bardzo prosty, jeśli pierwszym znakiem ciągu jest nowa linia, usuń ją. Ma to na celu ułatwienie obsługi pustych danych wejściowych, w przeciwnym razie golfista dodałby je do dwóch ostatnich etapów.

s`^>(.*)I( )?
$1$2I

Tutaj opcja spowoduje, że metaznak Regex .pasuje do nowych linii. Ten etap powoduje, że interlinia >zostanie dopasowana, Ia następnie opcjonalna spacja. Następnie zamienia pasujące elementy na następujące po >, następnie opcjonalne spacje (więc pusty ciąg znaków, jeśli spacja nie może być dopasowana), a następnie I.

s`^<(.*?)( )?I
$1I$2

Ten etap jest bardzo podobny do poprzedniego, tylko opcjonalna przestrzeń znajduje się przed I, a kolejność i oko są odwrócone.

s`^_>(.*)i
$1 i

Obsługa ijest w rzeczywistości często prostsza, ponieważ nie musimy martwić się opcjonalnym dodawaniem lub usuwaniem, ponieważ izawsze można to zrobić poprawnie. Dla iprzypadków dopasowujemy znak podkreślenia oraz znak większy / mniejszy, ale w przeciwnym razie stosujemy podobną logikę. Ten dodaje spację przed i.

s`^_<(.*?) ?i
$1i

Ponownie podobny do powyższego, ale usuwa znak przed, ijeśli znak ten jest spacją, w przeciwnym razie usuwa tylko emotikon.

FryAmTheEggman
źródło
Możesz go zmniejszyć do 86 za pomocą: s`^_>(.*)i( |$)?=> s`^_>(.*)ii jego zamiana $1$#2$* i=> $1 i, i s`^_<(.*?)( )?i=> s`^_<(.*?) ?ii jego zamiana $1i$2=> $1i.
daavko,
@ mbomb007 Tak, przetestowałem to dla wszystkich 24 wejść. Nie znaleziono błędów.
daavko,
@daavko Dzięki! Wiedziałem, że leżą jakieś rzeczy od czasu, gdy skopiowałem te dwie sprawy, ale musiałem opuścić komputer wkrótce po opublikowaniu. Edytowane :)
FryAmTheEggman
7

Python, 142 141 134 122 121 bajtów

Zaoszczędzono 19 bajtów dzięki xnor.

def f(l,I=0,i=1):
    for a,_,b in l.split():I-=[I>0,-(i!=I+1)][a>'='];i-=[i!=I+1,-1][b>'=']
    return'.'*I+'I'+'.'*(i+~I)+'i'

Przykład:

>>> assert f('<_> >_> >_> >_> <_> <_<') == '.I...i'
>>> 

Wyjaśnienie:

def f(l, I=0, i=1):
    for a, _, b in l.split():
        I-= -(i!=I+1) if a == '>' else I > 0
        i-= -1 if b == '>' else i!=I+1

    return '.'*I + 'I' + '.'*(i-I-1) + 'i'
sklepienie
źródło
Liczba bajtów po wklejeniu wynosi 148 - wygląda na to, że wkleiłeś kod z dodatkowymi spacjami do odpowiedzi.
Celeo
@Celeo: każda linia w treści funkcji jest wcięta 1 znakiem tabulacji. Możesz to sprawdzić, klikając „edytuj”. Jednak SE renderuje kod z tabulatorami zastąpionymi 4 spacjami. Możliwe jest jednak wcięcie ciała funkcji 1 spacją zamiast 1 tabulacji.
vaultah
Nie izawsze pozostanie większy niż I?
xnor
@xnor: nie mogę uwierzyć, że mi tego brakowało :( Dzięki.
vaultah
1
@vaultah Myślę, że pozwala to uprościć linię do łączenia ciągów kropek I, kropek i, bez potrzeby tworzenia list i łączenia.
xnor
7

GNU sed, 81 bajtów

(w tym +1 za -rflagę)

#!/bin/sed -rf
s!<!s/ I/I /;!g
s!>!s/I / I/;!g
s!_(.{9})!\L\1!g
s!i !i!g
s/.*/echo Ii|sed '&'/e

Spowoduje to utworzenie nowego programu sed na podstawie danych wejściowych (które można zobaczyć, usuwając ostatni wiersz) i zastosowanie go do stanu początkowego Ii.

Wyjaśnienie

  • Pierwsze dwie linie konwertują <i >zastępują polecenia, które przesuwają odpowiednio w Ilewo i w prawo.
  • Następnie zmieniamy jeden następujące _pracować na izamiastI
  • i nie jest ograniczony żadną prawą krawędzią, więc nie dodawaj ani nie zajmuj miejsca po nim
  • Na koniec zastosuj utworzone polecenie do danych wejściowych Ii. s///ezawsze używa /bin/shjako powłoki, więc nie mogłem tego skrócić tak, sed '&'<<<Iijak chciałem (taka jest składnia przekierowań Bash).

Wyniki testu

$ for i in '' '>_>' '<_<' '>_<' '<_>' '>_> >_>' '>_> <_<' '>_> >_<' '>_> <_>' '<_< >_>' '<_< <_<' '<_< >_<' '<_< <_>' '>_< >_>' '>_< <_<' '>_< >_<' '>_< <_>' '<_> >_>' '<_> <_<' '<_> >_<' '<_> <_>' '>_> >_> <_>' '<_> >_> >_> >_> <_> <_<' '<_> >_> >_> >_> <_> <_< >_< <_< >_<' '>_> >_< >_> >_> >_> >_> >_> >_> <_> <_> <_<'
> do printf '%s => ' "$i"; ./74719.sed <<<"$i" | tr \  .; done | cat -n
     1   => Ii
     2  >_> => I.i
     3  <_< => Ii
     4  >_< => Ii
     5  <_> => I.i
     6  >_> >_> => .I.i
     7  >_> <_< => Ii
     8  >_> >_< => .Ii
     9  >_> <_> => I..i
    10  <_< >_> => I.i
    11  <_< <_< => Ii
    12  <_< >_< => Ii
    13  <_< <_> => I.i
    14  >_< >_> => I.i
    15  >_< <_< => Ii
    16  >_< >_< => Ii
    17  >_< <_> => I.i
    18  <_> >_> => .I.i
    19  <_> <_< => Ii
    20  <_> >_< => .Ii
    21  <_> <_> => I..i
    22  >_> >_> <_> => I...i
    23  <_> >_> >_> >_> <_> <_< => .I...i
    24  <_> >_> >_> >_> <_> <_< >_< <_< >_< => ..Ii
    25  >_> >_< >_> >_> >_> >_> >_> >_> <_> <_> <_< => ...I.....i
Toby Speight
źródło
7

JavaScript (ES6) 176 171 168 155 148 147 142 141 bajtów

//v8 - I was sure saving off math was saving a byte, thanks ETF
_=>_.split` `.map(m=>(I=m<'='?I-1||0:Math.min(i-1,I+1))+(i=m[2]=='<'?Math.max(I+1,i-1):i+1),i=1,I=0)&&'.'.repeat(I)+'I'+'.'.repeat(--i-I)+'i'

//v7 - not checking first char when I can check whole string - changed how I create end string (stolen from edc65)
_=>_.split` `.map(m=>(I=m<'='?I-1||0:M.min(i-1,I+1))+(i=m[2]=='<'?M.max(I+1,i-1):i+1),i=1,I=0,M=Math)&&'.'.repeat(I)+'I'+'.'.repeat(--i-I)+'i'

//v6 - one more byte
_=>_.split` `.map(m=>(I=m[0]=='<'?M(0,I-1):Math.min(i-1,I+1))+(i=m[2]=='<'?M(I+1,i-1):i+1),i=1,I=0,M=Math.max)+((a=Array(i))[I]='I')&&a.join`.`+'i'

//v5 - not filling array with '.', just joining with . later
_=>_.split` `.map(m=>(I=m[0]=='<'?M(0,I-1):Math.min(i-1,I+1))+(i=m[2]=='<'?M(I+1,i-1):i+1),i=1,I=0,M=Math.max)&&((a=Array(i))[I]='I')&&a.join`.`+'i'

//v4 - realized I didn't need to split >_> on _, just use the 0th and 2nd index
_=>_.split` `.map(m=>(I=m[0]=='<'?M(0,I-1):Math.min(i-1,I+1))+(i=m[2]=='<'?M(I+1,i-1):i+1),i=1,I=0,M=Math.max)&&((a=Array(i).fill`.`)[I]='I')&&a.join``+'i'

//v3 - saving Math to a var (thanks @Verzio)
_=>_.split` `.map(m=>(I=(m=m.split`_`)[0]=='<'?M(0,I-1):Math.min(i-1,I+1))+(i=m[1]=='<'?M(I+1,i-1):i+1),i=1,I=0,M=Math.max)&&((a=Array(i).fill`.`)[I]='I')&&a.join``+'i'

//v2 - as a single expression! (thanks @Downgoat)
_=>_.split` `.map(m=>(I=(m=m.split`_`)[0]=='<'?Math.max(0,I-1):Math.min(i-1,I+1))+(i=m[1]=='<'?Math.max(I+1,i-1):i+1),i=1,I=0)&&((a=Array(i).fill`.`)[I]='I')&&a.join``+'i'

//version 1
_=>{I=0;i=1;_.split` `.map(m=>(I=(m=m.split`_`)[0]=='<'?Math.max(0,I-1):Math.min(i-1,I+1))+(i=m[1]=='<'?Math.max(I+1,i-1):i+1));(a=Array(i).fill`.`)[I]='I';return a.join``+'i'}

Stosowanie

f=_=>_.split` `.map(m=>(I=m<'='?I-1||0:Math.min(i-1,I+1))+(i=m[2]=='<'?Math.max(I+1,i-1):i+1),i=1,I=0)&&'.'.repeat(I)+'I'+'.'.repeat(--i-I)+'i'


f(">_> >_< >_> >_> >_> >_> >_> >_> <_> <_> <_<")
//"...I.....i"

Degolfed (v6, v7 nie różni się zbytnio)

//my solution has changed slightly, but not significantly enough to redo the below

_=>                   //take an input
  _.split` `          //split to each command <_<
   .map(              //do something for each command (each command being called m)
     m=>              
       (I=            //set I to.... 'I will be the index of the letter I'
         m[0]=='<'?   //is the first char of the command '<'?
           Math.max(0,I-1)   //yes => move I to the left (but don't move past 0)
           :
           Math.min(i-1,I+1)  //no => move I to the right one, but keep it one less than i
       )

       +              //also we need to mess with i
       (i=
        m[2]=='<'?    //is the 3rd char of the command '<'?
          Math.max(I+1,i-1)  //yes => move i to the left, but keep it one right of I
          :
          i+1         //move i to the right (no bounds on how far right i can go)
       )

       ,i=1,I=0       //set I to 0 and i to 1 initially
     )
   +                  //this just lets us chain commands into one expression, not really adding
   (
    (a=Array(i))[I]='I') //create an array of length i (will be one shorter than we really need)
                         //set element I to 'I'

   &&                    //last chained command, we know the array creation will be true
                         //so javascript will just output the next thing as the return for the function
   a.join`.`+'i'         //join the array with '.' (into a string) and append i
                         //i will always be the last element
Charlie Wynn
źródło
3
Zamiast używać, =>{ ... }możesz zrobić wyrażenie i zaoszczędzić sporo bajtów
Downgoat
Skradałem się z rezygnacji z czasu w pracy i chciałem to podsumować :) Próbowałem się tego pozbyć, ale nie mogłem tego całkiem zrozumieć przed 4: P Spojrzę jeszcze raz
Charlie Wynn
1
Wskazówka: oszczędzaj sobie bajt i po prostu wypisz matematykę dwa razy.
ETHproductions
6

MATL , 56 55 50 49 47 bajtów

1Hj3\q4ZC"w@1)+lhX>yqhX<w@3)+yQhX>]tZ"105b(73b(

Wypróbuj online!

1           % push 1: initial position of 'I'
H           % push 2: initial position of 'i'
j           % take input as a string
4\q         % modulo 3 and subtract 1: this gives -1 for '<', 1 for '>'
4Zc         % arrange blocks of length 4 as columns of 2D array. This pads last 
            % block with a zero (because the separating space won't be there).
            % Only first and third and last rows will be used
"           % for each column
  w         %   swap: move position of 'I' to top of stack
  @1)       %   first number (+/-1) of current column: tells where the 'I' moves
  +         %   add
  lhX>      %   max with 1: 'I' cannot move left past position 1
  y         %   duplicate position of 'i'
  qhX<      %   max with that number minus 1: 'I' cannot collide with 'i'
  w         %   swap: move position of 'i' to top of stack
  @3)       %   last number (+/-1) of current column: tells where the 'i' moves
  +         %   add
  y         %   duplicate position of 'I'
  QhX>      %   max with that number plus 1: 'i' cannot collide with 'I'
]           % end for each
t           % duplicate position of 'I'. This is the output string length
Z"          % string with that many spaces
105b(       % set 'i' at its computed position in that string
73b(        % set 'I' at its computed position in that string
Luis Mendo
źródło
brak pasujących parenów + aparatów ortodontycznych
kot
2
@tac Haha. Przynajmniej cytuje „mecz”
Luis Mendo
5

Retina, 91 86 bajtów

Prawdopodobnie nie podjąłem najlepszego podejścia, więc prawdopodobnie można grać w golfa więcej. I nie, nie skopiowałem FryAmTheEggman (wiem, że są bardzo podobne w naszym podejściu). Nie widziałem nawet jego odpowiedzi, dopóki nie opublikowałem mojej.

$
¶Ii
(`^¶

sr`^<_(.*)( |)I
$1I$2
s`^>_(.*)I( ?)
$1$2I
sr`^<(.*) ?i
$1i
s`^>(.*)i
$1 i

Wypróbuj online

mbomb007
źródło
1
Nie potrzebujesz ( |)końca na ostatniej linii meczowej, ponieważ nigdy nie będzie już miejsca i. Również w przypadku ostatniej linii dopasowania nie potrzebujesz wspornika zamykającego dla pętli. Zamknięta pętla jest automatycznie zamykana na końcu pliku w Retinie.
daavko
Dzięki. Kiedyś miałem spacje po, ia potem coś zastępowałem. Zapomniałem je zmienić.
mbomb007
4

JavaScript (ES6) 166 bajtów

Korzystając z odpowiedzi Charliego Wynna, udało mi się zaoszczędzić 10 bajtów, definiując Math.max jako M i wywołując M za każdym razem, gdy jego skrypt używa

_=>{I=0;i=1;_.split` `.map(m=>(I=(m=m.split`_`)[0]=='<'?M=Math.max;M(0,I-1):M(i-1,I+1))+(i=m[1]=='<'?M(I+1,i-1):i+1));(a=Array(i).fill`.`)[I]='I';return a.join``+'i'}

(Nie napisałem tego golfa, zrobił to tutaj Charlie Wynn . Po prostu zmodyfikowałem go, aby go skrócić)

Verzlo
źródło
4
Witamy w PPCG! Tutaj komentujemy posty, które można ulepszyć. Jeśli nie masz (radykalnie) innego rozwiązania, skomentuj sugestię golfa w oryginalnym poście.
Conor O'Brien
2
Zrobiłbym to, ale nie mam wystarczającej reputacji, aby to zrobić.
Verzlo
1
Może pozostać, ale ludzie mogą kończyć głosowanie. Przepraszam. Myślę, że może zostać, ale inni nie.
Rɪᴋᴇʀ
1
Zamierzałem skomentować inną odpowiedź, którą wprowadziłeś, zanim zobaczyłem twoją odpowiedź. +1 na to! Ale twój kod rzuca się SyntaxError: missing : in conditional expressionna Firefox. Możesz to naprawić za pomocą _=>{I=0,i=1,M=Math.max;_.split` `.map(m=>(I=(m=m.split`_`)[0]=='<'?M(0,I-1):M(i-1,I+1))+(i=m[1]=='<'?M(I+1,i-1):i+1));(a=Array(i).fill`.`)[I]='I';return a.join``+'i'}tego samego dokładnego rozmiaru.
Ismael Miguel
1
Dostaję błąd składniowy w chrome
Charlie Wynn
4

JavaScript (ES6), 115 118

Edycja: 3 bajty zapisane dzięki CharlieWynn

a=>a.split` `.map(x=>x[x>'='?q&&(--q,++p):p&&(--p,++q),2]>'='?++q:q&&--q,p=q=0)&&'.'.repeat(p)+`I${'.'.repeat(q)}i`

poznacza liczbę spacji wcześniej I; qto liczba spacji między Ii i. Żaden nie może być negatywny.

Mniej golfa

a=>(
  a.split(' ').map( x=> (
    x>'='?q&&(--q,++p):p&&(--p,++q), // try to move I based on 1st char of x
    x[2]>'='?++q:q&&--q // try to move i based on 3rd char of x
  ) 
  , p=q=0), // starting values of p and q
  '.'.repeat(p)+'I' + '.'.repeat(q) +'i' // return value
)

Test

f=a=>a.split` `.map(x=>x[x>'='?q&&(--q,++p):p&&(--p,++q),2]>'='?++q:q&&--q,p=q=0)&&'.'.repeat(p)+`I${'.'.repeat(q)}i`

console.log=x=>O.textContent+=x+'\n'

;[['','Ii'],
['>_>','I.i'],
['<_<','Ii'],
['>_<','Ii'],
['<_>','I.i'],
['>_> >_>','.I.i'],
['>_> <_<','Ii'],
['>_> >_<','.Ii'],
['>_> <_>','I..i'],
['<_< >_>','I.i'],
['<_< <_<','Ii'],
['<_< >_<','Ii'],
['<_< <_>','I.i'],
['>_< >_>','I.i'],
['>_< <_<','Ii'],
['>_< >_<','Ii'],
['>_< <_>','I.i'],
['<_> >_>','.I.i'],
['<_> <_<','Ii'],
['<_> >_<','.Ii'],
['<_> <_>','I..i'],
['>_> >_> <_>','I...i'],
['<_> >_> >_> >_> <_> <_<','.I...i'],
['<_> >_> >_> >_> <_> <_< >_< <_< >_<','..Ii'],
['>_> >_< >_> >_> >_> >_> >_> >_> <_> <_> <_<','...I.....i']]
.forEach(t=>{
  var i=t[0],k=t[1],r=f(i)
  console.log(i +' -> '+r + (r==k?' OK':' KO (exp '+k+')'))
})
<pre id=O></pre>

edc65
źródło
Możesz go zapisać, jeśli .split`` .map (zamiast .replace (/ \ S + /, naprawdę podoba mi się sposób przechowywania odległości od I do I zamiast pozycji i. Chciałem zmienić mój na ale myślę, że będzie to twoje lustro.
Charlie Wynn
oszczędza 2 bajty! dzięki @CharlieWynn .. lub nawet 3
edc65
3

Siatkówka, 61 58 bajtów

3 bajty zapisane dzięki @FryAmTheEggman.

^
Ii 
(`( ?)I(.*i) <|I( ?)(.*i) >
$3I$1$2$4
 ?i_<
i
i_>
 i

Wyjaśnienie nastąpi nieco później.

Wypróbuj online!

Zmodyfikowany kod z testem wsadowym.

randomra
źródło
Ach Umieszczenie
liter
2

Python 2, 96 92 bajtów

f=lambda s,I=1,i=2:s and f(s[2:],i,I+cmp(s,'=')*(0<I+cmp(s,'=')!=i))or'%*c'*2%(I,73,i-I,105)

Całkiem szykowne rozwiązanie na zmienne wyzwanie. Wejście jak f('>_> <_>'), wyjście jak 'I i'.

Program weryfikacyjny (przy założeniu, że testsjest to ciąg wielowierszowego przypadku testowego):

for test in zip(*[iter(tests.replace("[empty string]", "").splitlines())]*4):
    assert f(test[1]) == test[2].replace('.',' ')

Program odczytuje każdą strzałkę pojedynczo, zaczynając od I=1, i=2i wykorzystując indeksy 1. Nazwy zmiennych są nieco mylące, ponieważ zamieniają się rolami - po każdym znaku Istaje się ii ijest Iaktualizowane. Znak jest aktualizowany tylko wtedy, gdy nie przesunąłby się ani na pozycję innego znaku, ani na pozycję 0.

Na przykład >_> <_> >_<wykonujemy:

Char     I (= i from previous iteration)        i
-----------------------------------------------------------------------------------------
         1                                      2
>        2                                      1+1 = 2 would overlap, so remain 1
>        1                                      2+1 = 3
<        3                                      1-1 = 0 is too low, so remain 1
>        1                                      3+1 = 4
>        4                                      1+1 = 2
<        2                                      4-1 = 3

To daje ' Ii'zgodnie z życzeniem.

Sp3000
źródło
0

Lua, 104 bajty

s='Ii'for v in(...):gmatch'%S_?'do
s=s:gsub(('>i$ i< ii>_I  I<_ II '):match(v..'(..)(%P+)'))end
print(s)

Stosowanie:

$ lua shifter.lua "<_> >_> >_> >_> <_> <_<"
 I   i
Egor Skriptunoff
źródło
0

JavaScript (ES5), 153 125 bajtów

pobiera dane wejściowe poprzez ustawienie zmiennej aprzed uruchomieniem

I=i=0;for(b of a.split(" "))b[0]==">"?i!=I&&I++:I>0&&I--,b[2]==">"?i++:I!=i&&i--;r=Array(i).fill(".");r[I]="I";r.join("")+"i"

Nieco golfisty:

I=i=0;
for(b of a.split(" "))
   b[0]==">" 
       ? i!=I && I++ 
       : I>0 && I--,
   b[2]==">" 
       ? i++ 
       : I!=i && i--
;
r=Array(i).fill(".");
r[I]="I";
r.join("")+"i"
Jan
źródło
0

Mathematica, 125 bajtów

Fold[StringReplace,"Ii",StringCases[#,"<_"|">_"|">"|"<"]/.{"<_"->".I"->"I.",">_"->"I."->".I","<"->".i"->"i",">"->"i"->".i"}]&

Czysta funkcja z pierwszym argumentem #. Chodzi o to, że każdy <_, >_, <, i >na wejściu odpowiada z reguły zastępowania znaków. "<_"|">_"|">"|"<"to ciąg znaków pasujący do dowolnego z tych czterech wyrażeń. StringCases[#,"<_"|">_"|">"|"<"]znajdzie wszystkie takie dopasowania. Następnie zastępujemy ( /.) każdą "<_"regułą zastępowania łańcucha ".I"->"I.", każdą ">_"regułą "I."->".I"i tak dalej. Następnie chcę sekwencyjnie zastosować każdą regułę zamiany do łańcucha "Ii", ale StringReplacebędę szukał tylko dopasowań w częściach łańcucha, które nie zostały zamienione, więc zostawiliśmy Foldfunkcję StringReplacenad listą reguł zastępowania z wartością początkową "Ii".

Być może byłoby to bardziej zrozumiałe na przykładzie (tutaj %odnosi się do wyjścia poprzedniej komórki):

wprowadź opis zdjęcia tutaj

ngenisis
źródło