Ağaç halkalarının yaşını göster


24

Giriş

Dün bir doğum günü bulmacası gördüm . Tebrikler!!

Ayrıca bu hafta bir ağacın altında gömülü bir ceset bulunan TV dizisi Bones'ın bir bölümünü izledim . Ölüm zamanını hesaplamak için ağaç halkalarını saydılar.

Ağaç halkaları, ağaçların kışın daha yavaş ve yaz aylarında daha hızlı büyümesi nedeniyle oluşur. Böylece ağacın yaşını halkaları sayarak hesaplayabilirsiniz. Ayrıca yağışlı veya kurak mevsimler gibi doğal olayları görebilirsiniz.

görüntü tanımını buraya girin

Meydan okuma

n >= 1Giriş olarak bir tamsayı verildiğinde , ağaç çağı halkalarını çıkarmak için tam bir program yazın.

Çünkü halkalar şekil değiştirebildiğinden, iklim çevrimlerini göstermek için üç farklı karakter ('0', '*', '+') kullanın.

Yaş 1

0

Yaş 2

***
*0*
***

3 yaşında

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

4. yaş

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

Ağacın boyutu kenarlardan oluşan bir karedir. 2*n - 1

Kazanan

Bayt cinsinden en kısa kod kazanır.


Peki ya yaş = 5?
Mavi,

3
halkaların üç basamaklı bir çevrimi vardır. ('0', '*', '+')yani 5 yıl*
Juan Carlos Oropeza

@ vihan soruyu anlamadı.
Juan Carlos Oropeza 10:15

@ vihan üzgünüm hala iki tarafından bölmek sorunu çözmek nasıl anlamıyorum.
Çözmek

Alanın büyüklüğü, çevre mi yoksa her bir tarafın uzunluğu mu?
Beta Ayı

Yanıtlar:


6

K5, 27 30 26 25 22 bayt

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

Bu yaklaşım, yinelemeli olarak "0", diğer bazı karakterleri ( {4(|+y,)/x}) kullanarak dört taraftan da bir çekirdeği (başından itibaren ) "sarar" . Mevsimsel sarmaların sırası, bir modulo 3 ( 3!) dizisi ile belirlenir. Temel davayı doğru sıraya sokmak biraz zor.

Düzenle:

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

Bu alternatif, tüm dikdörtgen diziyi, !bir öğeyi ( t,1_|t:|) bıraktıktan sonra ters çevrilmiş ve kendisiyle birleştirilen sağlanan özel aralıktan ( ) bir kerede oluşturur . Daha sonra kartezyen ürünü maksimum ( u|\:u:) alıyoruz, modulo 3 ( 3!) matrisinin tamamını alıyoruz ve karakter dizisine indeksliyoruz.

Eylemde:

  "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 bilmiyorum, ama bu tam bir program ve sadece bir işlev değil mi?
Alex A.

Hem tam bir program hem de bir işlevdir. Bu "taktik tanımı" olarak adlandırılan bir örnek. Farklılık zaten son derece keyfi.
JohnE 09:

11

BBC Basic, 93 bayt

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.

Kısaltılmış anahtar kelimeler burada çok yardımcı olur. 2. satırda, her karakteri yazdırmak için VDUkomutu (C'nin eşdeğeri putchar()) kullanıyorum. Bu çok daha verimli P.MID$("0*+",p MOD3+1,1).

İşte Mac'te BeebEm3'te çalışıyor:

görüntü tanımını buraya girin


Bu gif nasıl yaratılır?
Juan Carlos Oropeza 10:15

9
@JuanCarlosOropeza Çok verimli değil. Ekranı yakalamak için QuickTime Player'ı, videoyu PNG görüntülerine dışa aktarmak için QuickTime Player 7'yi , sonuçları bir GIF'e dönüştürmek için GraphicConverter'ı ve sonuçları optimize etmek için ezgif.com'u kullandım.
pembemsi ossifrage

7

CJam, 25 bayt

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

Burada test et.

açıklama

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 bayt

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

Örnek:

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

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

Satır satır yazdırır. Her satır üç parçaya bölünür:

  • Tekrarlanan ilk karakter dahil, soldaki bisiklet bölümü.
  • Yinelenen merkez kısmı
  • Doğru bisiklet parçası.

İçin n=4:

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

Sol kısmı ters olarak oluşturur w, son karakter 2*izamanlarını kopyalar, sonra ilk karakter olmadan orijinal versiyona ekleriz.


5

Python 2, 83 bayt

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

Ağacı bir koordinat ızgarası olarak düşünürsek, içindeki sembol , veya ile eşdeğer (i,j)olarak belirlenir . Her satır için , o satırdaki sembolleri birleştirip yazdırıyoruz.max(abs(i),abs(j))%3max(i,-i,j,-j)%3i


Range deyimini doğrudan üçüncü satıra yerleştirerek bunu kısaltabilirsiniz.
Ethan Brouwer

@EthanBrouwer Rİki kere kullanıyorum ve 5 karakterden daha uzun, bu yüzden atama kazanıyor.
xnor

tuşe! Sadece ilkini gördüm. Benim hatam. :)
Ethan Brouwer

5

Pyth, 23 bayt

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

Çevrimiçi deneyin: Gösteri

Açıklama:

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 bayt

5 bayt tıraş etmeme yardım ettiğin için teşekkürler Luis Mendo!

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

Örnek

>> 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 ve Kod Açıklaması

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

Küçük Not

bwdistgörüntü işleme araç kutusunun bir parçası olan ve yalnızca MATLAB ile çalıştırılabilen bir işlevdir. Octave (IIRC) bwdisthenüz uygulamamıştır, bu yüzden bu Octave'da çalıştırılamaz.


Birkaç bayt tasarruf edebilirsiniz: "tohum" matrisini oluşturmak için 'ed' sürümüyle eyeelement-wise kullanın ve çoğaltın rot90:I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Luis Mendo

Oh harika! Thanks @LuisMendo
Reinstate Monica

2

Python 2, 134 bayt

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 bayt

Daha yapılacak, ancak şimdilik temel bir versiyon. Şimdi lezzetli ekstra spec bağlılık ile.

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

Kullanımı:

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 karakter

(251 karakter kodu + 1 karakter komut satırı seçeneği.)

Girişi unary formatında bekler .

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

Örnek çalışma:

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

Çıktı için uyarı kullanma - hatalı orantılı yazı tipi ve sonuç çirkin. Alttaki snippet'te uyarı, kesilen gövdeye yönlendirilir ve daha iyi sonuç elde edilir. Geri tepme çubukları içindeki yeni hat önemlidir ve sayılır.

Snippet'in Firefox'ta çalışmasını test edin.

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


Kod pasajını çalıştırmayı deniyorum ama hiçbir şey olmuyor. Krom yığınını açtığım için bu olup olmadığını bilmiyor musunuz?
Juan Carlos Oropeza 10:15

@JuanCarlosOropeza belki budur. Test running the snippet in FirefoxYazdım : açıkçası şaka yapıyordum, Chrome (Chrome'un hiçbir sürümü yok) EcmaScritpt 6 uyumlu değil, =>işlevleri eksik .
edc65 10:15

@JuanCarlosOropeza Kendimi düzeltmek zorundayım. Chrome'un en yeni sürümü arrow işlevine sahiptir, ancak spread operatörünü anlamıyor .... Hala ES6'dan uzakta
edc65

0

Ruby, 85 karakter

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

Örnek çalışma:

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

Aysonu - 104 bayt

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 bayt

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

tBir tamsayı parametresi alarak işlev - yaş.

Ungolfed ( mainyukarıdakileri kolayca çalıştırma fonksiyonu ile):

#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.hOnsuz bildirilmemiş fonksiyonun dönüş tipi nedeniyle, bazı sistemlerde gerekli olabilir callocvarsayılan olacaktır int. Çünkü intve char*zorunlu olarak aynı boyutta değildir, geçersiz bir işaretçi haline yazılmış olabilir c. En 32-bit sistemlerde her iki char*ve intaynı boyutta, ancak bu 64-bit sistemler için geçerli değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.