Pokaż wiek słojów drzew

24

Wprowadzenie

Wczoraj widziałem urodzinową układankę . Gratulacje!!

Również w tym tygodniu oglądałem odcinek programu telewizyjnego Bones, w którym znaleziono zwłoki zakopane pod drzewem. Aby obliczyć czas śmierci, policzyli słoje drzew.

Pierścienie drzew powstają, ponieważ drzewa rosną wolniej zimą i szybciej latem. W ten sposób możesz obliczyć wiek drzewa, licząc pierścienie. Możesz także zobaczyć naturalne wydarzenia, takie jak pora deszczowa lub sucha.

wprowadź opis zdjęcia tutaj

Wyzwanie

Biorąc pod uwagę liczbę całkowitą n >= 1jako dane wejściowe, napisz pełny program do generowania pierścieni wieku drzewa.

Ponieważ pierścienie mogą zmieniać kształt, użyj trzech różnych znaków („0”, „*”, „+”), aby pokazać cykle klimatyczne.

Wiek 1

0

Wiek 2

***
*0*
***

Wiek 3

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

Wiek 4

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

Wielkość drzewa to kwadrat boków 2*n - 1

Zwycięski

Najkrótszy kod w bajtach wygrywa.

Juan Carlos Oropeza
źródło
A co, gdy wiek = 5 lat?
Niebieski,
3
pierścienie mają trzyetapowy cykl. ('0', '*', '+')więc 5 lat to*
Juan Carlos Oropeza
@vihan nie rozumiem pytania.
Juan Carlos Oropeza,
@vihan przepraszam, nadal nie rozumiem, jak podzielić przez dwa rozwiązać problem. Jeśli masz hack, aby go rozwiązać, prawdopodobnie nie wiem o tym
Juan Carlos Oropeza
Czy rozmiar to obszar, obwód czy długość każdej strony?
Beta Decay

Odpowiedzi:

6

K5, 27 30 26 25 22 bajtów

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

Takie podejście iteracyjnie „otacza” rdzeń (zaczynając od "0") ze wszystkich czterech stron za pomocą innej postaci ( {4(|+y,)/x}). Sekwencja zawijania sezonowego jest określona przez 3!sekwencję modulo 3 ( ). To trochę kłopotliwe, aby ustawić skrzynkę podstawową w sam raz.

edytować:

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

Ta alternatywa buduje cały prostokątny układ jednocześnie z podanego wyłącznego zakresu ( !) odwróconego i połączonego ze sobą po upuszczeniu elementu ( t,1_|t:|). Następnie bierzemy iloczyn kartezjański maksimum ( u|\:u:), bierzemy całą macierz modulo 3 ( 3!) i indeksujemy do tablicy znaków.

W akcji:

  "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*"
 "*********")
JohnE
źródło
Nie znam K, ale czy to pełny program, a nie tylko funkcja?
Alex A.
Jest to zarówno pełny program, jak i funkcja. Jest to przykład tak zwanej „milczącej definicji”. To i tak rozróżnienie jest niezwykle arbitralne.
JohnE
11

BBC Basic, 93 bajty

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.

Skrócone słowa kluczowe bardzo tu pomagają. W wierszu 2 używam VDUpolecenia (odpowiednika liter C putchar()), aby wydrukować każdy znak. Jest to o wiele bardziej wydajne niż P.MID$("0*+",p MOD3+1,1).

Tutaj działa w BeebEm3 na Macu:

wprowadź opis zdjęcia tutaj

piskliwy kostuch
źródło
Jak tworzysz ten gif?
Juan Carlos Oropeza,
9
@JuanCarlosOropeza Niezbyt wydajnie. Użyłem QuickTime Player do przechwycenia ekranu, QuickTime Player 7, aby wyeksportować wideo do obrazów PNG, GraphicConverter, aby zamienić je w GIF, i ezgif.com, aby zoptymalizować wyniki.
squeamish ossifrage
7

CJam, 25 bajtów

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

Sprawdź to tutaj.

Wyjaśnienie

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.
Martin Ender
źródło
5

Matlab, 63 bajty

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

Przykład:

>> 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*
*********
Luis Mendo
źródło
5

Python 2, 83 bajty

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

Drukuje linia po linii. Każda linia jest podzielona na trzy części:

  • Lewa część rowerowa, w tym pierwszy powtórzony char.
  • Powtarzająca się część środkowa
  • Właściwa część rowerowa.

Dla n=4:

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

Generujemy lewą część w odwrotnej kolejności w, klonujemy 2*iczasy ostatniego znaku , a następnie dodajemy oryginalną wersję bez pierwszego znaku.

xnor
źródło
5

Python 2, 83 bajty

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

Jeśli myślimy o drzewie jako o siatce współrzędnych, symbol w (i,j)jest określany przez max(abs(i),abs(j))%3lub równorzędnie max(i,-i,j,-j)%3. Dla każdego rzędu iłączymy i drukujemy symbole w tym rzędzie.

xnor
źródło
Można to skrócić, umieszczając instrukcję range prosto w trzeciej linii.
Ethan Brouwer,
@EthanBrouwer Używam Rdwa razy i jest dłuższy niż 5 znaków, więc przypisanie wygrywa.
xnor
dotknąć! Widziałem tylko pierwszy. Mój błąd. :)
Ethan Brouwer,
5

Pyth, 23 bajty

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

Wypróbuj online: demonstracja

Wyjaśnienie:

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
Jakube
źródło
3

MATLAB, 80 78 73 bajtów

Dzięki Luis Mendo za pomoc w goleniu 5 bajtów!

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

Przykład

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

Wykluczenie i objaśnienie kodu

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

Drobne uwagi

bwdistto funkcja, która jest częścią przybornika przetwarzania obrazu i może być uruchomiona tylko w MATLAB. Octave (IIRC) nie został bwdistjeszcze zaimplementowany, więc nie można go uruchomić w Octave.

rayryeng - Przywróć Monikę
źródło
Możesz zapisać kilka bajtów: użyj eyei pomnóż element przez jego rot90edowaną wersję, aby wygenerować macierz „seed”:I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Luis Mendo
Fajnie! Dzięki @LuisMendo
rayryeng - Przywróć Monikę
2

Python 2, 134 bajty

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())
niebieski
źródło
2

Perl, 118 bajtów

Więcej do zrobienia, ale na razie podstawowa wersja. Teraz z zachowaniem doskonałej przyczepności do specyfikacji

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

Stosowanie:

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*+
+***************+
+++++++++++++++++
Dom Hastings
źródło
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,''])
wada
źródło
1

Sed, 277 252 znaków

(251 znaków kodowych + opcja 1 wiersza poleceń).

Oczekuje danych wejściowych w formacie jednoargumentowym .

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

Przykładowy przebieg:

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
człowiek w pracy
źródło
0

JavaScript (ES6), 114

Użycie alertu do wydruku - zła czcionka proporcjonalna i wynik jest brzydki. W poniższym fragmencie alert jest przekierowywany do wyciętego ciała, co daje lepszy wynik. Nowa linia w backticks jest znacząca i liczona.

Przetestuj uruchomienie fragmentu w przeglądarce 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>

edc65
źródło
Próbuję uruchomić fragment kodu, ale nic się nie dzieje. Nie wiesz, czy to dlatego, że otwieram przepełnienie stosu w chrome?
Juan Carlos Oropeza,
@JuanCarlosOropeza może to. Napisałem: Test running the snippet in Firefoxale oczywiście żartowałem, Chrome (brak wersji Chrome) nie jest zgodny z EcmaScritpt 6, brakuje =>funkcji.
edc65,
@JuanCarlosOropeza Muszę się poprawić. Najnowsza wersja Chrome ma funkcję strzałki, ale nie rozumie operatora rozprzestrzeniania .... Nadal daleko od ES6
edc65,
0

Ruby, 85 znaków

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

Przykładowy przebieg:

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
człowiek w pracy
źródło
0

Moonscript - 104 bajty

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!
Ryan Russell
źródło
0

C, 138 bajtów

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

Funkcja tprzyjmująca jeden parametr liczby całkowitej - wiek.

Niegolfowany (z mainfunkcją łatwego uruchomienia powyższego):

#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.hMogą być konieczne w niektórych systemach, ponieważ bez tego rodzaju powrót funkcji nierejestrowanej callocbędzie domyślnie int. Ponieważ inti char*niekoniecznie mają taki sam rozmiar, można zapisać nieprawidłowy wskaźnik c. W większości systemów 32-bitowych zarówno char*iint mieć taką samą wielkość, ale nie jest to prawdą dla systemów 64-bitowych.

pawel.boczarski
źródło