Tăng quy mô ốp lát kim cương


27

Bất kỳ hình lục giác thông thường có thể được lát bằng kim cương, ví dụ như vậy:

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

Chúng tôi sẽ xem xét kích thước trên 1(vì các mặt của kim cương được làm bằng một /hoặc \mỗi cái). Các lát tương tự của kích thước 2sẽ trông giống như:

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

Nhiệm vụ của bạn là nhận được một lát gạch nghệ thuật ASCII như vậy (có kích thước 1) làm đầu vào, cùng với một số nguyên dương N(theo số thập phân hoặc đơn nguyên), chỉ định kích thước của đầu ra mong muốn. Sau đó, bạn nên xuất phiên bản thu nhỏ của cùng một lát.

Lưu ý rằng hình lục giác có thể có kích thước bất kỳ và nhỏ bằng 1x1x1 (chứa ba viên kim cương).

Cả đầu vào lẫn đầu ra đều không chứa bất kỳ khoảng trắng ở cuối, cũng không có nhiều khoảng trắng ở đầu cần thiết hơn để căn chỉnh hình lục giác. Cả đầu vào và đầu ra có thể tùy ý chứa một dòng mới duy nhất (lựa chọn này không nhất thiết phải giống nhau cho đầu vào và đầu ra).

Bạn có thể viết chương trình hoặc hàm, lấy đầu vào qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm và xuất kết quả qua tham số STDOUT (hoặc thay thế gần nhất), tham số trả về hàm hoặc tham số hàm (out).

Đây là mã golf, vì vậy câu trả lời ngắn nhất (tính bằng byte) trong chiến thắng.

Ví dụ nghiêng

Dưới đây là một số nghiêng đầu vào mà bạn có thể sử dụng để kiểm tra trình của mình.

 __
/_/\
\_\/

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

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

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

Đoạn mã sau chứa các đầu ra tương ứng cho các đầu vào N = 1thông qua N = 6.


20
Tôi thấy bạn quan tâm đến kim cương bây giờ khi bạn có một cái bên cạnh tên người dùng của bạn.
dùng12205

3
@ace: Bạn biết những gì họ nói: kim cương là người bạn tốt nhất của người điều hành.
Alex A.

Tôi nghĩ rằng tôi biết câu trả lời, nhưng tôi hy vọng tôi đã sai: Dẫn các dòng trống sẽ được tính là không gian hàng đầu, mà bạn tuyên bố là bất hợp pháp? Giải pháp ban đầu của tôi có N-1hàng trống hàng đầu. :(
Reto Koradi

@RetoKoradi Thật vậy, không có dòng mới nào. Lấy làm tiếc.
Martin Ender

1
Tôi hình dung. Chi phí cho tôi khoảng 10 byte. Không tệ như nó nhìn khi tôi lần đầu tiên nhận ra vấn đề.
Reto Koradi

Câu trả lời:


8

CJam, 85 79 76 72 byte

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

Kích thước nên ở dòng đầu tiên. Và kim cương theo sau.

Không chơi gôn giỏi ... Và một nửa số nhân vật đến từ các chi tiết.

Giải thích (của phiên bản trước)

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

Con trăn 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

Đầu ra trên các trường hợp thử nghiệm.

Vì vậy, những gì đang xảy ra ở đây?

Ý tưởng chính là mỗi nhân vật trong bản gốc sẽ thổi thành một n*nkhối. Ví dụ: với n = 4, /có thể trở thành

   /
  /
 /
/___

Ký tự gốc xuất hiện một lần trong mỗi dòng và có phần đệm ở hai bên. Ở đây, nó ở bên trái, và _bên phải. Chỉ có hàng dưới cùng có thể được đệm bởi '_'; Phần còn lại là luôn ' '.

Khó khăn chính là phần đệm bên phải có thể phụ thuộc vào biểu tượng sắp tới. Cụ thể, '/ 'có phần đệm khác nhau '/_', vì vậy chúng tôi cần một chút hướng về phía trước. Hơn nữa, để tránh các dấu cách, chúng ta phải lưu ý rằng chúng ta đang ở biểu tượng cuối cùng và không được đệm ở bên phải.

Chúng tôi khắc phục cả hai vấn đề này bằng cách chỉ đệm ở bên trái của nhân vật hiện tại. Khi chúng tôi làm như vậy, chúng tôi cũng thực hiện phần đệm bên phải từ ký tự trước bằng biểu tượng đệm hiện tại. Vì vậy, chúng tôi in phần đệm bên phải còn nợ từ char trước, phần đệm bên trái từ char hiện tại, sau đó là char hiện tại. Chúng tôi cũng lưu trữ số tiền đệm "nợ" mà char tiếp theo sẽ cần phải trả.

Bây giờ chúng ta hãy đi qua mã.

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

Chuỗi đầu vào là svà hệ số tỷ lệ là n. Chúng tôi đi từng dòng, in ncác dòng cho từng dòng đầu vào W, với các bản sao được lập chỉ mục j=n,n-1,...,2,1. Dòng đầu tiên chỉ được sao chép một lần, chúng tôi đạt được điều này bằng cách khởi tạo jthành 1 nhưng thay đổi nó thành ntừng vòng lặp.

Chúng tôi lặp qua dòng đầu vào, tích lũy dòng để in O. Đầu tiên, chúng tôi tìm ra ký tự đệm phù hợp q, đó là dấu gạch dưới nếu chúng ta ở dòng dưới cùng và ký tự hiện tại hoặc trước đó là dấu gạch dưới, và nếu không thì là khoảng trắng.

Sau đó, chúng tôi quyết định số lượng phần đệm để đặt bên trái ( e). Đối với /, nó j-1(giảm khi giảm số lượng bản sao dòng) và phần bổ sung n-jcho \. Chúng tôi đối xử với các nhân vật khác theo cùng một cách. Ví dụ, mặc dù _có vẻ như nó cung cấp một hàng ngạch dưới, nhưng nó thực sự cho một dấu gạch dưới duy nhất, được đệm bởi các dấu gạch dưới ở bên trái và bên phải. Điều này có vẻ không hiệu quả, nhưng nó cho phép chúng tôi làm việc với _trong cùng một khuôn khổ /\Vị trí của dấu gạch dưới "trung tâm" không quan trọng, vì vậy chúng tôi gộp lại và với \; sự lựa chọn này cũng làm cho hàng trên cùng hoạt động mà không có vỏ đặc biệt.

Tiếp theo, chúng tôi thêm vào chuỗi đầu ra. Chúng tôi đã tìm ra biểu tượng đệm qvà số lượng đệm hiện tại e, nhưng chúng tôi cũng cần nhớ khoản nợ đệm dtừ biểu tượng trước đó. Vì vậy, chúng tôi thêm q*(e+d). Sau đó, chúng tôi thêm biểu tượng hiện tại c, ngoại trừ chúng tôi cần tránh dấu gạch dưới ở hàng không dưới cùng, chúng tôi sửa bằng cách chuyển đổi dấu gạch dưới thành biểu tượng đệm.

Cuối cùng, chúng tôi ghi lại số tiền nợ đệm, bổ sung cho n+~dsố tiền đệm trái hiện tại. Chúng tôi cũng ghi lại biểu tượng hiện tại pđể sau này chúng tôi sẽ biết liệu biểu tượng trước đó là gì _.


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

Con trăn 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 byte nhờ Sp3000.

Gọi mvới đối số thứ nhất là chuỗi kim cương dưới dạng chuỗi và đối số thứ hai là số lặp lại.

Điều này dựa trên chuỗi thay thế chuỗi 3 bước:

  • Đầu tiên, thay thế dấu gạch dưới bằng dấu cách 2n-1 hoặc dấu gạch dưới, tùy thuộc vào dòng.
  • Thứ hai, thay thế /\bằng / \, với số lượng khoảng trắng xen kẽ từ 2 đến 2 * (n-1) trên các dòng.
  • Thứ ba, thay thế \/bằng \ /, với số lượng khoảng trắng xen kẽ đi từ 2 * (n-1) đến 2 trên các dòng.

Sau đó, có một loạt các mucking sắp có được không gian hàng đầu đúng, và để có được dòng đầu tiên đúng.

Lưu ý rằng dòng cuối cùng của chương trình phải là một tab, không phải là 4 khoảng trắng. Markdown không hỗ trợ các tab.


Hai golf: (i+(n-i+~i)*(d[-1]>f)) --> [i,n+~i][d[-1]>f]và bạn chỉ sử dụng '_'một lần, vì vậy bạn lãng phí một byte xác định nó.
Sp3000

3

Python, 272 238 228 243 byte

Phiên bản cập nhật, bây giờ lấy một chuỗi đơn làm đầu vào, thay vì chuỗi chuỗi. Cũng loại bỏ khoảng trắng theo sau đã có trong phiên bản trước. Thật không may những thay đổi này làm tăng kích thước.

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

Phiên bản có khoảng trắng và các câu lệnh được chia thành các đơn vị nhỏ hơn để dễ đọc:

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

Cách tiếp cận cơ bản ở đây là:

  1. Lặp lại tất cả các dòng trong đầu vào.
  2. Đối với mỗi dòng, lặp qua kích thước đầu ra N, tạo ra một dòng đầu ra trong mỗi lần lặp lặp. Có một trường hợp đặc biệt cho dòng đầu tiên, trong đó chỉ có dòng đầu ra cuối cùng được tạo ra, để tránh tạo ra các dòng trống khi bắt đầu đầu ra.
  3. Thay thế mỗi ký tự trong dòng bằng Nký tự, trong đó:
    • Mỗi không gian được thay thế bằng Nkhông gian.
    • Mỗi dấu gạch dưới được thay thế bằng Nkhoảng trắng cho lần N -1lặp vòng lặp đầu tiên và Ndấu gạch dưới cho lần lặp vòng lặp cuối cùng.
    • Dấu gạch chéo và dấu gạch chéo ngược được đệm bằng N - 1khoảng trắng hoặc dấu gạch dưới.

Phần khó nhất ở đây là phần đệm cho dấu gạch chéo / dấu gạch chéo ngược sử dụng khoảng trắng hoặc dấu gạch dưới tùy thuộc vào ký tự đầu vào tiếp theo (đối với dấu gạch chéo) hoặc trước đó (đối với dấu gạch chéo ngược). Điều đó dường như không phù hợp với chiến lược thay thế chuỗi.

Điều tôi đã làm để giải quyết điều này là trước tiên tôi thay thế một số kết hợp hai ký tự bằng các ký tự khác nhau, để tôi có thể đối xử với chúng khác nhau trong quá trình thay thế thực tế. Ví dụ, /_được thay thế bởi (_. Sau này, thực sự (là một "dấu gạch chéo theo dấu gạch dưới", sau đó có thể được thay thế cho phù hợp.

Chương trình chính được sử dụng để kiểm tra chức năng:

import sys
import Golf

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

Golf.d(t, n)

1
n-1-kn+~k
đệ quy

Trong mối quan tâm của việc tiết lộ đầy đủ: Tôi chỉ thấy rằng giải pháp của tôi tạo ra một số khoảng trống. Vì điều đó không được phép trong định nghĩa đầu ra, nó không đáp ứng các yêu cầu. Trong trường hợp xấu nhất, tôi sẽ phải thêm .rstrip()9 ký tự nữa. Tôi hy vọng tôi có thể làm tốt hơn, và cũng tìm ra cách cắt bỏ 5 ký tự.
Reto Koradi

Có vẻ như định dạng đầu vào của bạn không được phép. sys.stdinkhông phải là một tham số đầu vào được phép - bạn cần phải tự thao tác chuỗi.
isaacg

Vâng, bạn có thể sử dụng sys.stdinint(sys.argv[1])nhưng bạn sẽ không nhận được chúng miễn phí bằng cách hy vọng chúng được chuyển qua dưới dạng các biến (nếu đó là trò chơi công bằng, thì bạn cũng có thể mong đợi các bí danh rangevà thay thế `và bất cứ điều gì khác mà bạn cần phải xác định trước) .
Martin Ender

@ MartinBüttner Nó nói rằng tôi có thể lấy đầu vào làm đối số hàm. Đây không phải là những gì tôi đang làm ở đây sao? Tôi sẽ thay đổi đối số hàm thành một danh sách các chuỗi. Đó sẽ là tốt? Nó không khác nhau lắm, vì cả hai stdinvà một danh sách các chuỗi là các chuỗi chuỗi.
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}

Kết hợp đầu vào STDIN và ARGV. Thí dụ:

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

Kiểm tra trực tuyến: http://ideone.com/e6XakQ

Đây là mã trước khi chơi golf:

-> 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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.