> <> Fuori dall'acqua


20

L'amato pesce che nuota attraverso il codice di > <> (un linguaggio di programmazione esoterico) è stato tolto dal suo ambiente naturale. Questo cambiamento lo ha reso incapace di muoversi nel modo in cui era solito: quello che era un movimento toroidale era limitato al semplice movimento da sinistra a destra. Ma i programmi> <> sono ancora scritti come se il pesce fosse in grado di attraversarli. È tuo compito, caro programmatore, scrivere un programma per linearizzare un programma> <>. E fallo nel minor numero di byte possibile; i pesci non hanno ricordi molto grandi.

Movimento in> <>

In> <>, il movimento è toroidale e un carattere alla volta. Ciò significa che il pesce (il puntatore) può "avvolgere" dalla fine di una linea all'inizio. In> <>, il pesce è anche in grado di spostarsi dall'alto verso il basso, dal basso verso l'alto e da destra a sinistra, in contrasto con il modo in cui si muovono i puntatori. Quindi questo schema di movimento sarebbe valido:

>>>^  >>>v
   >>>^  v

e finirebbe con un ciclo infinito (tornando alla riga superiore una volta che passa infinitamente il fondo).

Il pesce si muove in una griglia di lunghezza uguale a max (lunghezza della fila) e altezza uguale al numero di file.

Come capisci in che modo si muove il pesce? Questi comandi cambiano il vettore di direzione del movimento (ad es. (-1,0)Significa da destra a sinistra):

Command | Direction Change
---------------------------
   >    | (1,0) (default)
   <    | (-1,0)
   ^    | (0,1)
   v    | (0,-1)
   /    | (x,y) -> (y,x)
   \    | (x,y) -> (-y,-x)
   |    | (x,y) -> (-x,y)
   _    | (x,y) -> (x,-y)
   #    | (x,y) -> (-x,-y)
   ;    | (0,0)

Come notato, il pesce inizia a muoversi da sinistra a destra, cioè con il vettore di direzione (1,0). Il pesce inizia ad analizzare i comandi a partire dal primo comando che vede e cambia direzione se un comando corrisponde a uno dei suddetti cambi di direzione.

Il pesce smette di muoversi quando vede un ;e termina il programma.

Ingresso

L'ingresso sarà un programma valido (ad es. Non loop continuo) fornito tramite STDIN. Se lo desideri, puoi anche leggere un file. Le linee di ciascun programma non avranno necessariamente la stessa lunghezza.

L'input è dato come una stringa, con le nuove righe che separano ogni riga nel programma.

I programmi non eseguiranno il loop, il che significa anche che termineranno sempre con a ;.

Produzione

L'output sarà il programma linearizzato. Cioè, dovresti restituire tutti i personaggi (inclusi i cambi di direzione) che il pesce vedrebbe se eseguisse il programma "normalmente". Questo è tutti i personaggi nel suo percorso verso ;.

Se l'input ha linee di lunghezza disuguale e il pesce finisce per muoversi lungo una linea più corta della lunghezza della linea più lunga, dovresti trattarlo come se il pesce si stesse muovendo su uno spazio (vedi casi di test).

Chi ha familiarità con> <> saprà che i cambi di direzione non sono l'unico modo per fare movimento in esso, ma per semplicità trattano l'input come se fossero l' unico modo per influenzare il movimento.

Regole

  1. Si applicano scappatoie standard
  2. È possibile scrivere un programma completo o una funzione
  3. L'input viene fornito tramite STDIN o un file come stringa contenente le righe del programma separate da newline ( \n)
    • Puoi prendere l'input in modo diverso, entro limiti ragionevoli (sentiti libero di chiedermi se hai in mente un tipo specifico di input). Non è possibile riempire l'input con spazi in modo che la lunghezza della linea corrisponda.
    • Fare riferimento a questo meta post per quanto riguarda l'input flessibile. Per quanto riguarda la pubblicazione, il consenso generale deve essere il più flessibile possibile entro limiti ragionevoli.
  4. L'output è una singola stringa tramite STDOUT o restituito dalla funzione (a seconda di ciò che si sceglie di fare, vedere la regola 2)

Casi test

v     >v
>abcv//;
gfed<^ih

v>abcv<defghi^//>v;



v     >v
>abcv//;
gfed<^

v>abcv<defg  ^//>v;


abcdef;

abcdef;


abcd|;

abcd|dcba;


abcd#;

abcd#dcba;


abcd\;
    _

abcd\_\dcba;


^;
>abcde/
 ^jihg<

^ >abcde/ <ghij^a;


;

;

2
Possiamo prendere l'input come una matrice di stringhe?
Luca

2
Possiamo supporre che il primo carattere (quello in alto a sinistra) non sia un punto e virgola?
Kritixi Lithos,

1
@KritixiLithos bella domanda, sto per dire che non puoi supporre che. Aggiungerò un caso di prova.
Cole

1
@Luke puoi prendere l'input come una matrice di stringhe se è molto difficile o impossibile operare sul formato di input (stringa con linee separate da newline). Vedi la regola 3 ora aggiunta
Cole

3
Voto obbligatorio per assurda logica
Patrick Roberts

Risposte:


13

Röda , 405 393 392 391 371 366 361 236 234 232 230 223 200 byte

F f{L=f()|[#_]|sort|tail
c=""x=0
y=0
X=1
Y=0{l=f[y]l.=[" "]*(L-#l)c=l[x]a=X
[c]
C=indexOf(c,`><v^/\|_#`)X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]x+=X
x=x%L
y+=Y
y=y%#f}until[c=";"]}

Provalo online!

Controlla le uscite!

Spiegazione (obsoleta)

F f{                          /* Declares a function F with parameter f */
                              /* Takes a 2D array of single-char Strings as f */
L =                           /* L contains the value of the length of the longest line*/
    f()                       /* Push the contents each element of f to the stream; this pushes each line*/
        | [#_]                /* Pull a line and push its length to the stream*/
               |sort|tail     /* Sort it and get the last value (the largest one) */
c=""                          /* c contains the value of the current char that is being processed */
x=0; y=0                      /* x and y contain the position of the fish */
X=1; Y=0                      /* X and Y contain the direction of the fish */
{ ... }while [c != ";"]       /* While c is not `;` do: */
l=f[y]                        /*  l is the line (row) the fish is at */
c=" " if [x >= #l]            /*  If x is more than or equal to the line's length, set c to a space (so that we don't need to pad spaces to the array at the beginning)*/
else c = l[x]                 /*  Else set c to the character a position x of l*/
[c]                           /*  Push c to the output stream; ie prints c without a trailing newline*/
a = X                         /*  a preserves the value of X before analysing c */
C = indexOf(c,`><v^/\|_#`)    /*  Simple enough */
X=[1,-1,0,0,-Y,Y,-X,X,-X,X][C]/*  Map each value of C to their respective X-direction in the array */
                              /*  If c cannot be found in `><v^/\|_#` then it will be given the value of -1, or in other words, the -1th element of an array its last element */
Y=[0,0,1,-1,-a,a,Y,-Y,-Y,Y][C]/*  Do the same thing for Y */
x += X                        /*  Change the x-pos by the X-direction */
x = x%L                       /*  Wrap around the right edge */
y += Y                        /*  Do the same for y */
y=y%#f                        /*  But wrap around the bottom instead */
x+=L if[x<0]                  /*  Wrap around the left */
y+=#f if[y<0]                 /*  Wrap around the top */
}

Le modifiche

  • 10 byte salvati grazie a @fergusq usando %invece di controllare se x o y è oltre i confini, che ha spianato la strada per altri 2!
  • Usato al `\`posto di"\\"
  • Passato c=""alla seconda riga e quindi rimosso la nuova riga successiva
  • Sposta la conversione delle linee in array a carattere singolo nei loop anziché all'inizio (ispirato alla risposta di Python)
  • Usata la sintassi del controvento di while(grazie a @fergusq per averlo individuato)
  • Spostato le a=Xistruzioni if
  • Grazie a @fergusq per aver trovato un modo più breve per trovare la lunghezza della linea più lunga
  • Usata la sintassi dell'array invece delle istruzioni if ​​(come la risposta Python) per risparmiare tonnellate di byte
  • Rimosso il codice che riempiva gli spazi, invece gli spazi vengono aggiunti man mano che si sposta> <>
  • Risolto un bug grazie e giocato a un personaggio grazie a @fergusq
  • Rimosso il codice alla +1fine indexOfe ristrutturato per salvare 2 byte
  • Hai salvato 2 byte spostando le cose (grazie di nuovo a @fergusq)
  • Salvato 1 byte grazie a @fergusq utilizzando un metodo diverso di spazi di riempimento
  • Salvato 1 byte utilizzando until[c=";"]invece diwhile[c!=";"]
  • Grazie a un suggerimento di @fergusq, ho rimosso il loop che riempie gli spazi e lo ho sostituito l.=[" "]*L
  • Salvato oltre 20 byte rimuovendo le istruzioni if ​​alla fine che avvolgono il programma attorno ai bordi sinistro e superiore

Penso che puoi salvare qualche byte usando x=((x+X)%#l)invece di x+=X. Sfortunatamente, (-1)%#lritorna ancora -1.
Fergusq,

@fergusq ha golfato il tuo suggerimento :)
Kritixi Lithos il

Si può usare con ytroppo: y=y%#f.
Fergusq,

@fergusq Stavo per aggiungerlo :)
Kritixi Lithos il

Ci ho pensato di più, qui ci sono altri due consigli sul golf: usare keyinvece di cmpe usare {...}while[...]invece di while[...]do ... done.
Fergusq,

10

Python 2, 262 243 237 235 234 233 231 221 219 218 217 byte

Accetta input come ['<line_1>', '<line_2>', ...]

i=input()
q=max(map(len,i))
i=[k+' '*q for k in i]
x=y=k=0
j=1
o=''
while';'not in o:r=[1,-1,-j,-k,0,0];o+=i[y][x];l='><#\\v^/|_'.find(o[-1]);a=(r+[k,-j,j])[l];k=([k,-k,k,j]+r)[~l];j=a;x=(x+j)%q;y=(y-k)%len(i)
print o

Provalo online!

-19 byte grazie a @math_junkie
-6 byte grazie a @ThisGuy
-2 byte estraendo max(map(L,i))in una variabile (perché teoricamente viene usato due volte).
-1 byte riducendo il numero di volte che i[y][x]compare.
-1 byte usando '\x00'quindi non devo fare la [1:]parte o[1:]dell'output
-2 byte usando \0invece di \x00
-10 byte grazie a @KritixiLithos per rendermi conto che posso pad quanto voglio sul lato destro perché il extra verrà ignorato
(nessuna modifica di byte) bug corretto perché la variabile estratta era al di fuori del ciclo
-2 byte perché ora uso solo len2 volte, quindi la riassegnazione richiede 2 byte aggiuntivi
-2 byte usando while';'not in oinvece diwhile o[-1]!=';'e usando o=''invece di o='\0'. Questo non solo salva 2 byte, ma elimina anche il byte null iniziale che tecnicamente non era realmente valido.

Spiegazione

i = input()                       # Takes input as an array of strings
q = max(map(len,i))               # Finds the width of the longest line
i = [k + ' ' * q for k in i]      # Makes sure everything is at least that width
x = y = k = 0                     # Set the point to (0, 0). Set the vertical motion to 0
j = 1                             # Set the horizontal motion to 1
o = '\0'                          # Initialize the output to a null byte (this is output as nothing, so it doesn't actually affect output)
while o[-1] != ';':               # While the last character in the output is not ';' (this is why the output needs to be initialized with something, otherwise o[-1] gives an index error)
    r = [1,-1,-j,-k,0,0]          # Some of the vertical and horizontal coordinates correspond in opposite order
    o += i[y][x]                  # Add the current character to the output
    l = '><#\\v^/|_'.find(o[-1])  # Find the index of the current character here (or -1 if it's just a regular character)
    a = (r + [k, -j, j])[l]       # The fancy array contains the horizontal movement for each control character
    k = ([k, -k, k, j] + r)[~l]   # The fancy array contains the vertical movement for each control character. Using ~l to get the right index, because r has the values backwards
    j = a                         # a was a placeholder because otherwise k would not be correct
    x = (x + j) % q               # Adjust the pointer position
    y = (y - k) % len(i)          # Adjust the pointer position
print o                           # Print the output after the loop is finished

Puoi giocare a golf trydai findritorni da -1quando non lo trovi: TIO
drogato di matematica

@math_junkie Oh okay, grazie!
HyperNeutrino,

È possibile assegnare lena una variabile, ad esempio Lper salvare 3 byte e altri 4 modificando l'assegnazione multilinea 0in 1 riga x=y=k=0.
caird coinheringaahing

@ThisGuy Grazie!
HyperNeutrino,

2
@Cole Nel mio golf suggerito, ho aggiunto j e k alla fine di ogni array. È così che la direzione viene mantenuta
drogato di matematica il

5

Rubino, 274 200 187 183

Rasato fuori solo un paio di caratteri facendo cadere la matrice di moto, d.

Sono abbastanza orgoglioso di questo. È stato divertente! Accetta una matrice di stringhe e restituisce la stringa corretta.

->a{o,x,y='',-1,0
b,m=1,0
(o+=n=a[y=(y+m)%a.size][x=(x+b)%(a.map &:size).max]||' '
b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[2*('><^v/\\|_#'.index(n)||9),2])until o[?;]
o}

Commentato di seguito.

->a{
    o,x,y='',-1,0  # o is the output string, x and y are the positions in the array
    b,m=1,0          # b and m are the direction of momentum
    until o[?;] # until o contains a semicolon
        w=(a.map &:size).max # w is the max width of the arrays
        h=a.size    # h is the height of arrays
        x=x+b % w   # increment cursor position
        y=y+m % h
        o+=n=a[y][x]||' ' # add the new char (or " ") to o
        ix=2*('><^v/\\|_#'.index(n)||9) # find the index new char in the string
        b,m=([1]+[0,-1,0]*2+[1,-m]+[-b,m,b]*2+[-m,-b,-m,b,m])[ix,2] # set momentum to its new value
    end
    o # return output string
}

1

PHP 7, 291 260 byte

for($m=max(array_map(strlen,$z=explode("
",$argv[1]))),$y=0,$r=count($z)-$v=1;';'!=$c;[$v,$w]=[[$v,1,-1,0,0,-$w,$w,-$v,$v,-$v][$o=strpos(' ><^v/\|_#',$c)],[$w,0,0,-1,1,-$v,$v,$w,-$w,-$w][$o]],$x+=$m+$v,$x%=$m,$y=0<=($y+=$w)?$r<$y?:$y:$r)echo$c=$z[$y][$x]??' ';

Conto 291 byte / caratteri.
HyperNeutrino,

Hai ragione, non riesco a contare apparentemente = P
chocochaos

Hah Non preoccuparti, l'ho fatto anche io.
HyperNeutrino,

Ho trovato alcune cose da golf, portando questo dal 25% a 218 byte. Non testato, ma sicuramente vale la pena dare un'occhiata .
Tito

2
un difetto in uno dei miei campi da golf e altri sei byte nel golf: elenco di golf aggiornato .
Tito

1

JavaScript, 242 236 235 231 220 byte

a=>{n=a.length;m=x=y=p=0;a.map(g=>m=(w=g.length)<m?m:w);q=1,o="";while((t=a[y][x]||" ")!=";")o+=t,h=q,q=[q,1,0,p,-q][(s=">v\\| <^/_#".indexOf(t)+1)%5]*(r=s>5?-1:1),p=[p,0,1,h,p][s%5]*r,x=(x+q+m)%m,y=(y+p+n)%n;return o+t}

Provalo online!


puoi salvare 13 caratteri se prendi la stringa come un array. Le specifiche sono state modificate.
Non che Charles
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.