Mostra l'età degli anelli degli alberi


24

introduzione

Ieri ho visto un puzzle di compleanno . Congratulazioni!!

Anche questa settimana ho visto un episodio dello show televisivo Bones in cui è stato trovato un cadavere sepolto sotto un albero. Per calcolare l'ora della morte, hanno contato gli anelli degli alberi.

Gli anelli degli alberi si formano perché gli alberi crescono più lentamente durante l'inverno e più velocemente durante l'estate. Quindi puoi calcolare l'età dell'albero contando gli anelli. Inoltre puoi vedere eventi naturali come le stagioni piovose o secche.

inserisci qui la descrizione dell'immagine

Sfida

Dato un numero intero n >= 1come input, scrivere un programma completo per produrre gli anelli dell'età degli alberi.

Poiché gli anelli possono cambiare forma, utilizzare tre diversi caratteri ('0', '*', '+') per mostrare i cicli climatici.

Età 1

0

Età 2

***
*0*
***

Età 3

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

Età 4

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

La dimensione dell'albero è un quadrato di lati 2*n - 1

vincente

Vince il codice più breve in byte.


Che dire di quando età = 5?
Blu,

3
gli anelli hanno un ciclo di tre fasi. ('0', '*', '+')quindi 5 anni sono*
Juan Carlos Oropeza il

@vihan non capisco la domanda.
Juan Carlos Oropeza,

@vihan scusa ancora non capisco come dividere per due risolva il problema. Se hai un trucco per risolverlo, probabilmente non lo so
Juan Carlos Oropeza,

La dimensione è l'area, il perimetro o la lunghezza di ciascun lato?
Decadimento beta

Risposte:


6

K5, 27 30 26 25 22 byte

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

Questo approccio "avvolge" in modo iterativo un nucleo (a partire da "0") su tutti e quattro i lati usando un altro carattere ( {4(|+y,)/x}). La sequenza di avvolgimenti stagionali è determinata da una 3!sequenza modulo 3 ( ). È un po 'complicato far allineare il case base nel modo giusto.

modificare:

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

Questa alternativa crea l'intero array rettangolare in una sola volta dall'intervallo esclusivo fornito ( !) invertito e unito con se stesso dopo aver lasciato cadere un oggetto ( t,1_|t:|). Prendiamo quindi il massimo del prodotto cartesiano ( u|\:u:), prendiamo l'intera matrice modulo 3 ( 3!) e indicizziamo l'array di caratteri.

In azione:

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

Non conosco K, ma è un programma completo e non solo una funzione?
Alex A.

È sia un programma completo che una funzione. È un esempio di quella che viene chiamata "definizione tacita". La distinzione è comunque estremamente arbitraria.
Giovanni,

11

BBC Basic, 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.

Le parole chiave abbreviate aiutano molto qui. Nella riga 2, sto usando il VDUcomando (equivalente a C putchar()) per stampare ogni personaggio. Questo è molto più efficiente di P.MID$("0*+",p MOD3+1,1).

Qui è in esecuzione in BeebEm3 su un Mac:

inserisci qui la descrizione dell'immagine


Come si crea quella gif?
Juan Carlos Oropeza,

9
@JuanCarlosOropeza Non molto efficientemente. Ho usato QuickTime Player per catturare lo schermo, QuickTime Player 7 per esportare il video in immagini PNG, GraphicConverter per trasformarli in GIF ed ezgif.com per ottimizzare i risultati.
ossifrage schizzinoso,

7

CJam, 25 byte

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

Provalo qui.

Spiegazione

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)

Esempio:

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

Stampa riga per riga. Ogni riga è suddivisa in tre parti:

  • La parte ciclabile sinistra, incluso il primo carattere ripetuto.
  • La parte centrale ripetuta
  • La parte ciclistica giusta.

Per n=4:

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

Generiamo la parte sinistra al contrario come w, cloniamo i suoi ultimi 2*itempi carattere , quindi aggiungiamo la versione originale senza il primo carattere.


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)

Se pensiamo all'albero come una griglia di coordinate, il simbolo in (i,j)è determinato da max(abs(i),abs(j))%3, o in modo equivalente max(i,-i,j,-j)%3. Per ogni riga i, uniamo e stampiamo i simboli in quella riga.


Potresti accorciarlo mettendo l'istruzione range direttamente nella terza riga.
Ethan Brouwer,

@EthanBrouwer Sto usando Rdue volte, ed è più lungo di 5 caratteri, quindi il compito vince.
xnor

touche! Ho visto solo il primo. Colpa mia. :)
Ethan Brouwer il

5

Pyth, 23 byte

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

Provalo online: dimostrazione

Spiegazione:

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

Grazie Luis Mendo per avermi aiutato a radere 5 byte!

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

Esempio

>> 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 e spiegazione del codice

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

Nota minore

bwdistè una funzione che fa parte della casella degli strumenti di elaborazione delle immagini e può essere eseguita solo in MATLAB. Octave (IIRC) non è bwdistancora implementato, quindi non può essere eseguito in Octave.


Puoi salvare alcuni byte: usa eyee moltiplica l'elemento per la sua rot90versione "ed" per generare la matrice "seed":I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Luis Mendo,

Oh fico! Grazie @LuisMendo
rayryeng - Ripristina Monica il

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

Altro da fare, ma una versione base per ora. Ora con una deliziosa aderenza alle specifiche extra.

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

Uso:

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, 277252 caratteri

(251 codice carattere + 1 opzione riga di comando carattere.)

Prevede input in formato unario .

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

Esecuzione di esempio:

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

Uso dell'avviso per l'output: carattere proporzionale errato e il risultato è brutto. Nello snippet sottostante l'avviso viene reindirizzato al corpo snippato, fornendo un risultato migliore. La nuova riga all'interno dei backtick è significativa e contata.

Prova a eseguire lo snippet in 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>


Provo a eseguire lo snippet di codice, ma non succede nulla. Non so se è perché apro lo stack overflow in Chrome?
Juan Carlos Oropeza,

@JuanCarlosOropeza forse quello. Ho scritto: Test running the snippet in Firefoxma ovviamente stavo solo scherzando, Chrome (nessuna versione di Chrome) non è conforme a EcmaScritpt 6, mancando le =>funzioni.
edc65,

@JuanCarlosOropeza Devo correggermi. L'ultima versione di Chrome ha la funzione freccia, ma non comprende l'operatore di diffusione .... Ancora lontano da ES6
edc65,

0

Rubino, 85 caratteri

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

Esecuzione di esempio:

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

Funzione tche accetta un parametro intero: l'età.

Ungolfed (con mainfunzione per eseguire facilmente quello sopra):

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

La stdlib.hpuò essere necessario in alcuni sistemi, perché senza esso il tipo di ritorno della funzione sommerso callocstabilizzerebbe a int. Poiché inte char*non sono necessariamente della stessa dimensione, è possibile scrivere un puntatore non valido c. Nella maggior parte dei sistemi a 32 bit sia char*e inthanno le stesse dimensioni, ma questo non è vero per sistemi a 64 bit.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.