Làm cho tôi một hàng rào!


15

Thử thách

Đây là một thử thách đơn giản. Cho hai số nguyên dương whtạo một hàng rào ASCII có chiều rộng wvà chiều cao h. Hàng rào nên được xây dựng theo các quy tắc sau:

  • Các + nhân vật sẽ đại diện cho một bài.
  • Nhân -vật sẽ được sử dụng để thể hiện chiều rộng của hàng rào.
  • Các |sẽ được sử dụng để đại diện cho đỉnh cao của hàng rào.
  • Sau khi chính xác ba -ký tự đã được xuất ra, một +nhân vật phải được xuất ra sau đó. Không bao gồm bốn góc, bất kỳ lúc nào bạn xuất ra +sẽ không hợp lệ. Bạn được phép tuân theo quy tắc này bắt đầu từ bên trái hoặc bên phải (xem ví dụ), nhưng bạn phải nhất quán.
  • Sau khi chính xác hai |nhân vật đã được xuất ra, một +nhân vật phải được xuất ra sau đó. Không bao gồm bốn góc, bất kỳ lúc nào bạn xuất ra +sẽ không hợp lệ. Bạn được phép tuân theo quy tắc này bắt đầu từ đầu hoặc cuối (xem ví dụ), nhưng bạn phải nhất quán.
  • Mỗi hàng rào sẽ có chính xác bốn góc và mỗi góc sẽ được biểu thị bằng a +.

Nói cách khác: Ở mỗi ba -ký tự, bạn phải xuất a +. Và cứ sau hai |ký tự, bạn phải xuất ra a +.

Bạn có thể giả định rằng hàng rào sẽ luôn là một hình chữ nhật, và cả hai whsẽ không bao giờ lớn hơn 100hoặc nhỏ hơn 1. Trailing và / hoặc khoảng trắng trước được cho phép.

Ví dụ / Trường hợp kiểm tra

w = 1
h = 1

+-+ 
| |
+-+


w = 3
h = 2

+---+
|   |
|   |
+---+


w = 5
h = 7

+---+--+ or +--+---+
|      |    |      |
|      |    +      +
+      +    |      |
|      |    |      |
|      |    +      +
+      +    |      |
|      |    |      |
|      |    +      +
+      +    |      |
|      |    |      |
+---+--+    +--+---+

w = 10
h = 5

+---+---+---+-+  or +-+---+---+---+
|             |     |             |
|             |     +             +
+             +     |             |
|             |     |             |
|             |     +             +
+             +     |             |
|             |     |             |
+---+---+---+-+     +-+---+---+---+


w = 4
h = 4

+---+-+ or +-+---+
|     |    |     |
|     |    |     |
+     +    +     +
|     |    |     |
|     |    |     |
+---+-+    +-+---+

Quy tắc



3
Tôi có đúng để hiểu có thể không có hai +chạm?
xnor

@xnor Vâng, đúng vậy.
Christian Dean

3
Nhân tiện, thử thách đầu tiên.
xnor

1
@LeakyNun Quyền của bạn. Đó là một trường hợp tôi không có trong đầu khi đưa ra các quy tắc của mình. Tôi đã thêm một quy tắc để nêu tại sao +-+-+-+-+-+không hợp lệ. Xin lỗi vì sự nhầm lẫn.
Christian Dean

Câu trả lời:


9

C, 131 byte

#define L for(i=0,j=w;j;)putchar(i++%4?--j,45:43);puts("+")
f(w,h,i,j,c){L;for(j=1;h;printf("%c%*c\n",c,i,c))c=j++%3?--h,124:43;L;}

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

Giải trình:

// The first and the last line are always similar, so let's use a macro
// to avoid code duplication.
#define L

// Let's initialize 'i' and 'j'. 'i' will be used to keep track of which
// character ('+' or '-') we should print, whereas 'j' starts from the
// input width and the loop terminates when 'j' reaches zero.
for(i=0,j=w;j;)

// We post-increment 'i' and take a modulo 4 of its previous value.
// If i%4 == 0, we print '+' (ASCII 43), otherwise we decrement 'j'
// and print '-' (ASCII 45).
putchar(i++%4?--j,45:43);

// After the loop we print one more '+' and newline.
puts("+")

// The function declaration which takes the two input parameters, and
// also declares three integer variables. These three variables could
// also be declared as global variables with the same bytecount.
f(w,h,i,j,c)

// The start of the function body. We use the macro 'L' to print the 
// first line along with a newline.
{L;

// This loop prints all the lines between the first and the last. 'j'
// keeps track of when we should output a '+' instead of a '|'. 'h',
// which is the input parameter for height, serves as a terminator
// for the loop as it reaches zero.
for(j=1;h;<stuff missing from here>)

// We post-increment 'j' and check if its previous value is divisible
// by three, and if it isn't, we decrement 'h' and assign 124 (ASCII
// value for '|') to 'c'. Otherwise we assign '+' (ASCII 43) to 'c'.
c=j++%3?--h,124:43;

// The following is inside the 'increment' part of the 'for' loop.
// We print the character corresponding to the value of 'c', then
// the same character again, but padded with i-1  spaces before it 
// ('i' hasn't been touched since the first loop, so it still stores
// the length of the first line), then a newline.
printf("%c%*c\n",c,i,c)

// Lastly we print the first line again using the same macro 'L'.
L;}

5

Python 3 , 140 137 128 119 106 105 byte

def f(w,h):a=~-w//3-~w;b=("+---"*w)[:a]+'+';print(b,*[i+' '*~-a+i for i in"||+"*h][:h+~-h//2],b,sep='\n')

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


2
Bây giờ đã lâu hơn nhưng vấn đề đã được khắc phục.
GarethPW

1
Bạn có thể lưu một byte bằng cách loại bỏ khoảng trắng giữa in[w+1+(w-1)//3]]trong phần cuối cùng.
Christian Dean

1
Chào mừng đến với PPCG! Bạn có thể loại bỏ không gian '\n') forlà tốt. Ngoài ra, bạn có thể thay đổi (w-1)thành ~-wcho phép bạn loại bỏ dấu ngoặc đơn vì các toán tử đơn nguyên có độ ưu tiên cao hơn các toán tử nhị phân. Tương tự cho (h-1)-> ~-h(a-1)-> ~-a. Dùng thử trực tuyến - 128 byte
musicman523

1
Ngoài ra, vì tất cả đầu ra của bạn được in, def f(w,h)có cùng độ dài lambda w,h, nhưng cho phép bạn sử dụng nhiều dòng nếu điều đó giúp bạn chơi mã của mình hơn nữa
musicman523

1
a=~-w//3-~w;để tiết kiệm 1 byte
Felipe Nardi Batista

4

Toán học, 165 byte

v=Column;d[w_,y_,m_,n_]:=Table[If[Mod[i,y]==0&&i!=w,m,n],{i,w}];(a="+"<>d[#,3,"-+","-"]<>"+";b=v@d[#2,2,"|\n+","|"];v[{a,Row[{b,""<>Table[" ",#+Floor[#/3]],b}],a}])&

4

Pip , 38 byte

37 byte mã, +1 cho -ncờ.

Ph:'-Xa<>3JW'+PsX#h-2WR:'|Xb<>2J'+^xh

Lấy chiều rộng và chiều cao làm đối số dòng lệnh. Hãy thử trực tuyến!

Giải trình

                         a,b are cmdline args; s is space; x is empty string (implicit)
Ph:'-Xa<>3JW'+
   '-Xa                  String of hyphens of length a
       <>3               grouped into substrings of (maximum) length 3
          JW'+           Join on +, also wrapping the result in +
 h:                      Assign that string to h (mnemonic: "header")
P                        and print it (with newline)

PsX#h-2WR:'|Xb<>2J'+^xh
          '|Xb           String of pipes of length b
              <>2        grouped into substrings of (maximum) length 2
                 J'+     joined on +
                    ^x   and split on empty string (i.e. converted to list of chars)
 sX#h-2                  String of len(h)-2 spaces
       WR:               Wrap the spaces with the list of chars
                         Note 1: WR operates itemwise on lists, so the result is a list,
                          each item of which consists of the spaces wrapped in an item
                          from the list of chars
                         Note 2: the : compute-and-assign meta-operator is here abused
                          to give WR: lower precedence than J and ^ and avoid parentheses
P                        Print that list, newline-separated (-n flag)
                      h  Autoprint the header a second time as the footer

4

Than, 47 45 40 byte

F⁴«¿﹪ι³FIη↓⁺×+¬﹪κ²|FIθ⁺×+¬﹪κ³-P+¿⁼ι¹J⁰¦⁰

Giải thích: Hoạt động bằng cách lần lượt vẽ từng -s / |s, chèn +s khi cần thiết, sau đó hoàn thiện bằng a +. Sau khi vẽ mặt trên và mặt phải, nhảy trở lại điểm bắt đầu để vẽ chúng theo thứ tự ngược lại, vẽ mặt trái và mặt dưới một cách hiệu quả. Tôi không biết liệu đối xứng quay có được phép hay không, nhưng nếu vậy, thì với 27 25 byte:

F⁴«FI⎇﹪ι²ηθ⁺×+¬﹪κ⁻³﹪ι²-⟲T

Đưa ý tưởng trên đến cực điểm bằng cách vẽ mặt trên, xoay trái, vẽ mặt phải, xoay lại, rồi lặp lại để vẽ mặt dưới và mặt trái theo chiều ngược lại.


1
@LeakyNun Lần trước tôi đánh bại Pyth là để nhân đôi một số kim cương, và thậm chí sau đó nó chỉ ngắn hơn.
Neil

4

JavaScript (ES6), 133 132 byte

w=>h=>(a="-".repeat(w).replace(/--?-?/g,"+$&")+`+`)+(`
|`.padEnd(a.length)+`|`).repeat(h).replace(/(\|( +)\|\n)\1/g,`$&+$2+
`)+`
`+a

Đưa đầu vào theo cú pháp currying : f(width)(height).

Kiểm tra đoạn trích

f=
w=>h=>(a="-".repeat(w).replace(/--?-?/g,"+$&")+`+`)+(`
|`.padEnd(a.length)+`|`).repeat(h).replace(/(\|( +)\|\n)\1/g,`$&+$2+
`)+`
`+a
O.innerHTML=f(W.value=5)(H.value=10)
<div oninput="O.innerHTML=f(+W.value)(+H.value)">
W <input id=W type=number min=1> H <input id=H type=number min=1>
</div>
<pre id=O>



2

Java (OpenJDK 8) , 178 177 byte

w->h->{int i=0;String t="",m,r;for(;i<w;)t+=i++%3<1?"+-":"-";r=t+="+\n";m=t.format("|%"+(t.length()-3)+"s|\n","");for(i=0;i<h;)r+=i++%2<1&i>1?m.replace("|","+")+m:m;return r+t;}

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

-1 byte nhờ @KevinCruijssen


Bạn có thể lưu một byte bằng cách cuộn các tham số: w->h-> Hãy thử ở đây.
Kevin Cruijssen

Đúng, tôi liên tục quên về cà ri ... Đó không phải là điều tôi thấy tự nhiên: s
Olivier Grégoire

1

Than , 47 45 37 byte

A…+---÷⁺²×⁴N³αA…+||÷⁺¹×³N²βPα↓βα+↖↑⮌β

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

  • 2 byte được lưu sau khi chơi với các dấu hiệu trong việc tạo chuỗi.
  • 8 byte được lưu nhờ Neil, người đã đưa ra một cách đơn giản hơn nhiều để tính toán độ dài của hàng rào.

Một cách tiếp cận khác với @ Neil's : đầu tiên tôi tạo các chuỗi αβchứa các ký tự theo đường viền ngang và dọc, sử dụng Rangetoán tử tạo ra sự lặp lại của chuỗi cho đến khi đạt được độ dài nhất định. Sau đó tôi in chúng theo đúng thứ tự:

  • In α mà không di chuyển con trỏ.
  • In xuống dưới.
  • In α.
  • In một "+".
  • Di chuyển con trỏ lên và sang trái.
  • In lên trên, đảo ngược.

Liên kết đến một phiên bản dài dòng .


1
Cảm ơn đã nhắc nhở tôi Range, điều đó giúp tiết kiệm 3 byte cho cách tiếp cận thứ hai của tôi!
Neil

@Neil thật tuyệt vì tôi vừa vượt qua bạn và tôi không thể tin được. :-)
Charlie

1
Vẫn tốt hơn, tôi quản lý để tối ưu hóa các biểu thức của bạn, tiết kiệm 8 byte : A…+---÷⁺²×⁴N³αA…+||÷⁺¹×³N²βPα↓βα+↖↑⮌β.
Neil

@Neil Wow. Tối ưu hóa như vậy. Rất than.
Charlie

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.