Hiển thị vòng cây tuổi


24

Giới thiệu

Hôm qua tôi thấy một câu đố sinh nhật . Chúc mừng!!

Cũng trong tuần này tôi đã xem một tập của chương trình truyền hình Bones nơi tìm thấy xác chết được chôn dưới gốc cây. Để tính thời gian chết, họ đếm các vòng cây.

Vòng cây hình thành vì cây phát triển chậm hơn trong mùa đông và nhanh hơn trong mùa hè. Do đó, bạn có thể tính tuổi của cây bằng cách đếm các vòng. Ngoài ra, bạn có thể thấy các sự kiện tự nhiên như mùa mưa hoặc mùa khô.

nhập mô tả hình ảnh ở đây

Thử thách

Cho một số nguyên n >= 1làm đầu vào, viết một chương trình đầy đủ để xuất các vòng tuổi cây.

Vì các vòng có thể thay đổi hình dạng, sử dụng ba ký tự khác nhau ('0', '*', '+') để hiển thị chu kỳ khí hậu.

1 tuổi

0

2 tuổi

***
*0*
***

3 tuổi

+++++
+***+
+*0*+
+***+
+++++

4 tuổi

0000000
0+++++0
0+***+0
0+*0*+0
0+***+0
0+++++0
0000000

Kích thước của cây là một hình vuông của các cạnh 2*n - 1

Chiến thắng

Mã ngắn nhất trong byte thắng.


Còn khi tuổi = 5 thì sao?
Màu xanh

3
các vòng có một chu kỳ ba bước. ('0', '*', '+')vậy 5 năm là*
Juan Carlos Oropeza

@vihan không hiểu câu hỏi.
Juan Carlos Oropeza

@vihan xin lỗi vẫn không hiểu cách chia hai giải quyết vấn đề. Nếu bạn có một bản hack để giải quyết nó, có lẽ tôi không biết về nó
Juan Carlos Oropeza

Là kích thước diện tích, chu vi hoặc chiều dài của mỗi bên?
Beta Decay

Câu trả lời:


6

K5, 27 30 26 25 22 byte

"0"{4(|+y,)/x}/"0*+"3!1_!

Cách tiếp cận này lặp đi lặp lại "kết thúc" một lõi (bắt đầu bằng "0") ở cả bốn phía bằng cách sử dụng một số ký tự khác ( {4(|+y,)/x}). Trình tự bao bọc theo mùa được xác định bởi 3!trình tự modulo 3 ( ). Đó là một chút khó khăn để có được trường hợp cơ bản để xếp hàng vừa phải.

chỉnh sửa:

"0*+"3!u|\:u:t,1_|t:|!

Sự thay thế này xây dựng toàn bộ mảng hình chữ nhật cùng một lúc từ phạm vi độc quyền được cung cấp ( !) đảo ngược và nối với chính nó sau khi thả một vật phẩm ( t,1_|t:|). Sau đó, chúng tôi lấy sản phẩm cartesian tối đa ( u|\:u:), lấy toàn bộ ma trận modulo 3 ( 3!) và lập chỉ mục vào mảng các ký tự.

Trong hành động:

  "0*+"3!u|\:u:t,1_|t:|!1
,,"0"

  "0*+"3!u|\:u:t,1_|t:|!3
("+++++"
 "+***+"
 "+*0*+"
 "+***+"
 "+++++")

  "0*+"3!u|\:u:t,1_|t:|!5
("*********"
 "*0000000*"
 "*0+++++0*"
 "*0+***+0*"
 "*0+*0*+0*"
 "*0+***+0*"
 "*0+++++0*"
 "*0000000*"
 "*********")

Tôi không biết K, nhưng đây có phải là một chương trình đầy đủ và không chỉ là một chức năng?
Alex A.

Nó là cả một chương trình đầy đủ và một chức năng. Đó là một ví dụ về cái được gọi là "định nghĩa ngầm". Sự phân biệt là vô cùng tùy tiện.
JohnE

11

BBC cơ bản, 93 byte

1I.r:r=r-1:F.i=-r TOr:F.j=-r TOr:p=ABS(i):q=ABS(j):IFp<q TH.p=q
2V.48-(p MOD3)*6MOD7:N.:P.:N.

Các từ khóa viết tắt giúp rất nhiều ở đây. Trong dòng 2, tôi đang sử dụng VDUlệnh (tương đương với C putchar()) để in từng ký tự. Điều này là hiệu quả hơn nhiều P.MID$("0*+",p MOD3+1,1).

Ở đây, nó đang chạy trong BeebEm3 trên máy Mac:

nhập mô tả hình ảnh ở đây


Làm thế nào bạn tạo gif đó?
Juan Carlos Oropeza

9
@JuanCarlosOropeza Không hiệu quả lắm. Tôi đã sử dụng QuickTime Player để chụp màn hình, QuickTime Player 7 để xuất video thành hình ảnh PNG, GraphicConverter để biến chúng thành GIF và ezgif.com để tối ưu hóa kết quả.
squossish ossifrage

7

CJam, 25 byte

q~,_1>W%\+_ff{e>"0*+"=}N*

Kiểm tra nó ở đây.

Giải trình

q~,       e# Read input N, turn into range [0 1 ... N-1]
_1>       e# Duplicate and cut off the zero.
W%        e# Reverse.
\+        e# Prepend to original range to give [N-1 ... 1 0 1 ... N-1]
_         e# Duplicate
ff{       e# Nested map for each pair of elements in that array.
  e>      e# Take the maximum, i.e. chessboard distance from the centre.
  "0*+"=  e# Select the right character using cyclic indexing into this string.
}
N*        e# Join the lines with line feeds.

5

Matlab, 63 byte

n=input('')-1;x='0*+';t=abs(-n:n);x(mod(bsxfun(@max,t,t'),3)+1)

Thí dụ:

>> n=input('')-1;x='0*+';t=abs(-n:n);x(mod(bsxfun(@max,t,t'),3)+1)
5
ans =
*********
*0000000*
*0+++++0*
*0+***+0*
*0+*0*+0*
*0+***+0*
*0+++++0*
*0000000*
*********

5

Python 2, 83 byte

I=n=input()
while I+n-1:I-=1;i=abs(I);w=("O*+"*n)[i:n];print w[::-1]+w[0]*2*i+w[1:]

In từng dòng. Mỗi dòng được cắt thành ba phần:

  • Phần đi xe đạp bên trái, bao gồm char đầu tiên lặp lại.
  • Phần trung tâm lặp lại
  • Phần đi xe đạp đúng.

Dành cho n=4:

0    000000    
0+    ++++    0
0+*    **    +0
0+*0        *+0
0+*    **    +0
0+    ++++    0
0    000000    

Chúng tôi tạo phần bên trái ngược lại w, sao chép lần ký tự cuối cùng của nó 2*i, sau đó thêm vào phiên bản gốc mà không có ký tự đầu tiên.


5

Python 2, 83 byte

n=input()
R=range(1-n,n)
for i in R:print''.join('0*+'[max(i,-i,j,-j)%3]for j in R)

Nếu chúng ta nghĩ về cây như một lưới tọa độ, ký hiệu tại (i,j)được xác định bởi max(abs(i),abs(j))%3, hoặc tương đương max(i,-i,j,-j)%3. Đối với mỗi hàng i, chúng tôi tham gia và in các biểu tượng trong hàng đó.


Bạn có thể rút ngắn điều này bằng cách đặt câu lệnh phạm vi thẳng vào dòng thứ ba.
Ethan Brouwer

@EthanBrouwer Tôi đang sử dụng Rhai lần và nó dài hơn 5 ký tự, vì vậy bài tập sẽ thắng.
xnor

chạm vào! Tôi chỉ thấy cái đầu tiên. Lỗi của tôi. :)
Ethan Brouwer

5

Bình thường, 23 byte

VK+_StQUQsm@"0*+"eS,dNK

Dùng thử trực tuyến: Trình diễn

Giải trình:

VK+_StQUQsm@"0*+"eS,dNK   implicit: Q = input number
    StQ                   the list [1, 2, ..., Q-1]
   _                      reverse it [Q-1, ..., 2, 1]
       UQ                 the list [0, 1, ..., Q-1]
  +                       combine them [Q-1, ..., 1, 0, 1, ..., Q-1]
 K                        and store in K
VK                        for each N in K:
          m           K      map each element d in K to:
                 eS,dN          the maximum of d and N
           @"0*+"               and pick the corresponded char (modulo 3)
         s                   join the chars to a string and print

3

MATLAB, 80 78 73 byte

Cảm ơn Luis Mendo đã giúp tôi cạo 5 byte!

A=eye(2*input('')-1);a='0*+';a(mod(bwdist(A.*rot90(A),'chessboard'),3)+1)

Thí dụ

>> A=eye(2*input('')-1);a='0*+';a(mod(bwdist(A.*rot90(A),'chessboard'),3)+1)

5

ans =

*********
*0000000*
*0+++++0*
*0+***+0*
*0+*0*+0*
*0+***+0*
*0+++++0*
*0000000*
*********

Giải thích mã và mã

%// Accepts an integer n from the user and creates a 2*n - 1 x 2*n - 1 identity matrix
A=eye(2*input('')-1);

%// Creates an array of three characters to print each level of the ring
a='0*+';

%// By taking the identity matrix and element-wise multiplying with its 90 degree rotated 
%// version of itself, this creates a zero matrix except for the centre most
%// value, which is 1
%// This takes the distance transform via the chessboard / Chebyshev distance
%// from the centre element
%// This mirrors what "level" each square would be at
%// 1: https://en.wikipedia.org/wiki/Distance_transform
%// 2: https://en.wikipedia.org/wiki/Chebyshev_distance
b = bwdist(A.*rot90(A),'chessboard');

%// Because each level cycles through each of the characters in the
%// character array a, we need to perform a mod operation so that
%// all of the values cycle from 1 to 3
%// This changes the distance transform output so that we range
%// from 1 to 3 instead
c = mod(b,3) + 1;

%// The values in the matrix c correspond exactly to the locations
%// we need to sample from the array a and we display our result
a(c)

Lưu ý nhỏ

bwdistlà một chức năng là một phần của hộp công cụ xử lý ảnh và chỉ có thể chạy trong MATLAB. Octave (IIRC) chưa được bwdisttriển khai nên điều này không thể chạy trong Octave.


Bạn có thể lưu một vài byte: sử dụng eyevà nhân phần tử khôn ngoan theo rot90phiên bản ed của nó để tạo ma trận "hạt giống":I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Luis Mendo

Ồ tuyệt! Cảm ơn @LuisMendo
rayryeng - Phục hồi Monica

2

Python 2, 134 byte

def l(x,c=1):
 p="\n\x1b[%d"%c;d=p+";%dH"%c
 if x:s=x*2-1;d+=(p+"G").join(["0*+"[(x+1)%3]*s]*s)+l(x-1,c+1)
 return d
print l(input())

2

Perl, 118 byte

Nhiều việc phải làm, nhưng một phiên bản cơ bản bây giờ. Bây giờ với tuân thủ thêm spec ngon.

for$i(0..($-=<>-1)){substr$a[$_],$i,$}=2*($--$i)+1,(0,'*','+')[($--$i)%3]x$}for$i..$-}$,=$/;print@a,reverse@a[0..$--1]

Sử dụng:

perl -e 'for$i(0..($-=<>-1)){substr$a[$_],$i,$}=2*($--$i)+1,(0,'*','+')[($--$i)%3]x$}for$i..$-}$,=$/;print@a,reverse@a[0..$--1]' <<< 9
+++++++++++++++++
+***************+
+*0000000000000*+
+*0+++++++++++0*+
+*0+*********+0*+
+*0+*0000000*+0*+
+*0+*0+++++0*+0*+
+*0+*0+***+0*+0*+
+*0+*0+*0*+0*+0*+
+*0+*0+***+0*+0*+
+*0+*0+++++0*+0*+
+*0+*0000000*+0*+
+*0+*********+0*+
+*0+++++++++++0*+
+*0000000000000*+
+***************+
+++++++++++++++++

1

Matlab 92

input('')-1;x=ones(2*n+1,1)*abs(-n:n);z=mod(max(x,x'),3);z(z>1)=2;z(z<1)=7;disp([z+41,''])

1

Sed, 277 252 ký tự

(Tùy chọn dòng lệnh 251 ký tự + 1 ký tự.)

Mong đợi đầu vào ở định dạng đơn .

:m
s/1/0/
s/1/*/
s/1/+/
tm
h
s/^/:/
:r
s/(.*):(.)/\2\1:/
tr
s/://
G
s/\n.//
h
:
/^(.)\1*$/ba
s/(.)(.)(\2*)\1/\1:\2\3:\1/
:c
s/(:_*)[^_](.*:)/\1_\2/
tc
:u
s/(.)(:\1*)_/\1\2\1/
tu
s/://g
H
b
:a
g
s/[^\n]+/:/
:f
s/(.*):(\n[^\n]+)/\2\1:/
tf
s/://
G
s/\n//

Chạy mẫu:

bash-4.3$ sed -rf treering.sed <<< 1
0

bash-4.3$ sed -rf treering.sed <<< 11
***
*0*
***

bash-4.3$ sed -rf treering.sed <<< 111
+++++
+***+
+*0*+
+***+
+++++

bash-4.3$ sed -rf treering.sed <<< 1111
0000000
0+++++0
0+***+0
0+*0*+0
0+***+0
0+++++0
0000000

0

JavaScript (ES6), 114

Sử dụng cảnh báo cho đầu ra - phông chữ tỷ lệ xấu và kết quả là xấu. Trong đoạn trích bên dưới cảnh báo là chuyển hướng đến cơ thể bị cắt, cho kết quả tốt hơn. Dòng mới bên trong backticks là đáng kể và được tính.

Kiểm tra chạy đoạn mã trong Firefox.

/* Redefine alert for testing purpose */ alert=x=>O.innerHTML=x;

[...'*+0'.repeat(n=prompt()-1)].map((c,i)=>i<n?b=[z=c.repeat(i-~i),...b,z].map(r=>c+r+c):0,b=[0]);alert(b.join`
`)
<pre id=O></pre>


Tôi thử chạy đoạn mã, nhưng không có gì xảy ra. Không biết đó có phải là do tôi mở ngăn xếp tràn trong chrome không?
Juan Carlos Oropeza

@JuanCarlosOropeza có lẽ vậy. Tôi đã viết: Test running the snippet in Firefoxnhưng rõ ràng tôi chỉ đùa thôi, Chrome (không có phiên bản Chrome) không tuân thủ EcmaScritpt 6, thiếu các =>chức năng.
edc65

@JuanCarlosOropeza Tôi phải tự sửa. Bản phát hành mới nhất của Chrome có chức năng mũi tên, nhưng không hiểu toán tử lây lan .... Vẫn còn xa ES6
edc65

0

Ruby, 85 ký tự

puts (m=0..(n=gets.to_i-1)*2).map{|i|m.map{|j|"0*+"[[(i-n).abs,(j-n).abs].max%3]}*""}

Chạy mẫu:

bash-4.3$ ruby -e 'puts (m=0..(n=gets.to_i-1)*2).map{|i|m.map{|j|"0*+"[[(i-n).abs,(j-n).abs].max%3]}*""}' <<< 4
0000000
0+++++0
0+***+0
0+*0*+0
0+***+0
0+++++0
0000000

0

Moonscript - 104 byte

m=io.read!
n=2*m-1
for y=1,n
 io.write ({'0','*','+'})[(math.max y-m,x-m,m-y,m-x)%3+1]for x=1,n
 print!

0

C, 138 byte

j,k,l;t(i){l=2*i;char*c=calloc(l,l);memset(c,10,l*(l-2));for(;k<i;++k)for(j=k;j<l-1-k;)memset(c+j++*l+k,"+0*"[(i-k)%3],l-2*k-1);puts(c);}

Chức năng t lấy một tham số nguyên - tuổi.

Ungolfed (có mainchức năng dễ dàng chạy cái trên):

#include "stdlib.h" /* calloc - only necessary for 64-bit system */
j,k,l;t(i)
{
    l=2*i;
    char*c=calloc(l,l);
    memset(c,10,l*(l-2)); /* fill with '\n' */
    for(;k<i;++k)for(j=k;j<l-1-k;)memset(c+j++*l+k,"+0*"[(i-k)%3],l-2*k-1);
    puts(c);
}

main(int c,char**v)
{
    t(atoi(v[1]));
}

Điều stdlib.hnày có thể cần thiết trên một số hệ thống, bởi vì nếu không có nó, kiểu trả về của hàm không được khai báo callocsẽ mặc định int. Bởi vì intchar*không nhất thiết phải có cùng kích thước, một con trỏ không hợp lệ có thể được ghi vào c. Trong hầu hết các hệ thống 32-bit cả char*intcó cùng kích thước, nhưng điều này là không đúng đối với các hệ thống 64-bit.

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.