Escale um ladrilho de diamante


27

Qualquer hexágono regular pode ser revestido com diamantes, por exemplo:

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/

Consideraremos o tamanho acima de um ladrilho 1(já que os lados dos diamantes são feitos de um /ou de \cada). O mesmo tamanho do tamanho 2seria semelhante a:

      ____________ 
     /   /   /\   \  
    /___/___/  \___\ 
   /   /\   \  /\   \  
  /___/  \___\/  \___\ 
 /\   \  /   /\  /   /\  
/  \___\/___/  \/___/  \ 
\  /   /\   \  /   /\  /
 \/___/  \___\/___/  \/ 
  \   \  /   /\   \  /
   \___\/___/  \___\/ 
    \   \   \  /   /
     \___\___\/___/ 

Sua tarefa é receber uma peça de arte ASCII (de tamanho 1) como entrada, juntamente com um número inteiro positivo N(em decimal ou unário), especificando o tamanho da saída desejada. Em seguida, você deve produzir uma versão ampliada do mesmo lado a lado.

Observe que o hexágono pode ser de qualquer tamanho e tão pequeno quanto 1x1x1 (contendo três diamantes).

Nem a entrada nem a saída devem conter espaços à direita, nem mais espaços à esquerda do que o necessário para alinhar a forma do hexágono. Opcionalmente, entrada e saída podem conter uma nova linha final à direita (essa opção não precisa ser a mesma para entrada e saída).

Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e emitindo o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou parâmetro da função (saída).

Isso é código de golfe, então a resposta mais curta (em bytes) em vitórias.

Exemplo de inclinações

Aqui estão algumas sugestões de sugestões que você pode usar para testar seu envio.

 __
/_/\
\_\/

  ____
 /_/\_\
/\_\/_/\
\/_/\_\/
 \_\/_/

   ______
  /_/_/\_\
 /_/\_\/\_\
/\_\/_/\/_/\
\/_/\_\/_/\/
 \_\/_/\_\/
  \_\_\/_/

    ________
   /_/\_\_\_\
  /\_\/\_\_\_\
 /\/_/\/_/_/\_\
/\/\_\/_/_/\/\_\ 
\/\/_/\_\_\/\/_/
 \/\_\/_/\_\/_/
  \/\_\_\/_/_/
   \/_/_/_/_/

O seguinte fragmento contém as saídas para as entradas correspondentes N = 1através N = 6.


20
Vejo que você está interessado em diamantes agora que possui um próximo ao seu nome de usuário.
User12205

3
@ace: Você sabe o que dizem: os diamantes são os melhores amigos de um moderador.
Alex A.

Acho que sei a resposta, mas espero estar errado: linhas vazias à frente contariam como espaço à esquerda, que você declarou ilegal? Minha solução inicial tem N-1linhas vazias à esquerda. :(
Reto Koradi

@RetoKoradi De fato, não há novas linhas de liderança. Desculpe.
Martin Ender

1
Eu imaginei. Custou-me cerca de 10 bytes. Não é tão ruim quanto parecia quando reconheci o problema pela primeira vez.
Reto Koradi

Respostas:


8

CJam, 85 79 76 72 bytes

li:Tlf*NqN/T,f{ff{"_/"2$#_1<@+*~ST*@t}:+z{S+e`);e~{"_ "/"__"*W%}T2**N}/}

O tamanho deve estar na primeira linha. E o diamante segue.

Não jogou muito bem ... E metade dos personagens veio dos detalhes.

Explicações (da versão anterior)

li:T            e# Read the size and save to T.
qN/             e# Read and split to lines.
\,fm*           e# Convert each character X to [X 0] [X 1]... [X T(]
{~              e# For each [X I] in each line:
    ST*         e# T spaces.
    \           e# I.
    "_\\"3$#    e# If X is '_, '\ or '/, return Y = 0, 1, -1 respectively.
    _W>@+       e# If it was '_ or '\, increase I by one.
    *(          e# I * Y - 1.
    @t          e# Set the character at that position to X.
}f%
:z:+            e# Make the returned lists from each iteration across T lines.
{S+e`);e~N+}%   e# Boring details to remove trailing spaces and append a newline.
T(>(\s          e# Boring details to extract the first line and only work on others.
{_{"_ "/"__"*W%}2*_@=!}g
                e# Boring details to make underlines expand left and right.

10

Python 2, 164

def g(s,n,j=1):
 for W in s.split("\n"):exec"O=p='';d=0\nfor c in W:q=' _'[j*'_'in p+c];e=[n-j,j-1][c=='/'];O+=q*(e+d)+[c,q][c>'^'];p=c;d=n+~e\nprint O;j-=1;"*j;j=n

Saída em casos de teste.

Então, o que está acontecendo aqui?

A idéia principal é que cada personagem no original exploda em um n*nbloco. Por exemplo, para n = 4, /pode se tornar

   /
  /
 /
/___

O caractere original aparece uma vez em cada linha e há preenchimento para ambos os lados. Aqui, está à esquerda e _à direita. Somente a linha inferior pode ser preenchida '_'; o resto é sempre ' '.

A principal dificuldade é que o preenchimento à direita pode depender do próximo símbolo. Especificamente, '/ 'tem preenchimento diferente de '/_', portanto, precisamos de um olhar à frente. Além disso, para evitar espaços à direita, teríamos que observar que estamos no último símbolo e evitamos o preenchimento à direita.

Superamos esses dois problemas apenas preenchendo a esquerda do personagem atual. Quando fazemos isso, também executamos o preenchimento à direita do caractere anterior usando o símbolo de preenchimento atual. Portanto, imprimimos o preenchimento à direita devido ao caractere anterior, o preenchimento à esquerda do caractere atual e o caractere atual. Também armazenamos a quantidade de "dívida" de preenchimento que o próximo caractere precisará pagar.

Agora vamos revisar o código.

def g(s,n,j=1):
    for W in s.split("\n"):
        while j:
            O=p='';d=0
            for c in W:
                q=' _'[j*'_'in p+c]
                e=[n-j,j-1][c=='/']
                O+=q*(e+d)+[c,q][c>'^']
                p=c
                d=n+~e
            print O;j-=1;
        j=n

A sequência de entrada é se o fator de escala é n. Vamos linha por linha, nlinhas de impressão para cada linha de entrada W, com as cópias indexadas j=n,n-1,...,2,1. A primeira linha é copiada apenas uma vez, o que é possível ao inicializar jem 1, mas alterando-a para ncada loop.

Nós iteramos pela linha de entrada, acumulando a linha para imprimir O. Primeiro, descobrimos o caractere de preenchimento apropriado q, que é um sublinhado se estivermos na linha inferior e se o caractere atual ou anterior é um sublinhado e, de outra forma, um espaço.

Depois, decidimos a quantidade de preenchimento a colocar à esquerda ( e). Para /, é j-1(diminuindo com o número decrescente de cópias de linha) e o complementar n-jpara \. Tratamos outros personagens da mesma maneira. Por exemplo, embora _pareça dar uma linha de nsublinhados, na verdade, ele fornece um único sublinhado, preenchido por sublinhados à esquerda e à direita. Isto parece ineficiente, mas nos permite trabalha com _e no mesmo quadro /e \A posição do sublinhado "central" não importa, por isso, fixo-lo e com \; essa escolha também faz com que a linha superior funcione sem revestimento especial.

Em seguida, adicionamos à string de saída. Descobrimos o símbolo do preenchimento qe o valor atual do preenchimento e, mas também precisamos lembrar a dívida ddo preenchimento do símbolo anterior. Então, adicionamos q*(e+d). Em seguida, adicionamos o símbolo atual c, exceto que precisamos evitar sublinhados em uma linha que não seja inferior, que corrigimos convertendo sublinhados no símbolo de preenchimento.

Por fim, registramos o valor da dívida de preenchimento, que é o complemento n+~ddo valor atual de preenchimento à esquerda. Também registramos o símbolo atual em p, para que depois possamos saber se o símbolo anterior era _.


3

JavaScript ( ES6 ) 274 281 289 338

// GOLFED
F=(b,n)=>{
b=b[R='replace'](/ |_/g,c=>c[T='repeat'](n))[R](/_(?=[\\\/])/g,'_'[T](n))[R](/\/\\/g,`/${'  '[T](n-1)}\\`)
.split('\n');
for(i=l=b.length*n-n+1;--i;)
b[i]=i%n?b[i+1][R](/_/g,' ')[R](/\/ ?/g,' /')[R](/ \\(.)?/g,'\\$1$1')
:' '[T](i>l/2?n-1:0)+b[i/n];
return b.join('\n')}


// UNGOLFED
U=(b,n)=>{
  b=b
  .replace(/ |_/g,c=>c.repeat(n))
  .replace(/_(?=[\/\\])/g,'_'.repeat(n))
  .replace(/\/\\/g,`/${'  '.repeat(n-1)}\\`)
  .split('\n');
  for(i=l=b.length*n-n+1;--i;)
  {
    if(i%n)
     b[i]=b[i+1]
     .replace(/_/g,' ')
     .replace(/\/ ?/g,' /')
     .replace(/ \\/g,'\\ ').replace(/ +$/,'')
     .replace(/ \\(.)?/g,'\\$1$1')
    else {
      b[i]=b[i/n]
      if(i>l/2)b[i]=' '.repeat(n-1)+b[i];
    }
  }
  return b.join('\n')
}

//TEST

test=[
' __\n/_/\\\n\\_\\/',
'  ____\n /_/\\_\\\n/\\_\\/_/\\\n\\/_/\\_\\/\n \\_\\/_/',
'   ______\n  /_/_/\\_\\\n /_/\\_\\/\\_\\\n/\\_\\/_/\\/_/\\\n\\/_/\\_\\/_/\\/\n \\_\\/_/\\_\\/\n  \\_\\_\\/_/',
'    ________\n   /_/\\_\\_\\_\\\n  /\\_\\/\\_\\_\\_\\\n /\\/_/\\/_/_/\\_\\\n/\\/\\_\\/_/_/\\/\\_\\\n\\/\\/_/\\_\\_\\/\\/_/\n \\/\\_\\/_/\\_\\/_/\n  \\/\\_\\_\\/_/_/\n   \\/_/_/_/_/'
]

test.forEach(t=>{
  var row = '<td>'+t+'<td>'
  for(rr=2;rr<5;rr++)
    row += '<td>'+F(t,rr)+'</td>'
  OUT.innerHTML += '<tr>'+row+'</tr>'
})
td {
  font-family: monospace;
  white-space: pre;
}
(better full page)
<table id=OUT></table>


3

Python 2, 217 211 195 194 190

b,f,s='\/ '
R=str.replace
def m(g,n,z=1):
 for d in g.split('\n'):
    for i in range(z):a=z+~i;print[i,a][d[-1]>f]*s+R(R(R(R(d,s,s*n),'_','_ '[i<z-1]*(z+n-1)),f+b,f+s*2*i+b),b+f,b+s*2*a+f);z=n

6 bytes graças ao Sp3000.

Ligue mcom o primeiro argumento sendo o diamante como uma corda, e o segundo argumento com o número de repetição.

Isso se baseia em uma sequência de substituição de cadeia de três etapas:

  • Primeiro, substitua os sublinhados por espaços 2n-1 ou sublinhados, dependendo da linha.
  • Segundo, substitua /\por / \, pelo número de espaços intermediários, passando de 2 para 2 * (n-1) sobre as linhas.
  • Terceiro, substitua \/por \ /, com o número de espaços intermediários, passando de 2 * (n-1) para 2 acima das linhas.

Depois, há uma variedade de mudanças para acertar os espaços principais e acertar a primeira linha.

Observe que a linha final do programa deve ser uma guia, não quatro espaços. O Markdown não suporta guias.


Dois campos de golfe: (i+(n-i+~i)*(d[-1]>f)) --> [i,n+~i][d[-1]>f]você usa apenas '_'uma vez e perde um byte ao defini-lo.
Sp3000

3

Python, 272 238 228 243 bytes

Versão atualizada, agora usa uma única string como entrada, em vez de uma sequência de strings. Também remove o espaço em branco à direita que estava presente na versão anterior. Infelizmente, essas alterações aumentam o tamanho.

s,u,f,b=' _/\\'
r=str.replace
def d(t,n,j=1):
 for p in t.split('\n'):
  for k in range(n-j,n):m,v=n+~k,'_ '[k<n-1];print r(r(r(r(r(r(r(r(p,f+u,'(_'),u+b,'_)'),s,s*n),u,v*n),f,s*m+f+s*k),'(',v*m+f+v*k),b,s*k+b+s*m),')',v*k+b+v*m).rstrip();j=n

Versão com espaço em branco e instruções divididas em unidades menores para facilitar a leitura:

s, u, f, b = ' ', '_', '/', '\\'
def d(t, n):
    j = n - 1
    for p in t:
        for k in range(j, n):
            m, v = n - 1 - k, '_ '[k < n - 1]
            q = p[:-1]
            q = q.replace(f + u, '(_')
            q = q.replace(u + b, '_)')
            q = q.replace(s, s * n)
            q = q.replace(u, v * n)
            q = q.replace(f, s * m + f + s * k)
            q = q.replace('(', v * m + f + v * k)
            q = q.replace(b, s * k + b + s * m)
            q = q.replace(')', v * k + b + v * m)
            print q
            j = 0

A abordagem básica aqui é:

  1. Passe por todas as linhas na entrada.
  2. Para cada linha, faça um loop sobre o tamanho da saída N, gerando uma linha de saída em cada iteração do loop. Há um caso especial para a primeira linha, onde apenas a última linha de saída é gerada, para evitar a geração de linhas vazias no início da saída.
  3. Substitua cada caractere na linha por Ncaracteres, onde:
    • Cada espaço é substituído por Nespaços.
    • Cada sublinhado é substituído por Nespaços para as primeiras N -1iterações de loop e Nsublinhados para a última iteração de loop.
    • Barras e barras invertidas são preenchidas com N - 1espaços ou sublinhados.

A parte mais complicada aqui é que o preenchimento de barras / barras invertidas usa espaços ou sublinhados, dependendo do próximo caractere de entrada (para barras) ou anterior (para barras invertidas). Isso não parecia se encaixar bem na estratégia de substituição de cordas.

O que fiz para resolver isso é que primeiro substituo certas combinações de dois caracteres por caracteres diferentes, para que eu possa tratá-las de maneira diferente durante a substituição real. Por exemplo, /_é substituído por (_. Depois disso, (é efetivamente uma "barra seguida de sublinhado", que pode ser substituída de acordo.

Programa principal usado para testar a função:

import sys
import Golf

n = int(sys.argv[1])
t = ''.join(sys.stdin).rstrip()

Golf.d(t, n)

1
n-1-kén+~k
recursiva

No interesse da divulgação completa: Acabei de descobrir que minha solução produz alguns espaços à direita. Como isso não é permitido na definição de saída, ele não atende aos requisitos. Na pior das hipóteses, vou ter que adicionar .rstrip()mais 9 caracteres. Espero poder fazer melhor, e também encontrei uma maneira de cortar 5 caracteres.
Reto Koradi

Parece que seu formato de entrada não é permitido. sys.stdinnão é um parâmetro de entrada permitido - você precisa manipular a própria string.
Isaacg

Bem, você pode usá sys.stdin- int(sys.argv[1])lo, mas não os conseguirá de graça, esperando que sejam passados ​​como variáveis ​​(se esse foi um jogo justo, você também pode esperar apelidos para rangee substituir` e o que mais precisar para ser predefinido) .
Martin Ender

@ MartinBüttner Diz que posso aceitar a entrada como argumento de função. Não é isso que estou fazendo aqui? Eu ia mudar o argumento da função para uma lista de cadeias de qualquer maneira. Isso seria bom? Não é muito diferente, pois ambas stdine uma lista de seqüências de caracteres são sequências de seqüências.
Reto Koradi

1

Perl, 132

#!perl -p
INIT{$f=pop}s!.!$&x$f!ge;s! $!! while s!\\+\K\\|/(/)! $1!;
for$x(2..m!/!*$f){print y!_! !r;s!\\.?! \\!g;s!./(.)?!/$1$1!g;s!_ !__!g}

Entrada combinada STDIN e ARGV. Exemplo:

$ perl ~/hex.pl <~/hex.txt 3
         __________________
        /     /     /\     \
       /     /     /  \     \
      /_____/_____/    \_____\
     /     /\     \    /\     \
    /     /  \     \  /  \     \
   /_____/    \_____\/    \_____\
  /\     \    /     /\    /     /\
 /  \     \  /     /  \  /     /  \
/    \_____\/_____/    \/_____/    \
\    /     /\     \    /     /\    /
 \  /     /  \     \  /     /  \  /
  \/_____/    \_____\/_____/    \/
   \     \    /     /\     \    /
    \     \  /     /  \     \  /
     \_____\/_____/    \_____\/
      \     \     \    /     /
       \     \     \  /     /
        \_____\_____\/_____/

1

Ruby 236 237

->i,z{i.split(?\n).map{|l|z.times.map{|y|l.size.times.map{|i|z.times.map{|x|c=l[i]
z<y+2&&(l[i-1..i]=='_\\'||l[i..i+1]=='/_')&&o=?_
(c<?!||(x==y&&c==?\\)||(z==y+1&&c>?^)||(x+y+1==z&&c==?/))&&o=c
o||' '}.join}.join.rstrip}-['']}.join ?\n}

Teste on-line: http://ideone.com/e6XakQ

Este é o código antes de jogar golfe:

-> diamond, zoom {
  diamond.split(?\n).map do |l|
    zoom.times.map do |y|
      l.size.times.map do |i|
        zoom.times.map do |x|
          out_char = crt_char = l[i]

          out_char = ' '

          # _ has to be continued under / or \
          if zoom == y+1 && l[i-1..i]=='_\\'
            out_char = ?_
          end
          if zoom == y+1 && l[i..i+1]=='/_'
            out_char = ?_
          end

          # logic to "zoom" \, / and _ characters 
          out_char = crt_char if crt_char == ' '
          out_char = crt_char if x==y && crt_char == ?\\  
          out_char = crt_char if zoom==y+1 && crt_char == ?_
          out_char = crt_char if x+y+1==zoom && crt_char == ?/

          out_char
        end.join
      end.join.rstrip
    end - ['']
  end.join ?\n
}
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.