Faça-me uma cerca!


15

Desafio

Este é um desafio simples. Dados dois inteiros positivos w e hcrie uma cerca ASCII com largura we altura de h. A cerca deve ser construída usando as seguintes regras:

  • O +personagem representará uma postagem.
  • O -personagem será usado para representar a largura da cerca.
  • O |será usado para representar a altura da cerca.
  • Após exatamente três -caracteres terem sido produzidos, um +caractere deve ser produzido posteriormente. Excluindo os quatro cantos, qualquer outra vez que você gerar a +seria inválido. Você tem permissão para seguir esta regra começando pela esquerda ou pela direita (veja exemplos), mas você deve ser consistente.
  • Após exatamente dois |caracteres terem sido produzidos, um +caractere deve ser produzido posteriormente. Excluindo os quatro cantos, qualquer outra vez que você gerar a +seria inválido. Você tem permissão para seguir esta regra começando de cima ou de baixo (veja exemplos), mas você deve ser consistente.
  • Cada cerca terá exatamente quatro cantos e cada canto será representado com um +.

Em outras palavras: a cada três -caracteres, você deve gerar a +. E a cada dois |caracteres, você deve gerar a +.

Você pode supor que a cerca sempre será um retângulo e que ambas we hnunca serão maiores 100ou menores que 1. Trailing e / ou espaço em branco anterior é permitido.

Exemplos / Casos de Teste

w = 1
h = 1

+-+ 
| |
+-+


w = 3
h = 2

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


w = 5
h = 7

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

w = 10
h = 5

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


w = 4
h = 4

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

Regras



3
Estou certo de entender que pode não haver dois +toques?
xnor

@ xnor Sim, está correto.
Christian Dean

3
Grande primeiro desafio, a propósito.
xnor

1
@LeakyNun Você está certo. Esse é um caso que eu não tinha em mente ao fazer minhas regras. Eu adicionei uma regra para declarar por que +-+-+-+-+-+é inválido. Desculpe pela confusão.
Christian Dean

Respostas:


9

C, 131 bytes

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

Experimente online!

Explicação:

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

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

Experimente online!


2
Agora está mais longo, mas o problema foi corrigido.
GarethPW

1
Você pode salvar um byte removendo o espaço entre ine [w+1+(w-1)//3]]na última parte.
Christian Dean

1
Bem-vindo ao PPCG! Você pode remover o espaço '\n') fortambém. Além disso, você pode mudar (w-1)para ~-wqual permite remover os parênteses, pois os operadores unários têm uma precedência mais alta que os binários. O mesmo para (h-1)-> ~-he (a-1)-> ~-a. Tente online - 128 bytes
musicman523

1
Também desde toda a sua saída é impressa, def f(w,h)é o mesmo comprimento que lambda w,h, mas permite que você use várias linhas se isso ajuda você golf o seu código ainda mais
musicman523

1
a=~-w//3-~w;salvar 1 byte
Felipe Nardi Batista

4

Mathematica, 165 bytes

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 bytes

37 bytes de código, +1 para -nsinalizador.

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

Leva largura e altura como argumentos da linha de comando. Experimente online!

Explicação

                         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

Carvão, 47 45 40 bytes

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

Explicação: Trabalha desenhando -s / |s de cada lado , inserindo +s sempre que necessário, e finalizando com a +. Depois de desenhar os lados superior e direito, salta de volta ao início para desenhá-los na ordem inversa, desenhando efetivamente os lados esquerdo e inferior. Não sei se a simetria rotacional é permitida, mas se sim, então para 27 25 bytes:

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

Leva a idéia acima ao extremo, desenhando o lado superior, girando para a esquerda, desenhando o lado direito, girando novamente e depois repetindo para desenhar os lados inferior e esquerdo ao contrário.


1
@LeakyNun A última vez que derrotei Pyth foi por dobrar alguns diamantes, e mesmo assim foi apenas mais curto.
Neil

4

JavaScript (ES6), 133 132 bytes

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

Recebe entrada na sintaxe de currying: f(width)(height) .

Snippet de teste

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

Carvão , 47 45 37 bytes

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

Experimente online!

  • 2 bytes salvos após jogar com os sinais na criação da string.
  • 8 bytes economizados graças a Neil, que criou uma maneira muito mais simples de calcular o comprimento das cercas.

Uma abordagem diferente da @ Neil's : primeiro, crio as strings αe βos caracteres nas bordas horizontal e vertical, usando o Rangeoperador que cria a repetição de uma string até que um determinado comprimento seja atingido. Em seguida, imprimo-os na ordem correta:

  • Imprima α sem mover o cursor.
  • Imprima β para baixo.
  • Imprimir α.
  • Imprima um "+".
  • Mova o cursor para cima e para a esquerda.
  • Imprima β para cima, invertido.

Link para uma versão detalhada .


1
Obrigado por me lembrar Range, isso economiza 3 bytes na minha segunda abordagem!
Neil

@ Neil isso é legal porque acabei de derrotar você e simplesmente não consigo acreditar. :-)
Charlie

1
Melhor ainda, consegui otimizar suas expressões, economizando 8 bytes: A…+---÷⁺²×⁴N³αA…+||÷⁺¹×³N²βPα↓βα+↖↑⮌β.
28417 Neil

@Neil Wow. Essa otimização. Muito carvão.
Charlie

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.