ซิกแซ็กสตริง


46

เขียนโปรแกรม (หรือฟังก์ชัน) ที่รับสายอักขระที่ไม่ว่างเปล่าของอักขระ ASCII ที่พิมพ์ได้

พิมพ์ (หรือส่งคืน) ห่วงโซ่ซิกแซกของตัวละครในสตริงที่มีตัวละครทุกตัวที่เชื่อมโยงกันโดย:

  • /หากตัวอักษรตัวแรกเกิดขึ้นก่อนตัวอักษรตัวที่สองตามลำดับ ASCII ปกติ เช่น

      B
     /
    A
    
  • \หากตัวอักษรตัวแรกเกิดขึ้นหลังจากตัวละครตัวที่สองในลำดับ ASCII ปกติ เช่น

    B
     \
      A
    
  • -ถ้าตัวอักษรตัวแรกและตัวที่สองเหมือนกัน เช่น

    A-A
    

ดังนั้นผลลัพธ์สำหรับ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                          
                     \ /                                     
                                                             

หากมีเพียงหนึ่งอักขระในสตริงอินพุตเอาต์พุตก็จะเป็นอักขระนั้น

โปรแกรมของคุณควรปฏิบัติต่อ, /และ\, -เช่นเดียวกับตัวละครอื่น ๆ ทั้งหมด

เช่น -\//-- \ //- ควรผลิต:

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

ไม่ควรมีการขึ้นบรรทัดใหม่ที่ไม่เกี่ยวข้องในเอาต์พุตยกเว้นสำหรับการขึ้นบรรทัดใหม่ที่เป็นทางเลือกเดียว (โปรดสังเกตว่าบรรทัดว่างในตัวอย่างด้านบนเก็บช่องว่างสุดท้ายในสตริงและดังนั้นจึงไม่ใช่ภายนอก) อาจมีช่องว่างต่อท้ายในบรรทัดใด ๆ ในการจัดเรียงใด ๆ

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

อีกตัวอย่างหนึ่ง - อินพุต:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

เอาท์พุท:

                          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                              

คำตอบ:


8

Pyth, 69 ไบต์

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

สาธิต. อินพุตอีกต่อไปยังใช้งานได้ แต่ก็ไม่ได้ดูดีมากในกล่องเอาต์พุตความกว้างคงที่

ฉันเริ่มต้นด้วยการสร้างรายการในYของ [ตัวละคร, ความสูง] tuples มันเป็น[['P', 0], ['/', -1], ['r', -2], ['\\', -1], ['o', 0], ['\\', 1], ['g', 2]]ช่วงต้นในProgramming Puzzles & Code Golfตัวอย่าง

จากนั้นฉันจะสร้างสตริงของช่องว่างตามความยาวที่เหมาะสมแทรกตัวอักษรในตำแหน่งที่เหมาะสมโยกย้ายเข้าร่วมในการขึ้นบรรทัดใหม่และพิมพ์


7

Julia, 297 ไบต์

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 ไบต์

นี่คือความพยายามครั้งที่สี่ของฉัน:

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

ไม่สั้นพอ ๆ กับคนอื่น ๆ แต่ตอนนี้ฉันพอใจแล้ว

โอ้คุณต้องการทดสอบหรือไม่ เอาล่ะไปเลย:

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>

มีความสุข!

ปรับปรุง:

อัปเดต 1:ตีกอล์ฟ 29 ไบต์ด้วยเทคนิคทั่วไปที่หลากหลาย

อัปเดต 2:ดึงข้อมูลออก 15 ไบต์โดยการสร้างสตริงในแนวนอนตั้งแต่เริ่มต้นซึ่งต่างจากการสร้างอาร์เรย์ของสตริงตามแนวตั้งและสลับไปมารอบ ๆ ซึ่งเป็นสิ่งที่เคยทำมาก่อน

อัปเดต 3:บันทึกอีก 14 ไบต์

Golfiness เพิ่มเติมเร็ว ๆ นี้!


คุณสามารถบันทึกไบต์โดยแทนที่'\n'ด้วยสตริงแม่แบบเช่นนี้
jrich

@Undefined ฟังก์ชั่นใช่ฉันเคยใช้เคล็ดลับนั้นมาก่อน แต่ลืมที่จะใส่มันในคืนที่ผ่านมา ขอบคุณสำหรับการเตือน!
ETHproductions

forลูปของคุณสามารถถูกบีบได้มาก i++ไม่ต้องเสียบล็อกทั้งหมดของรหัสที่จำเป็นด้วย ให้รันforโค้ดส่วนใหญ่ในนั้นแทน นอกจากนี้คุณไม่จำเป็นต้องใส่เครื่องหมายวงเล็บในบรรทัดเดียว
ไม่ใช่ชาร์ลส์ที่

ดูเหมือนว่าวิธีเดียวที่คุณใช้lคือการคำนวณs.length*2-1และคุณทำสองครั้ง ทำไมไม่เก็บค่านั้นแทน?
ไม่ใช่ชาร์ลส์ที่

1
@NotthatCharles ขอบคุณสำหรับเคล็ดลับ! ฉันเพิ่งลองใช้อัลกอริทึมที่แก้ไขแล้วและยังไม่อยากตีกอล์ฟอีก ที่<br>อยู่ในนั้นจึงปรากฏในรุ่น HTML; หากคุณมองอย่างใกล้ชิดฉันใช้สตริงแม่แบบแทนในรายการจริง นอกจากนี้ยังไม่มีข้อกำหนด: "พิมพ์ (หรือส่งคืน) ... "
ETHproductions

3

Python ขนาด 393 ไบต์

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

ทำงานเป็น: z("Zigzag")


3

JavaScript (ES6), 202

ใช้สตริงแม่แบบ การเว้นวรรคการเยื้องและการขึ้นบรรทัดใหม่จะไม่นับยกเว้นการขึ้นบรรทัดใหม่ล่าสุดภายใน backticks ที่มีความสำคัญและนับ

หมายเหตุปกติ: ทดสอบการเรียกใช้ตัวอย่างข้อมูลบนเบราว์เซอร์ที่สอดคล้องกับ EcmaScript 6 (ไม่ใช่ Chrome ไม่ใช่ MSIE โดยเฉพาะอย่างยิ่งฉันทดสอบบน Firefox, Safari 9 แล้ว)

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 ไบต์

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

ลองออนไลน์

สิ่งนี้จะสร้างคอลัมน์เอาต์พุตตามคอลัมน์และแปลงผลลัพธ์ในตอนท้ายเพื่อรับเอาท์พุทแถวต่อแถว โดยรวมแล้วค่อนข้างเจ็บปวด

คำอธิบาย:

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

ทดสอบ

$ 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

ทับทิม, 158

ที่บันทึกไว้ 6 ไบต์ขอบคุณที่histocrat ขอบคุณ!

->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
คุณสามารถตั้งค่า i ->s,*i{เพื่ออาร์เรย์ที่ว่างเปล่าโดยใช้ และถ้าคุณแทนที่s[0]ด้วยs[/./]ผมคิดว่าคุณสามารถแทนที่ด้วยs[1..-1] $'
ฮิสโทแคต

@histocrat ยอดเยี่ยม! ขอบคุณ! ฉันคิดว่าคุณต้องการ parens สำหรับการประกาศแลมบ์ดาแบบหลายพารามิเตอร์ แต่เห็นได้ชัดว่าเป็นเพียง JS
ไม่ใช่ชาร์ลส์ที่

0

Python กับ Numpy: 218 ไบต์

มันคุ้มค่าที่จะเสีย 19 ไบต์สำหรับการนำเข้าจำนวนมาก

แข็งแรงเล่นกอล์ฟ:

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.