ダイヤモンドタイルのスケールアップ


27

たとえば、次のように、通常の六角形にダイヤモンドを並べることができます。

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

上記のサイズのタイルを考慮します1(ダイヤモンドの側面は1つ/または\それぞれで作られているため)。サイズの同じタイリングは次の2ようになります。

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

あなたの仕事は、希望する出力のサイズを指定する1正の整数N(10進数または単項)とともに、そのようなASCIIアートタイリング(サイズ)を入力として受け取ることです。次に、同じタイリングの拡大バージョンを出力する必要があります。

そのノート六角形は任意のサイズおよび1x1x1だけ小さく(3個のダイヤモンドを含む)であってもよいです。

入力と出力のいずれにも、後続のスペースや、六角形を揃えるのに必要な以上の先行スペースを含めることはできません。入力と出力の両方に、オプションで単一の末尾改行を含めることができます(この選択は、入力と出力で同じである必要はありません)。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

これはコードゴルフであるため、勝ちの最短の回答(バイト単位)になります。

タイルの例

以下は、提出物をテストするために使用できる入力タイルです。

 __
/_/\
\_\/

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

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

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

次のスニペットには、N = 1を介しN = 6た入力に対応する出力が含まれています。


20
ユーザー名の横に1つあるので、ダイヤモンドに興味があるようです。
user12205

3
@ace:あなたは彼らが言うことを知っています:ダイヤモンドはモデレーターの親友です。
アレックスA.

私は答えを知っていると思いますが、私が間違っていることを願っています:先行する空の行は、あなたが違法と宣言した先行スペースとしてカウントされますか?私の最初のソリューションには、N-1先頭に空の行があります。:(
レトコラディ

@RetoKoradi確かに、主要な改行はありません。ごめんなさい。
マーティンエンダー

1
私は理解した。約10バイトかかります。最初に問題を認識したときの見た目ほど悪くはありません。
レトコラディ

回答:


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。最初の行は1回だけコピーされます。jこれは、1に初期化してn各ループに変更することでこれを実現しています。

入力行を反復処理して、印刷する行を累積しOます。まず、適切なパディング文字を見つけますq。これは、最終行にいる場合はアンダースコアであり、現在または前の文字がアンダースコアである場合はスペースです。

次に、左側に配置するパディングの量を決定します(e)。の場合/j-1(ラインコピー数の減少とともに減少)、およびの補完n-jです\。他のキャラクターも同じように扱います。たとえば_nアンダースコアの行が表示されるように見えますが、実際には、左右にアンダースコアが埋め込まれた単一のアンダースコアが表示されます。これは非効率的なようだが、それは、私たちはで動作することができます_し、同じ枠組みの中で/\我々はそれをしこりとなるアンダースコアは、問題ではない「中央」の位置\。また、この選択により、特別なケースなしで一番上の列が機能します。

次に、出力文字列に追加します。パディング記号q、および現在のパディング量を計算しましたed、前の記号からのパディング負債を覚えておく必要もあります。そこで、を追加しq*(e+d)ます。次に、現在のsymbolを追加します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

Sp3000のおかげで6バイト。

m最初の引数を文字列としてのダイアモンド、2番目の引数を繰り返し数で呼び出します。

これは、3ステップの文字列置換シーケンスに基づいています。

  • まず、アンダースコアを行に応じて2n-1個のスペースまたはアンダースコアに置き換えます。
  • 2番目に、で置換/\/ \、その間にあるスペースの数を2から2 *(n-1)に変えます。
  • 3番目に、で置換 \/\ /、その間にあるスペースの数を2 *(n-1)から2に増やします。

次に、先頭のスペースを正しくし、最初の行を正しくするためのさまざまなマッキングがあります。

プログラムの最終行は、4つのスペースではなくタブであることに注意してください。Markdownはタブをサポートしていません。


2つのゴルフ:(i+(n-i+~i)*(d[-1]>f)) --> [i,n+~i][d[-1]>f]そして'_'1回しか使用しないので、それを定義するバイトを無駄にします。
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スペースまたはアンダースコアが埋め込まれます。

ここで最も注意が必要なのは、スラッシュ/バックスラッシュのパディングが、次の入力文字(スラッシュの場合)または前の入力文字(バックスラッシュの場合)に応じてスペースまたはアンダースコアを使用することです。これは、文字列置換戦略とうまく合わないようでした。

これを解決するために行ったのは、最初に特定の2つの文字の組み合わせを異なる文字に置き換え、実際の置換中にそれらを異なる方法で処理できるようにすることです。たとえば、/_はに置き換えられ(_ます。これは、(実質的に「アンダースコアが続くスラッシュ」であり、それに応じて置き換えることができます。

機能のテストに使用されるメインプログラム:

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文字を切り取る方法も見つけました。
レトコラディ

入力形式が許可されていないようです。sys.stdin入力パラメータとして許可されていません-文字列自体を操作する必要があります。
isaacg

さて、あなたは使用することができますsys.stdinし、int(sys.argv[1])(その後、あなたもの別名が期待できる、それが公正なゲームだった場合は、それらを変数として渡すことを期待することにより、あなたが自由のためにそれらを得るつもりじゃないけどrange、あなたが事前定義する必要が任意の他とreplace`とし) 。
マーティンエンダー

@MartinBüttnerそれは、関数の引数として入力を取ることができると言っています。これは私がここでやっていることではありませんか?とにかく、関数の引数を文字列のリストに変更するつもりでした。大丈夫でしょうか?両方stdinと文字列のリストは文字列シーケンスであるため、それほど違いはありません。
レトコラディ

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}

STDINとARGV入力の組み合わせ。例:

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

1

ルビー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}

オンラインテスト: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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.