Rompere le schede a metà


31

Le guerre sante sono state combattute su spazi contro schede. (E ovviamente gli spazi, essendo oggettivamente superiori, hanno vinto.) - Alex A.

S ome peo p le rifiutano ancora di un ccept che WHI c h è cl e arly s upreme. Hai appena ricevuto un file utilizzando l'INCOR re ct, b annuncio e inf e sotto forma di rior WHI t espace, e ora t E lui cont e nti del file di un R e macchiata e rovinata.

Decidi che potresti anche mostrare alla persona che ti ha inviato il file quanto sbagliano, violentemente.

Descrizione

Come suggerisce il titolo, la tua sfida è quella di prendere un file che contiene una o più schede:

this is an evil tab    onoes

e spietatamente frantumali in pezzi:

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Si noti che il software Stack Exchange trasforma le schede letterali in quattro spazi (perché è giusto), quindi le schede all'interno di questo post verranno visualizzate come quattro spazi. L'input per il tuo programma, tuttavia, conterrà schede effettive.

Sfida

La soluzione dovrebbe assumere una singola stringa come input, che può contenere ASCII, newline e tab stampabili. Ci sarà sempre almeno una singola scheda nell'input.

L'output dovrebbe essere la stessa stringa, con le seguenti regole applicate:

  • Inizia il cursore alle coordinate (0,0) e con una direzione di destra. Le coordinate sono (colonna, riga), a zero, e la direzione è il modo in cui dovresti spostare il cursore dopo aver stampato un carattere.

  • Per ogni carattere nella stringa:

    • Se si tratta di una nuova riga, passa alle coordinate (0, n), dove n è il numero di nuove righe nella stringa finora (inclusa questa) e reimposta la direzione verso destra.

    • Se è una scheda, genera due spazi, ruota la direzione del cursore di 90 gradi in senso orario e genera altri due spazi, "rompendo" la scheda in modo efficace a metà. Ecco un esempio visivo, in cui una scheda è rappresentata da --->e spazi come ·:

      foo--->bar--->baz
      

      diventa

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • Altrimenti, basta semplicemente emettere il carattere sul cursore e spostare il cursore di un passo nella direzione corrente.

Dato che stai leggendo la stringa dall'inizio alla fine, è possibile che tu debba scrivere "in cima" ai caratteri esistenti — questo va bene. Ad esempio, l'input

foo--->bar


spaces are superior

dovrebbe risultare in un output di

foo

     b
spaces are superior
     r

Puoi scegliere se le "schede spezzate" debbano sovrascrivere altri personaggi - l'intenzione originale era che non lo facessero, ma le specifiche erano ambigue, quindi questa è la tua decisione.

Inoltre, dopo aver applicato queste regole, puoi anche

  • aggiungi o rimuovi tutti gli spazi finali che desideri.

  • aggiungere un massimo di una nuova riga finale.

L'input non conterrà mai spazi finali; inoltre non conterrà mai nuove righe iniziali o finali. Puoi anche sempre presumere che non dovrai mai scrivere su una colonna o una riga inferiore a 0 (cioè fuori dallo schermo).

Caso di prova

Le schede in questo caso di test sono rappresentate come --->perché altrimenti SE le divora.

Ingresso:

Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah

Produzione:

Test case. Here's a tab
blah
blah                     t
blah blah blah blah blah blah
                        blaablah
                         r     b
                         e     l  b
                      h  'h    a  l
                      a  sa    a  a
                      l   l    h  h
       this is some mobe tbxt

                         haalhalb
     b                   a
     a                   b
     t

        bat a erehwyreve

Animazione di fantasia:

Regole

  • Questo è , quindi vincerà il codice più breve in byte!

Quando dici che il cursore deve iniziare su (0,0)vuoi dire che dobbiamo prima cancellare la console o intendi semplicemente la posizione predefinita del cursore con quella?
Martin Ender,

18
Sto votando per chiudere questa domanda come fuori tema perché è piena di odio e blasfemia.
aditsu,

1
La tua animazione assomiglia così tanto all'interprete> <> che ora voglio vedere una voce automodificante> <>.
Sanchises,

1
Mi è piaciuto il messaggio nascosto nel paragrafo iniziale ma non sono d'accordo.
wf4,

@ MartinBüttner Significa solo la posizione predefinita.
Maniglia della porta

Risposte:


8

MATLAB, 144 byte

L'arma preferita per gestire le stringhe è ovviamente un linguaggio progettato per manipolare i numeri [citazione necessaria]. Scherzi a parte, la cosa grandiosa di Matlab è che non gli importa se si assegna a un array "fuori limite": creerà semplicemente una matrice più grande. Inoltre, l'elemento matrice predefinito 0, viene visualizzato come spazio anziché come nullcarattere prescritto dalle specifiche ASCII.

Le schede sono semplicemente un salto nelle coordinate, quindi non viene emesso spazio per una scheda.

function o=q(t)
u=2;v=0;x=1;y=1;n=1;for s=t
if s==9 x=x+u-v;y=y+v+u;a=v;v=u;u=-a;elseif s<11
n=n+1;x=1;y=n;else
o(y,x)=s;x=x+u/2;y=y+v/2;end
end

Ho iniziato con 209 byte, ma alcuni golfisti più attenti si sono sbarazzati di gran parte di ciò; c'è molta ripetizione in questo codice, quindi ho fatto qualche prova ed errore quali alternative hanno funzionato meglio. Non credo che ci sia molto spazio per una maggiore ottimizzazione con questo codice, ma sono sempre felice di essere smentito. Modifica: Tom Carpenter è riuscito a dimostrarmi che mi sbagliavo; è riuscito a salvare 9 byte che ho ottimizzato per salvare ben 29 byte. Ultimo byte salvato supponendo che non vi siano caratteri di controllo (ASCII <9) nell'input - le stringhe MATLAB non vengono nullterminate.


Non sembra funzionare. Ho provato questo q('hello<tab>my name<tab>is tom<tab>c'), ma è qualcosa del genere Attempted to access o(11,-2); on line 7. Anche se questo potrebbe avere più a che fare con un problema nella domanda: se il cursore si sta spostando all'indietro e oltrepassa la prima colonna, cosa succede al resto della riga.
Tom Carpenter,

Sì, il mio male mi è mancato un po '. Ora me ne vado;)
Tom Carpenter il

1
Puoi salvare altri 9 caratteri rimuovendo la dvariabile e invece avendo 4 variabili che per un ciclo rendono il modello [1 0 -1 0] come tale: function o=q(t) u=1;v=0;w=-1;z=0;x=0;y=1;n=1;for s=t if s==9 x=x+2*u-2*v;y=y+2*v+2*u;a=z;z=w;w=v;v=u;u=a;elseif s==10 n=n+1;x=0;y=n;else x=x+u;y=y+v;o(y,x)=s;end end (ovviamente essendo nei commenti ha rimosso tutte le righe, quindi avrai riformattarlo come il tuo per vedere cosa ho fatto)
Tom Carpenter,

@TomCarpenter Questo è ... davvero brutto. Lo adoro.
Sanchises,

5

Python 3, 272 270 266 262 255 253 244 byte

I=[]
try:
 while 1:I+=[input()]
except:r=m=0
M=sum(map(len,I))
O=[M*[' ']for _ in[0]*M]
for l in I:
 x=b=0;y=r;a=1;r+=1
 for c in l:
  if'\t'==c:a,b=-b,a;x+=a+2*b;y+=b-2*a
  else:O[y][x]=c
  x+=a;y+=b;m=max(m,y)
for l in O[:m+1]:print(*l,sep='')

Il \tdovrebbe essere un vero e proprio carattere di scheda.

Il codice funziona un po 'come risposta Zach Gates', generando un primo Mda Mgriglia in cui Mè la somma delle lunghezze delle linee. (È un'enorme quantità di eccesso, ma rende il codice più breve.) Quindi passa in rassegna i personaggi, posizionandoli nei punti corretti, tenendo traccia della riga visitata più in basso. Infine, stampa tutte le linee fino a quella riga.

L'output contiene (di solito una grande quantità di) spazi finali e 1 riga finale finale.


3

Javascript (ES6), 264 245 byte

Ho provato l'approccio "creare una griglia gigante di spazi, riempire e tagliare", che è risultato più corto di 19 byte rispetto all'altro.

a=t=>(o=`${' '.repeat(l=t.length)}
`.repeat(l).split`
`.map(q=>q.split``),d=x=y=z=0,s=c=>o[d>2?y--:d==1?y++:y][d?d==2?x--:x:x++]=c,[...t].map(c=>c=='\t'?(s` `,s` `,++d,d%=4,s` `,s` `):c==`
`?(x=d=0,y=++z):s(c)),o.map(p=>p.join``).join`
`.trim())

Modificando la penultima riga in questo modo, puoi rimuovere la grande quantità di spazi finali su ogni riga:

...o.map(p=>p.join``.trimRight())...

Provalo qui:

Spiegazione in arrivo; suggerimenti benvenuti!


3

JavaScript (ES6), 180 183

Usando le stringhe di modello, ci sono alcune nuove righe che sono significative e contate.

Questa è una funzione che restituisce l'output richiesto (riempito con tonnellate di spazi finali)

C'è poco da spiegare: le file sono costruite come necessarie. Non esiste una variabile di direzione, ma solo l'offset 2 per xey, poiché in senso orario sono facilmente gestibili:dx <= -dy, dy <= dx

Prova a eseguire lo snippet di seguito in Firefox

f=s=>[...s].map(c=>c<`
`?(x+=2*(d-e),y+=2*(e+d),[d,e]=[-e,d]):c<' '?(y=++r,e=x=0,d=1):(t=[...(o[y]||'')+' '.repeat(x)],t[x]=c,o[y]=t.join``,x+=d,y+=e),o=[r=x=y=e=0],d=1)&&o.join`
`

// TEST  

// Avoid evil tabs even in this source 
O.innerHTML = f(`Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah`
 .replace(/--->/g,'\t'))
<pre id=O></pre>


Vorrei che tutte le lingue avessero [x, y] = [expr1, expr2] ...
Sanchises

1

Python 2, 370 369 368 byte

Grazie a @sanchises e @ edc65 per avermi salvato un byte ciascuno.

J=''.join
u=raw_input().replace('\t','  \t  ')
w=u[:]
G=range(len(u))
d,r=0,[[' 'for _ in G]for _ in G]
u=u.split('\n')
for t in G:
 x,y=0,0+t
 for c in u[t]:
  if c=='\t':d=(d+1)%4
  if c!='\t':
   if c.strip():r[y][x]=c
   if d<1:x+=1
   if d==1:y+=1
   if d==2:x-=1
   if d>2:y-=1
r=r[:max(i for i,n in enumerate(r)if J(n).strip())+1]
for i in r:print J(i).rstrip()

Genera la griglia più grande possibile e quindi gira, carattere per carattere, cambiando direzione in ogni scheda.


Suggerimento: if !deif d>2
Sanchises,

!dnon è una sintassi valida. @sanchises Grazie per la d>2punta, però.
Zach Gates,

Mi dispiace, in realtà non conosco Python :) Ho pensato che avrebbe funzionato così.
Sanchises,

Anch'io non capisco python, ma se d in 0 ... 3, d==0->d<1
edc65

Sì, hai ragione. Grazie per il byte. @ edc65
Zach Gates,
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.