Zigzagify một chuỗi


46

Viết chương trình (hoặc hàm) nhận chuỗi không trống của bất kỳ ký tự ASCII có thể in nào .

In (hoặc trả lại) chuỗi ký tự ngoằn ngoèo của các ký tự trong chuỗi với mỗi cặp ký tự lân cận được liên kết bởi:

  • /nếu ký tự đầu tiên xuất hiện trước ký tự thứ hai theo thứ tự ASCII bình thường. ví dụ

      B
     /
    A
    
  • \nếu ký tự đầu tiên xuất hiện sau ký tự thứ hai theo thứ tự ASCII bình thường. ví dụ

    B
     \
      A
    
  • -nếu các ký tự đầu tiên và thứ hai là như nhau. ví dụ

    A-A
    

Vì vậy, đầu ra cho Programming Puzzles & Code Golfsẽ là

                                                        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                          
                     \ /                                     
                                                             

Nếu chỉ có một ký tự trong chuỗi đầu vào, đầu ra sẽ chỉ là ký tự đó.

Chương trình của bạn nên đối xử , /, \, và -chỉ giống như tất cả các nhân vật khác.

ví dụ: -\//-- \ //- nên sản xuất:

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

Không nên có các dòng mới ngoại lai trong đầu ra ngoại trừ một dòng mới tùy chọn duy nhất. (Lưu ý rằng dòng trống trong ví dụ ngay phía trên giữ khoảng trống cuối cùng trong chuỗi và do đó không phải là không liên quan.) Có thể có các khoảng trắng ở bất kỳ dòng nào trong bất kỳ sắp xếp nào.

Mã ngắn nhất tính bằng byte thắng.

Một ví dụ nữa - Đầu vào:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

Đầu ra:

                          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                              

Câu trả lời:


8

Bình thường, 69 byte

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

Trình diễn, thuyết trình. Đầu vào dài hơn vẫn hoạt động, nhưng chúng trông không được tốt trong hộp đầu ra có chiều rộng cố định.

Tôi bắt đầu bằng cách xây dựng một danh sách, trong Y, các ký tự [ký tự, chiều cao]. Đó là [['P', 0], ['/', -1], ['r', -2], ['\\', -1], ['o', 0], ['\\', 1], ['g', 2]]sớm trong Programming Puzzles & Code Golfví dụ.

Sau đó tôi tạo các chuỗi khoảng trắng có độ dài phù hợp, chèn ký tự vào vị trí thích hợp, hoán vị, tham gia vào dòng mới và in.


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)

Ung dung:

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

Đây là nỗ lực thứ tư của tôi:

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`
`}

Không ngắn như một số người khác, nhưng tôi hài lòng với nó bây giờ.

Oh, vì vậy bạn muốn kiểm tra nó? Được rồi, bạn đi đây:

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>

Chúc vui vẻ!

Cập nhật:

Cập nhật 1: Chơi hết 29 byte với nhiều kỹ thuật điển hình.

Cập nhật 2: Đánh bóng thêm 15 byte bằng cách xây dựng chuỗi theo chiều ngang từ đầu, trái ngược với việc xây dựng một chuỗi các chuỗi dọc và chuyển đổi chúng xung quanh, đó là những gì nó đã làm trước đây.

Cập nhật 3: Lưu thêm 14 byte.

Sắp có thêm golf!


Bạn có thể lưu một byte bằng cách thay thế '\n'bằng một chuỗi mẫu như thế này
jrich

@Und xác định chức năng Vâng, tôi đã sử dụng thủ thuật đó trước đây, nhưng đã quên đưa nó vào tối qua. Cảm ơn đã nhắc nhở!
Sản phẩm ETH

Các forvòng lặp của bạn có thể bị cắt xén rất nhiều. Đừng lãng phí cả một khối mã cần thiết với i++. Thay vào đó, hãy chạy hầu hết formã của bạn trong đó. Ngoài ra, bạn không cần niềng răng xung quanh các dòng mã.
Không phải Charles

Có vẻ như cách duy nhất bạn sử dụng llà tính toán s.length*2-1và bạn làm điều đó hai lần. Tại sao không lưu trữ giá trị đó thay thế?
Không phải Charles

1
@NotthatCharles Cảm ơn lời khuyên! Tôi vừa thử thuật toán đã sửa đổi và không bận tâm đến việc chơi golf nữa. Nó <br>chỉ ở trong đó để nó xuất hiện trong phiên bản HTML; nếu bạn nhìn kỹ, tôi sử dụng một chuỗi mẫu thay vì trong mục thực tế. Ngoài ra, đó không phải là một yêu cầu: "In (hoặc trả lại) ..."
Sản phẩm ETH

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

Chạy như: z("Zigzag")


3

JavaScript (ES6), 202

Sử dụng chuỗi mẫu. Không gian thụt lề và dòng mới không được tính, ngoại trừ dòng mới cuối cùng bên trong backticks có ý nghĩa và được tính.

Lưu ý thông thường: kiểm tra chạy đoạn mã trên bất kỳ trình duyệt tuân thủ EcmaScript 6 nào (đáng chú ý không phải Chrome không phải MSIE. Tôi đã thử nghiệm trên Firefox, Safari 9 có thể đi)

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*

Dùng thử trực tuyến

Điều này xây dựng cột đầu ra theo cột và chuyển kết quả ở cuối để lấy hàng đầu ra theo hàng. Điều này là khá đau đớn tổng thể.

Giải trình:

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

Kiểm tra

$ 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
                     \ /

Ung dung:

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

Hồng ngọc, 158

Đã lưu 6 byte nhờ histocrat . Cảm ơn!

->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
Bạn có thể đặt i thành một mảng trống bằng cách sử dụng ->s,*i{. Và nếu bạn thay thế s[0]bằng s[/./], tôi nghĩ bạn có thể thay thế s[1..-1]bằng $'.
lịch sử

@histocrat Tuyệt vời! Cảm ơn! Tôi nghĩ rằng bạn cần parens cho các khai báo lambda đa thông số, nhưng dường như đó chỉ là JS.
Không phải là Charles

0

Python với Numpy: 218 byte

Nó đáng giá để lãng phí 19 byte để nhập numpy.

Chơi gôn

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)

Ung dung:

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.