放大钻石拼贴


27

任何规则的六角形都可以用钻石平铺,例如:

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

我们将考虑上面的大小拼贴1(因为钻石的侧面是由一个/\每个组成)。相同大小的瓦片2看起来像:

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

您的任务是接收这样的ASCII艺术图块(大小1)作为输入,以及一个正整数N(十进制或一进制),指定所需输出的大小。然后,您应该输出相同切片的放大版本。

请注意,六边形可以是任意大小,并且小至1x1x1(包含三颗菱形)。

输入或输出都不得包含任何尾随空格,也不得包含超过对齐六边形所需的任何前导空格。输入和输出都可以选择包含一个尾随换行符(此选择对于输入和输出不必相同)。

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行参数或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

这是代码高尔夫,因此获胜时最短的答案(以字节为单位)。

拼贴示例

这里有一些输入图块,您可以用来测试提交。

 __
/_/\
\_\/

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

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

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

以下代码段包含N = 1通过进行输入的相应输出N = 6


20
我看到您对钻石感兴趣,因为您的用户名旁边有一个。
user12205

3
@ace:您知道他们在说什么:钻石是版主的最好的朋友。
Alex A.

我想我知道答案,但是我希望我是错的:空行开头将被视为领先空间,您认为这是非法的?我最初的解决方案N-1有空行。:(
Reto Koradi 2015年

@RetoKoradi确实,没有领先的换行符。抱歉。
Martin Ender 2015年

1
我估计。花了我大约10个字节。并没有我最初认识到这个问题时看起来那么糟糕。
Reto Koradi 2015年

Answers:


8

CJam,85 79 76 72字节

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

大小应在第一行。钻石随之而来。

打高尔夫球不是很好。一半的角色来自细节。

解释(以前的版本)

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

输出测试用例。

那么,这是怎么回事?

主要思想是将原始字符中的每个字符炸成一个n*n块。例如,对于n = 4,/可能变为

   /
  /
 /
/___

原始字符在每行中出现一次,并且在两边都有填充。在这里,它的左侧,并_在右侧。只有底行可以用填充'_'; 其余的永远都是' '

主要困难在于,右侧的填充可能取决于即将出现的符号。具体来说,与相比'/ '具有不同的填充'/_',因此我们需要提前一些注意。此外,为避免尾随空格,我们必须注意,我们位于最后一个符号处,请勿在右边填充。

我们通过仅填充当前字符的左侧来克服了这两个问题。这样做时,我们还将使用当前的填充符号从上一个字符开始右填充。因此,我们先打印上一个字符的右填充,再打印当前字符的左填充,再打印当前字符。我们还存储下一个字符需要支付的填充“债务”的金额。

现在让我们来看一下代码。

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

输入字符串为s,比例因子为n。我们逐行打印n每行输入的行W,并为副本建立索引j=n,n-1,...,2,1。第一行仅复制一次,我们可以通过初始化j为1并将其更改为n每个循环来实现。

我们遍历输入行,累积要打印的行O。首先,我们找出适当的填充字符q,如果我们位于最底行,则该字符为下划线,而当前字符或前一个字符为下划线,否则为空格。

然后,我们确定要放在左侧(e)的填充量。对/,这是j-1和互补(随线拷贝数减少)n-j\。我们以相同的方式对待其他字符。例如,尽管_看起来它给出了n下划线,但实际上它给出了单个下划线,并在左右两侧用下划线填充。这似乎效率不高,但它让我们的工作与_在同一框架/\“中央”下划线的位置并不重要,所以我们忍下这口气,并\; 这种选择还可以使顶部的行无需特殊的外壳即可工作。

接下来,我们将添加到输出字符串。我们已经弄清楚了pad​​ding符号q和当前的padding数量e,但是我们还需要记住d前一个符号的padding债务。因此,我们添加q*(e+d)。然后,我们添加当前符号c,除了需要避免在非底行中使用下划线,我们可以通过将下划线转换为填充符号来解决此问题。

最后,我们记录填充债务金额,它n+~d是当前左填充金额的补充。我们还将当前符号记入其中p,以便以后知道以前的符号是否为_


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字节归功于Sp3000。

m以第一个参数为菱形作为字符串调用,第二个参数为重复编号。

这是基于三步字符串替换序列的:

  • 首先,根据行将下划线替换为2n-1空格或下划线。
  • 其次,将替换/\/ \,行上的中间空格数从2变为2 *(n-1)。
  • 第三,替换 \/\ /,与插入空格的通过线从2 *(N-1)将2的数量。

然后,要想弄清引导空格并弄清楚第一行,有各种各样的方法。

请注意,程序的最后一行应为制表符,而不是4个空格。Markdown不支持标签。


两次高尔夫:(i+(n-i+~i)*(d[-1]>f)) --> [i,n+~i][d[-1]>f]您只使用'_'一次,因此浪费了一个字节来定义它。
Sp3000

3

Python中,272个 238 228 243字节

更新版本,现在仅使用一个字符串作为输入,而不是字符串序列。还删除早期版本中存在的尾随空格。不幸的是,这些更改增加了大小。

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

带有空格的版本,为了便于阅读,将语句分成较小的单元:

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

这里的基本方法是:

  1. 循环输入中的所有行。
  2. 对于每一行,循环遍历输出大小N,在每次循环迭代中生成一条输出行。第一行有一种特殊情况,即仅生成最后一条输出行,以避免在输出开始时生成空行。
  3. 用字符替换该行中的每个字符N,其中:
    • 每个空格都被N空格替换。
    • N对于下一个N -1循环迭代,每个下划线都由空格代替,而对于下一个循环迭代,每个下划线都由空格代替N
    • 斜杠和反斜杠用N - 1空格或下划线填充。

这里最棘手的部分是,斜杠/反斜杠的填充使用空格或下划线,具体取决于下一个(斜杠)或上一个(反斜杠)输入字符。这似乎不太适合字符串替换策略。

解决此问题的方法是,我先用不同的字符替换某些两个字符的组合,以便在实际替换期间可以区别对待它们。例如,/_被替换(_。在此之后,(实际上是一个“斜杠后跟下划线”,然后可以相应地将其替换。

用于测试功能的主程序:

import sys
import Golf

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

Golf.d(t, n)

1
n-1-kn+~k
递归

为了完全公开:我刚刚发现我的解决方案产生了一些尾随空格。由于输出定义中不允许这样做,因此不符合要求。在最坏的情况下,我必须再添加.rstrip()9个字符。希望我能做得更好,并且找到了减少5个字符的方法。
Reto Koradi 2015年

看来您的输入格式是不允许的。sys.stdin不是允许的输入参数-您需要操纵字符串本身。
2015年

好吧,您可以使用sys.stdinint(sys.argv[1])但不能期望期望它们作为变量传递来免费获得它们(如果那是公平的游戏,那么您还可以期望别名range和替换`,以及需要预先定义的其他内容) 。
马丁·恩德

@MartinBüttner它说我可以将输入作为函数参数。这不是我在这里做什么吗?无论如何,我都打算将function参数更改为字符串列表。可以吗?并没有太大的不同,因为stdin和字符串列表都是字符串序列。
Reto Koradi 2015年

1

珀尔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}

STDIN和ARGV组合输入。例:

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

1

红宝石236237

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

在线测试:http//ideone.com/e6XakQ

这是打高尔夫球之前的代码:

-> 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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.