Zigzagify a String


46

Scrivi un programma (o una funzione) che accetta una stringa non vuota di qualsiasi carattere ASCII stampabile .

Stampa (o restituisce) una catena a zig-zag dei caratteri nella stringa con ogni coppia di caratteri adiacenti collegata da:

  • /se il primo carattere appare prima del secondo carattere nell'ordine ASCII normale. per esempio

      B
     /
    A
    
  • \se il primo carattere appare dopo il secondo carattere nell'ordine ASCII normale. per esempio

    B
     \
      A
    
  • -se il primo e il secondo carattere sono uguali. per esempio

    A-A
    

Quindi l'output per Programming Puzzles & Code Golfsarebbe

                                                        o    
                                                       / \   
  r                         z-z               o   e   G   l  
 / \                       /   \             / \ / \ /     \ 
P   o   r   m-m   n       u     l   s   &   C   d           f
     \ / \ /   \ / \     /       \ / \ / \ /                 
      g   a     i   g   P         e                          
                     \ /                                     
                                                             

Se nella stringa di input è presente un solo carattere, l'output sarebbe proprio quel carattere.

Il vostro programma dovrebbe trattare , /, \, e -proprio come tutti gli altri personaggi.

ad es. -\//-- \ //- dovrebbe produrre:

      \                      
     / \                     
    -   /-/                  
   /       \                 
 -          ---   \   /-/    
               \ / \ /   \   
                          -  
                           \ 
                             

Non dovrebbero esserci newline estranee nell'output tranne una singola newline finale opzionale. (Si noti che la riga vuota nell'esempio appena sopra contiene l'ultimo spazio nella stringa e quindi non è estranea.) Potrebbero esserci spazi finali su qualsiasi riga in qualsiasi disposizione.

Vince il codice più breve in byte.

Un altro esempio: input:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

Produzione:

                          9   9       8   6   6                                                                                                                                                            
                         / \ / \     / \ / \ / \                                                                                                                                                           
            9   6       8   7   3   3   4   2   4     8       9       8-8                                                                                                                                  
           / \ / \     /         \ /             \   / \     / \     /   \                                                                                                                                 
      4   5   2   5   5           2               3-3   3   7   5   2     4   9       9   9-9   7                                                                                                          
     / \ /         \ /                                   \ /     \ /       \ / \     / \ /   \ / \                                                                                                         
3   1   1           3                                     2       0         1   7   6   3     3   5       8                             8   6                                                              
 \ /                                                                             \ /               \     / \                           / \ / \                                                             
  .                                                                               1                 1   5   2   9             9   3   7   1   4   6   8                                                   9
                                                                                                     \ /     \ / \           / \ / \ /         \ / \ / \                                                 / 
                                                                                                      0       0   7   9     5   2   0           0   2   6       9-9               8   5   4             7  
                                                                                                                   \ / \   /                             \     /   \             / \ / \ / \           /   
                                                                                                                    4   4-4                               2   8     8           4   2   3   2     7   6    
                                                                                                                                                           \ /       \         /             \   / \ /     
                                                                                                                                                            0         6   8   3               1-1   0      
                                                                                                                                                                       \ / \ /                             
                                                                                                                                                                        2   0                              

Risposte:


8

Pyth, 69 byte

aY,JhzZVtzaY,@"-\/"K-<NJ>N~JN=+ZKaY,N=+ZK;jbCmX*\ h-e=GSeMYhG-edhGhdY

Dimostrazione. Gli input più lunghi funzionano ancora, ma non sembrano molto buoni nella casella di output a larghezza fissa.

Comincio costruendo un elenco, in Y, di tuple [carattere, altezza]. È [['P', 0], ['/', -1], ['r', -2], ['\\', -1], ['o', 0], ['\\', 1], ['g', 2]]presto Programming Puzzles & Code Golfnell'esempio.

Quindi creo stringhe di spazi della lunghezza appropriata, inserisco il carattere nella posizione appropriata, traspondo, unisco su nuove linee e stampo.


7

Julia, 297 byte

s->(l=length;d=sign(diff([i for i=s]));J=join([[string(s[i],d[i]>0?:'/':d[i]<0?:'\\':'-')for i=1:l(d)],s[end]]);D=reshape([d d]',2l(d));L=l(J);E=extrema(cumsum(d));b=2sumabs(E)+1;A=fill(" ",L,b);c=b-2E[2];for (i,v)=enumerate(J) A[i,c]="$v";i<l(D)&&(c-=D[i])end;for k=1:b println(join(A'[k,:]))end)

Ungolfed:

function f(s::String)
    # Get the direction for each slash or dash
    # +1 : /, -1 : \, 0 : -
    d = sign(diff([i for i in s]))

    # Interleave the string with the slashes as an array
    t = [string(s[i], d[i] > 0 ? '/' : d[i] < 0 ? '\\' : '-') for i = 1:length(d)]

    # Join the aforementioned array into a string
    J = join([t, s[end]])

    # Interleave D with itself to duplicate each element
    D = reshape(transpose([d d]), 2*length(d))

    # Get the length of the joined string
    L = length(J)

    # Get the maximum and minimum cumulative sum of the differences
    # This determines the upper and lower bounds for the curve
    E = extrema(cumsum(d))

    # Get the total required vertical size for the output curve
    b = 2*sumabs(E) + 1

    # Get the beginning vertical position for the curve
    c = b - 2*E[2]

    # Construct an array of spaces with dimensions corresponding
    # to the curve rotated 90 degrees clockwise
    A = fill(" ", L, b)

    # Fill the array with the curve from top to bottom
    for (i,v) = enumerate(J)
        A[i,c] = "$v"
        i < length(D) && (c -= D[i])
    end

    # Print out the transposed matrix
    for k = 1:b
        println(join(transpose(A)[k,:]))
    end
end

5

Javascript (ES6), 360 331 316 302 byte

Ecco il mio quarto tentativo:

s=>{r=[],c=s[m=w=n=0];for(i in s)(i?(d=s[++i])>c?++n:c>d?--n:n:n)<m&&m--,n>w&&w++,c=d;for(i=0,n=w*2;i<(w-m)*2+1;r[i++]=[...' '.repeat(l=s.length*2-1)]);for(i=0;i<l;i++)i%2?(A=s[C=(i-1)/2])<(B=s[C+1])?r[--n,n--][i]='/':A>B?r[++n,n++][i]='\\':r[n][i]='-':r[n][i]=s[i/2];return r.map(x=>x.join``).join`
`}

Non basso come alcuni degli altri, ma per ora sono soddisfatto.

Oh, quindi vuoi provarlo? Bene, eccoti qui:

z=s=>{r=[],c=s[m=w=n=0];for(i in s)(i?(d=s[++i])>c?++n:c>d?--n:n:n)<m&&m--,n>w&&w++,c=d;for(i=0,n=w*2;i<(w-m)*2+1;r[i++]=[...' '.repeat(l=s.length*2-1)]);for(i=0;i<l;i++)i%2?(A=s[C=(i-1)/2])<(B=s[C+1])?r[--n,n--][i]='/':A>B?r[++n,n++][i]='\\':r[n][i]='-':r[n][i]=s[i/2];return r.map(x=>x.join``).join('<br>')};

input=document.getElementById("input");
p=document.getElementById("a");
input.addEventListener("keydown", function(){
  setTimeout(function(){p.innerHTML = "<pre>"+z(input.value)+"</pre>";},10);
})
<form>Type or paste your text here: <input type="text" id="input"/></form>

<h3>Output:</h3>
<p id="a"></p>

Divertiti!

aggiornamenti:

Aggiornamento 1: golf fuori 29 byte con una varietà di tecniche tipiche.

Aggiornamento 2: liberato altri 15 byte costruendo la stringa in senso orizzontale dall'inizio, invece di costruire un array di stringhe verticali e di cambiarle, cosa che ha fatto prima.

Aggiornamento 3: salvati altri 14 byte.

Più golfiness in arrivo!


Puoi salvare un byte sostituendolo '\n'con una stringa modello come questa
jrich

@UndefinedFunction Sì, ho già usato quel trucco, ma ho dimenticato di inserirlo ieri sera. Grazie per il promemoria!
ETHproductions

I tuoi forloop possono essere schiacciati molto. Non sprecare un intero blocco di codice richiesto con i++. Invece, esegui la maggior parte del forcodice lì dentro. Inoltre, non hai bisogno di parentesi graffe attorno a singole righe di codice.
Non che Charles

Sembra anche che l'unico modo che usi lsia calcolare s.length*2-1e lo fai due volte. Perché non memorizzare quel valore invece?
Non che Charles

1
@NotthatCharles Grazie per i suggerimenti! Avevo appena provato l'algoritmo modificato e non mi ero ancora preoccupato di giocare a golf. L' <br>è proprio lì così si presenta nella versione HTML; se guardi da vicino, uso invece una stringa di modello nella voce effettiva. Inoltre, non è un requisito: "Stampa (o ritorno) ..."
ETHproductions

3

Python, 393 byte

def z(n,h=[]):
 for j in range(len(n)):h.append(sum(cmp(ord(n[i]),ord(n[i+1]))for i in range(j)))
 h=[j-min(h)for j in h]
 for y in range(max(h)*2+2):
  s=""
  for x in range(len(n)):
   if h[x]*2==y:s+=n[x]
   else:s+=" "
   if x==len(n)-1:continue
   c=" "
   if h[x]<h[x+1]and h[x]*2==y-1:c="\\"
   if h[x]>h[x+1]and h[x]*2==y+1:c="/"
   if h[x]==h[x+1]and h[x]*2==y:c="-"
   s+=c
  print s

Correre come: z("Zigzag")


3

JavaScript (ES6), 202

Utilizzo delle stringhe del modello. Spazi di rientro e newline non conteggiati, tranne l'ultima newline all'interno di backtick che è significativa e conteggiata.

Nota usuale: test di esecuzione dello snippet su qualsiasi browser compatibile con EcmaScript 6 (in particolare Chrome non MSIE. Ho testato su Firefox, Safari 9 potrebbe andare)

f=z=>
  [...z].map(c=>
    (d=0,x=w+c,p&&(
      c<p?o[d=1,g='\\ ',r+=2]||o.push(v,v)
      :c>p?(d=-1,g='/ ',r?r-=2:o=[v,v,...o]):x='-'+c,
      o=o.map((o,i)=>o+(i-r?i-r+d?b:g:x),v+=b)
    ),p=c)
  ,v=w=' ',o=[z[p=r=0]],b=w+w)&&o.join`
`

Ungolfed=z=>
(
  v=' ',o=[z[0]],r=0,p='',
  [...z].map(c=>{
    if (p) {
      if (c < p) {
        if (! o[r+=2])
          o.push(v,v)
        o = o.map((o,i)=>o+(i==r ? ' '+c : i==r-1 ? '\\ ' : '  '))
      } else if (c > p) {
        if (r == 0)
          o = [v,v,...o]
        else
          r -= 2
        o = o.map((o,i)=>o+(i==r ? ' '+c : i==r+1 ? '/ ' : '  '))
      } else {
        o = o.map((o,i)=>o+(i==r ? '-'+c : '  '))
      }
      v += '  '
    }
    p = c
  }),
  o.join`\n`
)

out=x=>O.innerHTML+=x+'\n'

test = [
"Programming Puzzles & Code Golf",  
"-\\//-- \\ //- ",  
"3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"]

test.forEach(t=>out(t+"\n"+f(t)))
<pre id=O></pre>


2

CJam, 79 byte

l__0=\+2ew::-:g_0\{+_}%);_$0=fm2f*_$W=)S*:E;]z{~\_)"/-\\"=2$@-E\@t@@E\@t}%(;zN*

Provalo online

Ciò crea l'output colonna per colonna e traspone il risultato alla fine per ottenere l'output riga per riga. Questo è stato nel complesso abbastanza doloroso.

Spiegazione:

l__   Get input and create a couple of copies.
0=\+  Prepend copy of first letter, since the following code works only with
      at least two letters.
2ew   Make list with pairs of letters.
::-   Calculate differences between pairs...
:g    ... and the sign of the differences.
_0\   Prepare for calculating partial sums of signs by copying list and
      pushing start value 0.
{     Loop for calculating partial sums.
  +_    Add value to sum, and copy for next iteration.
}%    End of loop for partial sums. We got a list of all positions now.
);    Pop off extra copy of last value.
_$0=  Get smallest value.
fm    Subtract smallest value to get 0-based positions for letters.
2f*   Multiply them by 2, since the offsets between letters are 2.
_$W=  Get largest position.
)     Increment by 1 to get height of result.
S*    Build an empty column.
:E;   Store it in variable E.
]     We got the input string, list of relative offsets, and list of
      absolute positions now. Wrap these 3 lists...
z     ... and transpose to get triplets of [letter offset position].
{     Loop over triplets.
  ~     Unwrap triplet.
  \     Swap offset to front.
  _)    Copy and increment so that offset is in range 0-2.
  "/-\\"  List of connection characters ordered by offset.
  =     Pick out connection character for offset.
  2$@   Get position and copy of offset to top.
  -     Subtract to get position of connection character.
  E     Empty column.
  \@    Shuffle position and character back to top. Yes, this is awkward.
  t     Place connection character in empty line. Done with first column.
  @@    Shuffle letter and position to top.
  E     Empty column.
  \@    Stack shuffling again to get things in the right order.
  t     Place letter in empty line. Done with second column.
}%    End of main loop for triplets.
(;    Pop off first column, which is an extra connector.
z     Transpose the whole thing for output by row.
N*    Join with newlines.

1

Perl 5, 230 214

@A=split(//,pop);$y=$m=256;map{$c=ord$_;$d=$c<=>$p;$t=$d>0?'/':$d<0?'\\':'-';$B[$x++][$y-=$d]=$t;$B[$x++][$y-=$d]=$_;$m=$y,if$m>$y;$M=$y,if$M<$y;$p=$c}@A;for$j($m..$M){for$i(1..$x){$s.=$B[$i][$j]||$"}$s.=$/}print$s

Test

$ perl zigzag.pl "zigge zagge hoi hoi hoi"
z
 \
  i
   \
    g-g
       \
        e   z   g-g       o       o       o
         \ / \ /   \     / \     / \     / \
              a     e   h   i   h   i   h   i
                     \ /     \ /     \ /


$ 

1

K, 86

{-1@+((d#\:" "),'1_,/("\\-/"1+e),'x)@\:!|/d:(|/b)+-:b:1_+\,/2#'e:{(x>0)-x<0}@-':6h$x;}  

.

k){-1@+((d#\:" "),'1_,/("\\-/"1+e),'x)@\:!|/d:(|/b)+-:b:1_+\,/2#'e:{(x>0)-x<0}@-':6h$x;} "Programming Puzzles & Code Golf"
                                                        o
                                                       / \
  r                         z-z               o   e   G   l
 / \                       /   \             / \ / \ /     \
P   o   r   m-m   n       u     l   s   &   C   d           f
     \ / \ /   \ / \     /       \ / \ / \ /
      g   a     i   g   P         e
                     \ /

Ungolfed:

f:{
    dir:{(x>0)-x<0}-':[*a;a:"i"$x];          //directional moves (-1, 0, 1)
    chars:1_,/("\\-/"1+dir),'x;              //array of input string combined with directional indicators
    depths:(|/b)+-:b:1_+\,/2#'dir;           //depth for each char, normalised to start at 0
    -1@+((depths#\:" "),'chars)@\:!|/depths; //Pad each character by the calculated depths, extend each string to a uniform length and transpose
    }

1

Ruby, 158

6 byte salvati grazie all'istocratico . Grazie!

->s,*i{i[x=n=k=(4*m=s=~/$/).times{i<<'  '*m}/2][j=0]=l=s[/./]
$'.chars{|c|i[k-=d=c<=>l][j+1]=%w{- / \\}[d]
i[k-=d][j+=2]=l=c
n,x=[x,n,k].minmax}
puts i[n..x]}

1
È possibile impostare i su un array vuoto usando ->s,*i{. E se sostituisci s[0]con s[/./], penso che puoi sostituire s[1..-1]con $'.
histocrat

@histocrat Great! Grazie! Pensavo avessi bisogno di parentesi per le dichiarazioni lambda multiparam, ma a quanto pare è solo JS.
Non che Charles, il

0

Python con Numpy: 218 byte

Vale la pena sprecare 19 byte per l'importazione di numpy.

golfed:

from numpy import*
z=zip
r=raw_input()
s=sign(diff(map(ord,r[0]+r)))
c=cumsum(s)
p=2*(max(c)-c)+1
for L in z(*[c.rjust(i).ljust(max(p))for _ in z(z(p+s,array(list('-/\\'))[s]),z(p,r))for i,c in _][1:]):print''.join(L)

Ungolfed:

from numpy import *

letters = raw_input()
#letters = 'Programming Puzzles & Code Golf'
s = sign(diff(map(ord, letters[0] + letters)))
c = cumsum(s)
lines = array(list('-/\\'))[s]

letter_heights = 2 * (max(c) - c) + 1
line_heights = letter_heights + s

columns = [symbol.rjust(height).ljust(max(letter_heights))
    for pair in zip(                    # interleave two lists of (height, symbol) pairs...
        zip(line_heights,   lines),
        zip(letter_heights, letters)
    )
    for height, symbol in pair          # ... and flatten.
][1:]                                   # leave dummy '-' out
for row in zip(*columns):
    print ''.join(row)
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.