แสดงอายุแหวนของต้นไม้


24

บทนำ

เมื่อวานนี้ผมเห็นปริศนาวันเกิด ยินดีด้วย!!

นอกจากนี้ในสัปดาห์นี้ฉันได้ดูตอนหนึ่งของรายการทีวีกระดูกที่ศพถูกฝังอยู่ใต้ต้นไม้ ในการคำนวณเวลาแห่งความตายพวกเขานับจำนวนต้นไม้

ต้นไม้ดังขึ้นเพราะต้นไม้เติบโตช้าในช่วงฤดูหนาวและเร็วกว่าในช่วงฤดูร้อน ดังนั้นคุณสามารถคำนวณอายุของต้นไม้โดยการนับวง นอกจากนี้คุณสามารถดูเหตุการณ์ธรรมชาติเช่นฤดูฝนหรือฤดูแล้ง

ป้อนคำอธิบายรูปภาพที่นี่

ท้าทาย

กำหนดจำนวนเต็มn >= 1เป็นอินพุตให้เขียนโปรแกรมเต็มรูปแบบเพื่อเอาท์พุทริงอายุของต้นไม้

เนื่องจากวงแหวนสามารถเปลี่ยนรูปร่างใช้อักขระสามตัวที่แตกต่างกัน ('0', '*', '+') เพื่อแสดงวัฏจักรของสภาพภูมิอากาศ

อายุ 1

0

อายุ 2

***
*0*
***

อายุ 3

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

อายุ 4

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

ขนาดของต้นไม้เป็นรูปสี่เหลี่ยมจัตุรัส 2*n - 1

การชนะ

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


เมื่ออายุ = 5 จะเกิดอะไรขึ้น
บลู

3
วงแหวนมีวงจรสามขั้นตอน ('0', '*', '+')ดังนั้น 5 ปีคือ*
Juan Carlos Oropeza

@ วิหารไม่เข้าใจคำถาม
Juan Carlos Oropeza

@ วิหารยังคงไม่เข้าใจว่าการหารสองแก้ปัญหาอย่างไร หากคุณมีแฮ็คที่จะแก้ปัญหาฉันอาจไม่รู้เกี่ยวกับมัน
Juan Carlos Oropeza

ขนาดของพื้นที่ปริมณฑลหรือความยาวของแต่ละด้านหรือไม่
สลายตัวเบต้า

คำตอบ:


6

K5, 27 30 26 25 22 ไบต์

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

วิธีนี้ซ้ำ ๆ "wraps" แกนกลาง (เริ่มต้นด้วย"0") ทั้งสี่ด้านโดยใช้อักขระอื่น ( {4(|+y,)/x}) ลำดับของการห่อตามฤดูกาลถูกกำหนดโดย3!ลำดับโมดูโล 3 ( ) เป็นบิตเที่ยวยุ่งยิ่งที่จะได้รับกรณีฐานในการเข้าแถวที่ถูกต้อง

แก้ไข:

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

ทางเลือกนี้จะสร้างอาร์เรย์สี่เหลี่ยมทั้งหมดในครั้งเดียวจากช่วงเอกสิทธิ์เฉพาะบุคคลที่มีให้ซึ่งมีการ!ย้อนกลับและเข้าร่วมกับตัวเองหลังจากวางรายการ ( t,1_|t:|) จากนั้นเราจะนำผลิตภัณฑ์คาร์ทีเซียนสูงสุด ( u|\:u:) นำเมทริกซ์โมดูโล 3 ทั้งหมด ( 3!) และดัชนีไปไว้ในอาร์เรย์ของอักขระ

ในการดำเนินการ:

  "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*"
 "*********")

ฉันไม่รู้ K แต่นี่เป็นโปรแกรมเต็มรูปแบบไม่ใช่แค่ฟังก์ชั่นใช่หรือไม่
Alex A.

มันเป็นทั้งโปรแกรมเต็มรูปแบบและฟังก์ชั่น มันเป็นตัวอย่างของสิ่งที่เรียกว่า "นิยามโดยนัย" ความแตกต่างเป็นอย่างมากโดยพลการอยู่แล้ว
JohnE

11

BBC Basic, 93 ไบต์

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.

คำหลักที่สั้นช่วยได้มากที่นี่ ในบรรทัดที่ 2 ฉันใช้VDUคำสั่ง (เทียบเท่าของ C putchar()) เพื่อพิมพ์อักขระแต่ละตัว P.MID$("0*+",p MOD3+1,1)นี้เป็นจำนวนมากที่มีประสิทธิภาพมากกว่า

ที่นี่มันทำงานใน BeebEm3 บน Mac:

ป้อนคำอธิบายรูปภาพที่นี่


คุณสร้าง gif นั้นได้อย่างไร?
Juan Carlos Oropeza

9
@JuanCarlosOropeza ไม่ค่อยมีประสิทธิภาพ ฉันใช้ QuickTime Player เพื่อจับภาพหน้าจอ QuickTime Player 7 เพื่อส่งออกวิดีโอไปยังภาพ PNG, GraphicConverter เพื่อเปลี่ยนเป็น GIF และezgif.comเพื่อให้ได้ผลลัพธ์ที่ดีที่สุด
ossifrage คลื่นไส้

7

CJam, 25 ไบต์

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

ทดสอบที่นี่

คำอธิบาย

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 ไบต์

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

ตัวอย่าง:

>> 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 ไบต์

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:]

พิมพ์ทีละบรรทัด แต่ละบรรทัดถูกสับเป็นสามส่วน:

  • ส่วนการขี่จักรยานทางซ้ายรวมถึงตัวแรกที่ทำซ้ำ
  • ส่วนศูนย์ซ้ำ
  • ส่วนการขี่จักรยานที่เหมาะสม

สำหรับn=4:

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

เราสร้างส่วนด้านซ้ายในสิ่งที่ตรงกันข้ามเป็นwโคลนครั้งสุดท้ายของตัวละคร2*iแล้วเพิ่มในรุ่นเดิมโดยไม่ต้องตัวแรก


5

Python 2, 83 ไบต์

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

ถ้าเราคิดว่าต้นไม้เป็นตารางพิกัดสัญลักษณ์ที่(i,j)จะถูกกำหนดโดยหรือเท่ากันmax(abs(i),abs(j))%3 max(i,-i,j,-j)%3สำหรับแต่ละแถวiเราเข้าร่วมและพิมพ์สัญลักษณ์ในแถวนั้น


คุณสามารถย่อให้สั้นลงได้โดยใส่คำสั่ง range ลงในบรรทัดที่สาม
Ethan Brouwer

@EthanBrouwer ฉันใช้Rสองครั้งและยาวกว่า 5 ตัวอักษรดังนั้นการมอบหมายจึงเป็นสิ่งที่ชนะ
xnor

Touche! ฉันเห็นแค่อันแรกเท่านั้น ความผิดฉันเอง. :)
Ethan Brouwer

5

Pyth, 23 ไบต์

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

ลองใช้งานออนไลน์: การสาธิต

คำอธิบาย:

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 ไบต์

ขอบคุณ Luis Mendo ที่ช่วยฉันโกน 5 ไบต์!

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

ตัวอย่าง

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

Ungolfed และคำอธิบายรหัส

%// 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)

หมายเหตุเล็กน้อย

bwdistเป็นฟังก์ชั่นที่เป็นส่วนหนึ่งของกล่องเครื่องมือประมวลผลภาพและสามารถเรียกใช้ใน MATLAB เท่านั้น Octave (IIRC) ยังไม่ได้bwdistใช้งานดังนั้นจึงไม่สามารถทำงานได้ใน Octave


คุณสามารถบันทึกไม่กี่ไบต์ใช้งาน: ใช้eyeและคูณองค์ประกอบที่ชาญฉลาดโดยตัวของมันrot90'รุ่นเอ็ดในการสร้าง 'เมล็ดพันธุ์' เมทริกซ์:I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
หลุยส์ Mendo

โอ้เยี่ยมมาก! ขอบคุณ @LuisMendo
rayryeng - Reinstate Monica


2

Perl, 118 ไบต์

สิ่งที่ต้องทำเพิ่มเติม แต่เป็นรุ่นพื้นฐานในตอนนี้ ขณะนี้มีการยึดมั่นพิเศษ spec อร่อย

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

การใช้งาน:

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

ไม่เกิน277 252 ตัวอักษร

(รหัสอักขระ 251 ตัวเลือกบรรทัดคำสั่ง 1 ตัวอักษร)

คาดว่าอินพุตในรูปแบบunary

: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//

วิ่งตัวอย่าง:

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

การใช้การแจ้งเตือนสำหรับเอาต์พุต - แบบอักษรที่มีสัดส่วนไม่ดีและผลลัพธ์นั้นน่าเกลียด ในตัวอย่างด้านล่างการแจ้งเตือนจะถูกเปลี่ยนเส้นทางไปยังเนื้อหาที่จัดไว้ให้ผลลัพธ์ที่ดีกว่า บรรทัดใหม่ภายใน backticks มีความสำคัญและนับ

ทดสอบการเรียกใช้ตัวอย่างข้อมูลใน 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>


ฉันลองเรียกใช้โค้ดขนาดเล็ก แต่ไม่มีอะไรเกิดขึ้น ไม่ทราบว่าเป็นเพราะฉันเปิดสแต็คล้นในโครเมี่ยมหรือไม่
Juan Carlos Oropeza

@JuanCarlosOropeza อาจเป็นไปได้ว่า ฉันได้เขียน: Test running the snippet in Firefoxแต่เห็นได้ชัดว่าฉันล้อเล่น Chrome (ไม่มีรุ่นของ Chrome) ไม่ใช่ EcmaScritpt 6 เป็นไปตาม=>ฟังก์ชั่นที่ขาดหายไป
edc65

@JuanCarlosOropeza ฉันต้องแก้ไขตัวเอง Chrome รุ่นใหม่ล่าสุดมีฟังก์ชั่นลูกศร แต่ไม่เข้าใจผู้ประกอบการสเปร...ด ยังห่างไกลจาก ES6
edc65

0

Ruby, 85 ตัวอักษร

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

วิ่งตัวอย่าง:

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

C, 138 ไบต์

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

ฟังก์ชั่นtรับพารามิเตอร์จำนวนเต็มหนึ่งตัว - อายุ

Ungolfed (พร้อมmainฟังก์ชั่นการวิ่งด้านบนอย่างง่ายดาย):

#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]));
}

stdlib.hอาจมีความจำเป็นในบางระบบเพราะไม่ได้ชนิดที่การกลับมาของฟังก์ชั่นที่ไม่ได้ประกาศจะเริ่มต้นกับcalloc intเพราะintและไม่จำเป็นต้องมีขนาดเดียวกันการชี้ไม่ถูกต้องอาจจะเขียนลงในchar* cในระบบ 32- บิตส่วนใหญ่ทั้งคู่char*และintมีขนาดเท่ากัน แต่นี่ไม่เป็นความจริงสำหรับระบบ 64- บิต

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.