Afficher l'âge des anneaux d'arbre

24

introduction

Hier, j'ai vu un puzzle d'anniversaire . Félicitations!!

Cette semaine également, j'ai regardé un épisode de l'émission télévisée Bones où un cadavre a été retrouvé enterré sous un arbre. Pour calculer l'heure de la mort, ils ont compté les cernes des arbres.

Les cernes se forment parce que les arbres poussent plus lentement en hiver et plus rapidement en été. Ainsi, vous pouvez calculer l'âge de l'arbre en comptant les anneaux. Vous pouvez également voir des événements naturels comme les saisons pluvieuses ou sèches.

entrez la description de l'image ici

Défi

Étant donné un entier n >= 1en entrée, écrivez un programme complet pour sortir les anneaux d'âge de l'arbre.

Parce que les anneaux peuvent changer de forme, utilisez trois caractères différents ('0', '*', '+') pour montrer les cycles climatiques.

Âge 1

0

2 ans

***
*0*
***

3 ans

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

4 ans

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

La taille de l'arbre est un carré de côtés 2*n - 1

Gagnant

Le code le plus court en octets gagne.

Juan Carlos Oropeza
la source
Et quand l'âge = 5?
Blue
3
les anneaux ont un cycle en trois étapes. ('0', '*', '+')donc 5 ans est*
Juan Carlos Oropeza
@vihan ne comprend pas la question.
Juan Carlos Oropeza
@vihan désolé ne comprend toujours pas comment diviser par deux résout le problème. Si vous avez un hack pour le résoudre, je ne le sais probablement pas
Juan Carlos Oropeza
La taille est-elle la surface, le périmètre ou la longueur de chaque côté?
Beta Decay

Réponses:

6

K5, 27 30 26 25 22 octets

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

Cette approche "enveloppe" itérativement un noyau (en commençant par "0") sur les quatre côtés en utilisant un autre caractère ( {4(|+y,)/x}). La séquence des emballages saisonniers est déterminée par une 3!séquence modulo 3 ( ). C'est un peu compliqué de faire en sorte que le scénario de base soit parfaitement aligné.

modifier:

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

Cette alternative construit le tableau rectangulaire entier à la fois à partir de la plage exclusive fournie ( !) inversée et jointe à elle-même après avoir déposé un élément ( t,1_|t:|). Nous prenons ensuite le produit cartésien maximum ( u|\:u:), prenons l'ensemble de la matrice modulo 3 ( 3!) et indexons dans le tableau de caractères.

En action:

  "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
la source
Je ne connais pas K, mais est-ce un programme complet et pas seulement une fonction?
Alex A.
C'est à la fois un programme complet et une fonction. C'est un exemple de ce qu'on appelle une "définition tacite". La distinction est de toute façon extrêmement arbitraire.
JohnE
11

BBC Basic, 93 octets

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.

Les mots-clés abrégés aident beaucoup ici. À la ligne 2, j'utilise la VDUcommande (équivalente aux C putchar()) pour imprimer chaque caractère. C'est beaucoup plus efficace que P.MID$("0*+",p MOD3+1,1).

Ici, il fonctionne dans BeebEm3 sur un Mac:

entrez la description de l'image ici

ossifrage délicat
la source
Comment créez-vous ce gif?
Juan Carlos Oropeza
9
@JuanCarlosOropeza Pas très efficacement. J'ai utilisé QuickTime Player pour capturer l'écran, QuickTime Player 7 pour exporter la vidéo en images PNG, GraphicConverter pour les transformer en GIF et ezgif.com pour optimiser les résultats.
squeamish ossifrage
7

CJam, 25 octets

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

Testez-le ici.

Explication

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
la source
5

Matlab, 63 octets

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

Exemple:

>> 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
la source
5

Python 2, 83 octets

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

Imprime ligne par ligne. Chaque ligne est coupée en trois parties:

  • La partie cycliste gauche, y compris le premier caractère répété.
  • La partie centrale répétitive
  • La bonne partie cycliste.

Pour n=4:

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

Nous générons la partie gauche en sens inverse w, clonons ses derniers 2*itemps de caractère , puis ajoutons la version originale sans le premier caractère.

xnor
la source
5

Python 2, 83 octets

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

Si nous considérons l'arbre comme une grille de coordonnées, le symbole à (i,j)est déterminé par max(abs(i),abs(j))%3ou de manière équivalente max(i,-i,j,-j)%3. Pour chaque ligne i, nous joignons et imprimons les symboles de cette ligne.

xnor
la source
Vous pouvez raccourcir cela en plaçant l'instruction de plage directement dans la troisième ligne.
Ethan Brouwer
@EthanBrouwer J'utilise Rdeux fois, et c'est plus de 5 caractères, donc l'affectation l'emporte.
xnor
touche! Je n'ai vu que le premier. Ma faute. :)
Ethan Brouwer
5

Pyth, 23 octets

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

Essayez-le en ligne: Démonstration

Explication:

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
la source
3

MATLAB, 80 78 73 octets

Merci Luis Mendo de m'avoir aidé à raser 5 octets!

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

Exemple

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

Non golfé et explication du code

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

Note mineure

bwdistest une fonction qui fait partie de la boîte à outils de traitement d'image et ne peut être exécutée que dans MATLAB. Octave (IIRC) n'a pas encore été bwdistimplémenté, donc cela ne peut pas être exécuté dans Octave.

rayryeng - Réintégrer Monica
la source
Vous pouvez économiser quelques octets: utilisez eyeet multipliez élément par élémentrot90 version 'ed' pour générer la matrice "seed":I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Luis Mendo
Oh cool! Merci @LuisMendo
Reinstate Monica
2

Python 2, 134 octets

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())
Bleu
la source
2

Perl, 118 octets

Plus à faire, mais une version de base pour l'instant. Maintenant, avec une délicieuse adhérence aux spécifications supplémentaires.

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

Usage:

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
la source
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,''])
flawr
la source
1

Sed, 277 252 caractères

(Code de 251 caractères + option de ligne de commande de 1 caractère.)

Attend une entrée au format unaire .

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

Exemple d'exécution:

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
homme au travail
la source
0

JavaScript (ES6), 114

Utilisation de l'alerte pour la sortie - mauvaise police proportionnelle et le résultat est moche. Dans l'extrait de code ci-dessous, l'alerte est redirigée vers le corps coupé, ce qui donne un meilleur résultat. La nouvelle ligne à l'intérieur des backticks est significative et comptée.

Testez l'exécution de l'extrait dans 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
la source
J'essaie d'exécuter l'extrait de code, mais rien ne se passe. Je ne sais pas si c'est parce que j'ouvre le débordement de pile en chrome?
Juan Carlos Oropeza
@JuanCarlosOropeza peut-être cela. J'ai écrit: Test running the snippet in Firefoxmais évidemment je plaisantais, Chrome (pas de version de Chrome) n'est pas conforme à EcmaScritpt 6, il manque les =>fonctions.
edc65
@JuanCarlosOropeza Je dois me corriger. La dernière version de Chrome a la fonction flèche, mais ne comprend pas l'opérateur de propagation .... Toujours loin d'ES6
edc65
0

Ruby, 85 caractères

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

Exemple d'exécution:

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
homme au travail
la source
0

Moonscript - 104 octets

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
la source
0

C, 138 octets

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

Fonction tprenant un paramètre entier - l'âge.

Non golfé (avec mainfonction pour exécuter facilement celui ci-dessus):

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

Le stdlib.hpeut être nécessaire sur certains systèmes, car sans lui, le type de retour de la fonction non déclarée callocserait par défaut int. Parce que , intet char*ne sont pas nécessairement de même taille, un pointeur non valide peut être écrit dans c. Dans la plupart des systèmes 32 bits char*et intont la même taille, mais ce n'est pas le cas pour les systèmes 64 bits.

pawel.boczarski
la source