Gấp một chuỗi thành một hình tam giác


22

Cho một chuỗi có độ dài chia hết cho 4, tạo một tam giác như minh họa dưới đây.

Nếu chuỗi là abcdefghijkl, thì tam giác sẽ là:

   a
  b l
 c   k
defghij

Nếu chuỗi là iamastringwithalengthdivisiblebyfour, thì tam giác sẽ là:

         i
        a r
       m   u
      a     o
     s       f
    t         y
   r           b
  i             e
 n               l
gwithalengthdivisib

Nếu chuỗi là thisrepresentationisnotatriangle, thì tam giác sẽ là:

        t
       h e
      i   l
     s     g
    r       n
   e         a
  p           i
 r             r
esentationisnotat

Ghi chú

  • Chuỗi sẽ chỉ bao gồm các ký tự từ ađến z.
  • Hàng đầu / Trailing whitespaces và newlines được cho phép miễn là hình dạng không bị phá vỡ.
  • Một danh sách các chuỗi như đầu ra được cho phép.

Đây là . Câu trả lời ngắn nhất trong byte thắng. Tiêu chuẩn áp dụng.

Câu trả lời:


7

Than , 25 22 21 byte

≔÷Lθ⁴λ↙…θλ→✂θλ±λ↖✂θ±λ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Đơn giản chỉ cần cắt chuỗi thành ba phần và in chúng theo các hướng thích hợp. Chỉnh sửa: Đã lưu 3 byte bằng cách sử dụng phép chia và cắt số nguyên. Đã lưu thêm một byte bằng cách sử dụng CycleChopthay vì Slicecho đầu chuỗi. Chỉnh sửa: Char than hiện hỗ trợ vẽ văn bản tùy ý dọc theo cạnh của đa giác, đơn giản hóa mã thành 12 byte:

GH↙→→↖⊕÷Lθ⁴θ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã.


Các s làm gì?
Erik the Outgolfer

@EriktheOutgolfer Đó là toán tử Slice mới.
Neil

: | Rất tiếc có nghĩa là làm cho PolygonHollow làm điều này, GH↙→→↖⊕÷Lθ⁴θsẽ hoạt động vào lần tới khi tôi đẩy Char than
ASCII vào

6

05AB1E , 23 byte

ćsIg4÷GćsÁćsŠN·<ú«s}».C

Hãy thử trực tuyến!

Giải trình

ć                        # extract head of input
 s                       # swap the remaining string to top of stack
  Ig4÷G                  # for N in [1...len(input)/4-1] do:
       ć                 # extract head
        sÁ               # swap remaining string to top of stack and rotate right
          ć              # extract head
           sŠ            # reorder stack as tail, head, remaining
             N·<ú        # prepend N-1 spaces to tail
                 «s      # concatenate with head and swap remaining string to top
                   }     # end loop
                    ».C  # join by newlines and center

6

JavaScript (ES6), 119 117 108 105 byte

s=>(l=s.length/4,S=' ',g=([c,...s],p)=>S.repeat(l)+c+(l--?p+s.pop()+`
`+g(s,p?p+S+S:S):s.join``))(s+S,'')

Định dạng và nhận xét

s => (                            // given the input string s:
  l = s.length / 4,               // l = length of side edge - 1
  S = ' ',                        // S = space (defining S costs 6 bytes but saves 7)
  g = (                           // g = recursive function which takes:
       [c,                        //   - c = next character
           ...s],                 //   - s = array of remaining characters
                  p) =>           //   - p = middle padding string
    S.repeat(l) + c + (           // append left padding + left character
      l-- ?                       // if side edges are not complete:
        p + s.pop() + '\n' +      //   append middle padding + right character + Line Feed
        g(s, p ? p + S + S : S)   //   and do a recursive call with updated middle padding
      :                           // else:
        s.join``                  //   append all remaining characters and stop recursion
    )                             //   (this is the bottom edge)
  )(s + S, '')                    // initial call to g()

Các trường hợp thử nghiệm


4

C #, 260 byte

namespace System{using static Console;class P{static void Main(){var d=ReadLine();int e=d.Length/4,x=e,y=0,g=0,i=0;Action<int,int>a=(p,q)=>{SetCursorPosition(p,q);Write(d[g++]);};for(;i<e;i++)a(x--,y++);for(i=0;i<e*2;i++)a(x++,y);for(i=0;i<e;i++)a(x--,y--);}}}

Thực sự muốn sử dụng SetCursorPosition .

Ung dung:

namespace System {
    using static Console;

    class P {
        static void Main() {
            var d = ReadLine();
            int e = d.Length / 4, x = e, y = 0, g = 0, i = 0;
            Action<int, int> a = (p, q) => { SetCursorPosition(p, q); Write(d[g++]); };
            for (; i < e; i++)
                a(x--, y++);
            for (i = 0; i < e * 2; i++)
                a(x++, y);
            for (i = 0; i < e; i++)
                a(x--, y--);
        }
    }
}

Xin tha thứ cho sự thiếu hiểu biết của tôi, nhưng mục đích của Hành động trong giải pháp của bạn là gì? Có phải nó chỉ ít byte hơn một hàm void?
bối rối và sử dụng

1
@confusesandamuse Tôi đã quen viết câu trả lời cho một hàm nên thậm chí còn không xem xét việc đặt hàm bình thường, mặc dù vậy nó sẽ ngắn hơn.
LiefdeWen

3

Toán học, 164 byte

(b=Length[c=Characters@#];k=Column[#,Alignment->Center]&;T=Table;k@{#&@@c,k@T[""<>{c[[i+2]],T[" ",2i+1],c[[-i-1]]},{i,0,(a=b/4)-2}],""<>T[c[[i]],{i,a+1,b/2+1+a}]})&


đầu vào

["iamastringwithalengthdivisiblebyfour"]


Chúng ta đều biết rằng [[1]]có thể được thay thế bằng #&@@.
dùng202729

1
bạn thật là thông minh
J42161217


Khi bạn thấy mình làm @(...), chỉ cần làm [...]thay thế. Và tôi đã không kiểm tra nhưng có lẽ bạn có thể lưu một byte khác bằng cách Columnđặt tên (hoặc thậm chí Column[#,Alignment->Center]&để tránh q) và sau đó bằng cách đặt tất cả các biến còn lại vào đối số đầu tiên của bên ngoài Column(để lưu các dấu ngoặc đơn xung quanh).
Martin Ender

3

Con trăn 3 , 120 byte

Golf đầu tiên, hình dung tôi cũng có thể học một số Python trên đường đi.

a=input()
l=len(a)//4
print(l*" "+a[0])
for i in range(1,l):print((l-i)*" "+a[i]+(2*i-1)*" "+a[4*l-i])
print(a[l:3*l+1])

Hãy thử trực tuyến!

Giải trình:

Ký tự đầu tiên được in sau các len(a)//4khoảng trắng, sau đó các iký tự đầu tiên và cuối cùng bắt đầu từ ký tự thứ hai được in, cách nhau bởi2*i - 1 khoảng trắng.

Cuối cùng, chuỗi con còn lại được in.


Chào mừng đến với PPCG! Bạn có thể học hỏi từ giải pháp này .
Rò rỉ Nun

Một golf có thể ở đây là để khai báo p=print, và sau đó chỉ cần sử dụng pcho ba prints bạn sử dụng.
FlipTack

Ngoài ra, vì độ dài chuỗi được đảm bảo luôn chia hết cho bốn, //(phân chia tầng) có thể được thay thế bằng /.
FlipTack

Nhân tiện, mã bạn đã liên kết để thử trực tuyến không giống với mã trong câu trả lời của bạn.
FlipTack

3

GNU sed , 178 158 132 + 1 = 133 byte

+1 byte cho -rcờ.

s/(.)(.*)(.)/ \1\n\2;\3/
:
s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1  \6\n\3;\4\5/m
t
:A
s/(.*\n)( *)(.*);/ \2;\1\2\3/m
tA
s/. (.)$/\1/gm

Hãy thử trực tuyến!

Giải trình

Trong các lần sửa đổi trước, tôi đã sử dụng rất nhiều byte liên quan đến toán học, các trường hợp đặc biệt và dọn dẹp, mặc dù theo trực giác tôi chắc chắn rằng chúng có thể tránh được. Kể từ đó tôi đã xoay sở để làm như vậy.

Giả sử chúng ta có đầu vào abcdEFGHIJKLMnop. Các chữ cái EFGHIJKLMsẽ là đáy của hình tam giác, vì vậy tôi đã viết hoa chúng như một trợ giúp trực quan.

Trước tiên, chúng tôi chuẩn bị đầu vào bằng cách đặt ký tự đầu tiên trên dòng riêng của nó (trước một khoảng trắng) và chèn một con trỏ ( ;) trước ký tự cuối cùng:

s/(.)(.*)(.)/ \1\n\2;\3/

Bây giờ chúng tôi có:

 a
bcdEFGHIJKLMno;p

Bây giờ, trong một vòng lặp, chúng ta sẽ thực hiện một số điều cho dòng cuối cùng: 1. Sao chép khoảng trắng từ dòng trước đó và chèn chúng sau ký tự đầu tiên, cộng với hai; 2. Di chuyển ký tự cuối cùng sang phải sau dấu cách, theo sau là dòng mới; và 3. Di chuyển con trỏ ba ký tự sang trái.

:
  s/( *)(.\n.)(.*)(...);(.*)(.)/\1\2\1  \6\n\3;\4\5/m
  t

Đây là kết quả của mỗi lần lặp:

 a
b   p
cdEFGHIJKL;Mno

 a
b   p
c     o
dEFGHI;JKLMn

 a
b   p
c     o
d       n
EF;GHIJKLM

Bạn có thể thấy kim tự tháp bắt đầu hình thành. Bạn cũng có thể thấy con trỏ dùng để làm gì: Trong mỗi lần lặp, nó di chuyển sang trái ba ký tự và khi không còn ba ký tự bên trái, nó sẽ phá vỡ vòng lặp, điều này xảy ra ngay khi chúng ta chạm đến "đáy" của kim tự tháp.

Bây giờ chúng ta sẽ thực hiện một hoạt động tương tự nhưng ngược lại. Trong một vòng lặp, chúng tôi sẽ sao chép các khoảng trắng từ đầu dòng bằng con trỏ đến đầu dòng trước, cộng với một, trong quá trình di chuyển con trỏ lên đến dòng đó.

:A
  s/(.*\n)( *)(.*);/ \2;\1\2\3/m
  tA

Dưới đây là một vài lần lặp và kết quả cuối cùng:

 a
b   p
c     o
 ;d       n
EFGHIJKLM

 a
b   p
  ;c     o
 d       n
EFGHIJKLM

...

    ; a
   b   p
  c     o
 d       n
EFGHIJKLM

Bây giờ chúng ta đã hoàn thành, ngoại trừ một số ký tự phụ: A ;và thêm khoảng trắng trên dòng đầu tiên và hai khoảng trắng ở "giữa" của kim tự tháp trên ba dòng tiếp theo. Một sự thay thế đơn giản được loại bỏ chúng:

s/. (.)$/\1/gm

Tất cả đã được làm xong!

    a
   b p
  c   o
 d     n
EFGHIJKLM


2

Python 2 , 100 97 96 byte

  • Jacoblaw lưu 1 byte: chia số nguyên là không cần thiết
a=input()+" "
k=j=len(a)/4
while j:print j*" "+a[0]+(2*(k-j)-1)*" "+a[-1];a=a[1:-1];j-=1
print a

Hãy thử trực tuyến!

Giải trình:

Một điều thông minh mà tôi đã thực hiện ở đây là đệm đầu vào với một khoảng trắng ở cuối, sao cho các ký tự đầu tiên ghép với nó và điều này có thể được đẩy vào vòng lặp (và vì các khoảng trắng theo dõi được cho phép)

abcdefghijkl[space]   
To print [0] [-1]            Output=>[spaces]a[another_calculated_spaces(=0 here)][space]
Strip at both ends(a[1:-1])  
bcdefghijkl                
To print [0] [-1]            Output=>[spaces]b[another_calculated_spaces]l
Strip at both ends(a[1:-1])
and so on.

Số vòng lặp để theo dõi được liên kết với len(word)//4. Trong bước cuối cùng, toàn bộ chuỗi còn lại được in (điều này tạo thành cơ sở của tam giác). Các không gian theo một mô hình đơn giản; bộ không gian thứ nhất tiếp tục giảm đi 1, trong khi bộ không gian thứ hai tiếp tục tăng thêm 2.


1
Bạn có thể cạo một byte bằng cách không thực hiện phép chia số nguyên? Vì asẽ luôn là bội số của 4. //->/
jacoblaw

Cảm ơn bạn, tôi ngạc nhiên khi nó không ném bất kỳ lỗi nào ngay cả đối với [đầu vào có độ dài không chia hết cho 4] [ tio.run/ Kẻ
chính thức tuyên bố

1
Đó là bởi vì trong Python 2, phép chia là số nguyên theo mặc định. Điều đó đã bị bẻ khóa trong Python 3.
CalculatorFeline

2

C 225 byte

p(c){putchar(c);}S(n){while(n--)p(' ');}main(int c,char**v){int i= strlen(v[1]),n=i/4,r;char*s=v[1],*e=&s[i-1];S(n);p(*s++);p('\n');for (r=1;r<n;r++){S(n-r);p(*s++);S(2*r-1);p(*e--);p('\n');}e++;while (s!=e)p(*s++);p('\n');}

giải thích

p(c){putchar(c);}        // p is alias for putchar
S(n){while(n--)p(' ');}  // S prints n spaces
main(int c,char**v){
    int i= strlen(v[1]), // counter
        n=i/4,           // num rows in figure - 1
        r;               // current row 
    char*s=v[1],         // start char
        *e=&s[i-1];      // end char
    S(n);p(*s++);p('\n');// print first row
    for (r=1;r<n;r++){ 
        S(n-r);p(*s++);S(2*r-1);p(*e--);p('\n'); // print middle rows
    }
    e++;while (s!=e)p(*s++);p('\n'); // print last row
}

2

C #, 172 byte

int i=0,n=s.Length;var p="";p=new string(' ',n/4)+s[i]+"\r\n";for(i=1;i<n/4;i++){p+=new string(' ',n/4-i)+s[i]+new string(' ',i*2-1)+s[n-i]+"\r\n";}p+=s.Substring(i,n/2+1);

Hãy thử trực tuyến!


1

Octave, 87 byte

@(s,x=(n=nnz(s))/4)[[' ';flip(diag(s(1:x))')]' [' ';diag(s(n:-1:n-x+2))];s(x+1:n-x+1)];

* Trong một máy tính windows, đoạn mã trên tạo ra kết quả chính xác tuy nhiên trong tio tôi đã thêm một số mã để sửa nó.

Giải trình:

[' ';flip(diag(s(1:x))')]'        %left side
[' ';diag(s(n:-1:n-x+2))]         %right side
s(x+1:n-x+1)                      %bottom side

Hãy thử trực tuyến!




1

AWK , 129 byte

{n=split($0,a,"")
printf"%"(w=n/4+1)"s\n",a[++i]
for(;++i<w;)printf"%"(w-i+1)"s%"2*i-2"s\n",a[i],a[n-i+2]
$0=substr($0,i,i+w-1)}1

Hãy thử trực tuyến!

Tôi nên nghĩ rằng điều này có thể được chơi golf nhiều hơn một chút, chỉ cần không nhìn thấy nó.


1

Võng mạc , 99 byte

^(.)(?=(....)+)
$#2$*  $1¶$#2$* 
( ( *).)(.*)(.)$
$1 $4¶$2$3
+`(( +).¶ ( *).)(.*)(.)$
$1$2  $5¶$3$4

Hãy thử trực tuyến! Giải thích: Hai giai đoạn đầu tiên tạo ra hai dòng đầu tiên, nhưng sau đó không có vỏ đặc biệt là cần thiết và mỗi dòng tiếp theo có thể được tạo tự động:

thisrepresentationisnotatriangle

        t
       hisrepresentationisnotatriangle

        t
       h e
      isrepresentationisnotatriangl

        t
       h e
      i   l
     srepresentationisnotatriang

...

        t
       h e
      i   l
     s     g
    r       n
   e         a
  p           i
 r             r
esentationisnotat

1

Java 8, 213 byte

s->{int n=s.length()/4,i;String r=s(n)+s.charAt(0)+"\n";for(i=1;i<n;r+=s(n-i)+s.charAt(i)+s(i*2-1)+s.charAt(n*4-i++)+"\n");return r+s.substring(i,n*2+i+1);}String s(int n){String r="";for(;n-->0;r+=" ");return r;}

Giải trình:

Hãy thử nó ở đây.

s->{                           // Method (1) with String parameter and String return-type
  int n=s.length()/4,          //  The length of the input divided by 4
      i;                       //  And an index-integer
  String r=                    //  Result-String which starts as:
           s(n)                //   Trailing spaces
           +s.charAt(0)+"\n";  //   + the first character and a new-line
  for(i=1;i<n;                 //  Loop from `1` to `n`
      r+=                      //   And append the result-String with:
         s(n-i)                //    Trailing spaces
         +s.charAt(i)          //    + the character of the left diagonal line
         +s(i*2-1)             //    + center spaces
         +s.charAt(n*4-i++)    //    + the character of the right diagonal line
         +"\n"                 //    + a new-line
  );                           //  End of loop
  return r                     //  Return the result-String
         +s.substring(i,n*2+i+1);
                               //   + the bottom part of the triangle
}                              // End of method (1)

String s(int n){               // Method (2) with integer parameter and String return-type
  String r="";                 //  Result-String
  for(;n-->0;r+=" ");          //  Append the result-String with `n` spaces
  return r;                    //  Return the result-String
}                              // End of method (2)

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.