Fammi una recinzione!


15

Sfida

Questa è una sfida semplice. Dati due numeri interi positivi w e hcrea una recinzione ASCII con una larghezza di we un'altezza di h. La recinzione deve essere costruita utilizzando le seguenti regole:

  • Il +personaggio rappresenterà un post.
  • Il -personaggio verrà utilizzato per rappresentare la larghezza della recinzione.
  • La |saranno utilizzati per rappresentare l'altezza della recinzione.
  • Dopo che sono stati emessi esattamente tre -personaggi, un +personaggio deve essere emesso in seguito. Escludendo i quattro angoli, ogni altra volta che si emette un non +sarebbe valido. Puoi seguire questa regola partendo da sinistra o da destra (vedi esempi), ma devi essere coerente.
  • Dopo che sono stati emessi esattamente due |personaggi, un +personaggio deve essere emesso in seguito. Escludendo i quattro angoli, ogni altra volta che si emette un non +sarebbe valido. Puoi seguire questa regola partendo dall'alto o dal basso (vedi esempi), ma devi essere coerente.
  • Ogni recinzione avrà esattamente quattro angoli e ogni angolo sarà rappresentato con un +.

In altre parole: ad ogni tre -caratteri, devi produrre a +. E ad ogni due |caratteri, devi produrre a +.

Puoi presumere che la recinzione sarà sempre un rettangolo e che entrambi we hche non saranno mai maggiori 100o minori di 1. È consentito lo spazio bianco finale e / o precedente.

Esempi / casi di test

w = 1
h = 1

+-+ 
| |
+-+


w = 3
h = 2

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


w = 5
h = 7

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

w = 10
h = 5

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


w = 4
h = 4

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

Regole



3
Ho ragione a capire che potrebbero non esserci due +toccanti?
xnor

@xnor Sì, è corretto.
Christian Dean,

3
Grande prima sfida, comunque.
xnor

1
@LeakyNun Il tuo diritto. Questo è un caso che non avevo in mente quando ho fatto le mie regole. Ho aggiunto una regola per indicare perché +-+-+-+-+-+non è valido. Dispiace per la confusione.
Christian Dean,

Risposte:


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

Provalo online!

Spiegazione:

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

Provalo online!


2
Ora è più lungo ma il problema è stato risolto.
GarethPW,

1
È possibile salvare un byte rimuovendo lo spazio tra ine [w+1+(w-1)//3]]nell'ultima parte.
Christian Dean,

1
Benvenuti in PPCG! Puoi anche rimuovere lo spazio '\n') for. Inoltre, è possibile passare (w-1)a ~-wquale consente di rimuovere le parentesi poiché gli operatori unari hanno una precedenza maggiore rispetto a quelli binari. Lo stesso per (h-1)-> ~-he (a-1)-> ~-a. Provalo online - 128 byte
musicman523

1
Inoltre, poiché tutto l'output è stampato, ha def f(w,h)la stessa lunghezza di lambda w,h, ma ti consente di utilizzare più righe se ciò ti aiuta a
golfare

1
a=~-w//3-~w;per salvare 1 byte
Felipe Nardi Batista,

4

Mathematica, 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 di codice, +1 per la -nbandiera.

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

Accetta larghezza e altezza come argomenti della riga di comando. Provalo online!

Spiegazione

                         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

Carbone, 47 45 40 byte

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

Spiegazione: Opere di disegno ciascun fianco di -s / |s, a sua volta, inserendo +s ove necessario, poi finire con un +. Dopo aver disegnato i lati superiore e destro, torna all'inizio per disegnarli in ordine inverso, disegnando efficacemente i lati sinistro e inferiore. Non so se sia consentita la simmetria rotazionale, ma in tal caso, quindi per 27 25 byte:

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

Porta l'idea di cui sopra all'estremo disegnando il lato superiore, ruotando a sinistra, disegnando il lato destro, ruotando di nuovo e quindi ripetendo per disegnare il lato inferiore e il lato sinistro al contrario.


1
@LeakyNun L'ultima volta che ho battuto Pyth era per raddoppiare alcuni diamanti, e anche allora era solo più breve.
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

Riceve l'input nella sintassi accattivarsi: f(width)(height).

Test snippet

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>




1

Carbone , 47 45 37 byte

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

Provalo online!

  • 2 byte salvati dopo aver giocato con i segni nella creazione della stringa.
  • 8 byte salvati grazie a Neil, che ha escogitato un modo molto più semplice per calcolare la lunghezza delle recinzioni.

Un approccio diverso da quello di @ Neil : per prima cosa creo le stringhe αe βcontengo i caratteri nei bordi orizzontale e verticale, usando l' Rangeoperatore che crea una ripetizione di una stringa fino a raggiungere una determinata lunghezza. Quindi le stampo nell'ordine corretto:

  • Stampa α senza spostare il cursore.
  • Stampa β verso il basso.
  • Stampa α.
  • Stampa un "+".
  • Sposta il cursore verso l'alto e verso sinistra.
  • Stampa β verso l'alto, invertita.

Collegamento a una versione dettagliata .


1
Grazie per avermelo ricordato, questo mi fa Rangerisparmiare 3 byte sul mio secondo approccio!
Neil,

@Neil è carino perché ti ho appena superato e non ci posso credere. :-)
Charlie,

1
Meglio ancora, sono riuscito a ottimizzare le espressioni, risparmiando 8 byte: A…+---÷⁺²×⁴N³αA…+||÷⁺¹×³N²βPα↓βα+↖↑⮌β.
Neil,

@Neil Wow. Tale ottimizzazione. Molto carbone.
Charlie,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.