Зробіть мені паркан!


15

Виклик

Це простий виклик. Дано два додатних цілих числа w і hстворіть огорожу ASCII шириною wі висотою h. Огорожа повинна бути побудована за такими правилами:

  • +Персонаж буде являти собою пост.
  • -Символ буде використовуватися для подання ширина забору.
  • |Використовуватиметься для позначення висоти паркану.
  • Після того ,- як було виведено рівно три символи, +символ повинен бути виведений згодом. Виключаючи чотири кути, будь-який інший час, коли ви виводите а +, буде недійсним. Ви можете дотримуватися цього правила, починаючи зліва або справа (див. Приклади), але ви повинні бути послідовними.
  • Після того ,| як виведено рівно два символи, +символ повинен бути виведений згодом. Виключаючи чотири кути, будь-який інший час, коли ви виводите а +, буде недійсним. Ви можете дотримуватися цього правила, починаючи з верху або знизу (див. Приклади), але ви повинні бути послідовними.
  • Кожен паркан матиме рівно чотири кути, а кожен кут буде представлений символом a +.

Іншими словами: На кожні три -символи ви повинні виводити a +. І кожні два |символи ви повинні виводити a +.

Можна припустити, що огорожа завжди буде прямокутником, і те і те wі hніколи не буде більшим 100або меншим за 1. Дозволяється відстежувати та / або попередні пробіли.

Приклади / Випробування

w = 1
h = 1

+-+ 
| |
+-+


w = 3
h = 2

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


w = 5
h = 7

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

w = 10
h = 5

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


w = 4
h = 4

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

Правила



3
Чи правильно я розумію, що може бути двох +дотиків?
xnor

@xnor Так, це правильно.
Крістіан Дін

3
Великий перший виклик, до речі.
xnor

1
@LeakyNun Ваше право. Це випадок, який я не мав на увазі, коли розробляв свої правила. Я додав правило, щоб вказати, чому +-+-+-+-+-+це недійсне. Вибачте за непорозуміння.
Крістіан Дін

Відповіді:


9

C, 131 байт

#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;}

Спробуйте в Інтернеті!

Пояснення:

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

Пітон 3 , 140 137 128 119 106 105 байт

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')

Спробуйте в Інтернеті!


2
Зараз це вже більше, але проблема виправлена.
GarethPW

1
Ви можете зберегти байт, видаливши пробіл між inі [w+1+(w-1)//3]]в останній частині.
Крістіан Дін

1
Ласкаво просимо до PPCG! Ви також можете видалити простір '\n') for. Крім того , ви можете змінити (w-1)на ~-wякий дозволяє видалити дужки , так як унарні оператори мають більш високий пріоритет , ніж бінарні. Те саме для (h-1)-> ~-hі (a-1)-> ~-a. Спробуйте в Інтернеті - 128 байт
musicman523

1
Крім того, оскільки всі ваші вихідні дані надруковані, def f(w,h)мають однакову довжину lambda w,h, але дозволяють використовувати кілька рядків, якщо це допоможе вам надалі гольф коду
musicman523

1
a=~-w//3-~w;щоб зберегти 1 байт
Феліпе Нарді Батіста

4

Математика, 165 байт

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

Піп , 38 байт

37 байт коду, +1 для -nпрапора.

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

Ширина та висота приймає як аргументи командного рядка. Спробуйте в Інтернеті!

Пояснення

                         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

Вугілля деревне, 47 45 40 байт

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

Пояснення: Працює, малюючи по черзі -s / |s кожної сторони , вставляючи +s, де потрібно, а потім закінчуючи a +. Після того, як намалювали верхню і праву сторони, відскакує назад до початку, щоб намалювати їх у зворотному порядку, ефективно малюючи ліву і нижню сторони. Я не знаю, чи дозволена обертальна симетрія, але якщо так, то для 27 25 байт:

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

Піднімає вищезазначену ідею до крайності, малюючи верхню сторону, обертаючи ліворуч, малюючи праву сторону, знову обертаючись, а потім повторюючи, щоб намалювати нижню та ліву сторони у зворотному напрямку.


1
@LeakyNun Останній раз, коли я переміг Pyth, був за Double в кілька алмазів, і навіть тоді це було лише коротше.
Ніл

4

JavaScript (ES6), 133 132 байт

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

Вводить в синтаксис currying: f(width)(height) .

Тест-фрагмент

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 байт

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

Спробуйте в Інтернеті!

-1 байт завдяки @KevinCruijssen


Ви можете зберегти байт, скориставшись параметрами: w->h-> Спробуйте його тут.
Кевін Круїйсен

Так, я постійно забуваю про каррі ... Це не те, що я вважаю природним: s
Олів'є Грегоар

1

Вугілля , 47 45 37 байт

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

Спробуйте в Інтернеті!

  • 2 байти, збережені після гри зі знаками у створенні рядків.
  • 8 байтів збереглися завдяки Нілу, який придумав набагато простіший спосіб обчислити довжину заборів.

Інший підхід від @ Neil's : спочатку я створюю рядки αі βмістять символи в горизонтальній і вертикальній рамках, використовуючи Rangeоператор, який створює повторення рядка до досягнення заданої довжини. Потім я друкую їх у належному порядку:

  • Друкуйте α, не переміщуючи курсор.
  • Роздрукуйте β вниз.
  • Друк α.
  • Роздрукуйте "+".
  • Перемістіть курсор вгору та вліво.
  • Роздрукуйте β вгору, назад.

Посилання на багатослівну версію .


1
Дякуємо, що нагадали Range, що заощаджує 3 байти під час мого другого підходу!
Ніл

@Neil це приємно, тому що я щойно перевершив тебе, і я просто не можу в це повірити. :-)
Чарлі

1
А ще краще, мені вдалося оптимізувати вираження, економлячи 8 байт: A…+---÷⁺²×⁴N³αA…+||÷⁺¹×³N²βPα↓βα+↖↑⮌β.
Ніл

@Neil Wow. Така оптимізація. Дуже вугілля.
Чарлі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.