Показать возраст годичных колец


24

Введение

Вчера я видел загадку дня рождения . Congrats !!

Также на этой неделе я посмотрел эпизод телешоу « Кости», где было найдено мертвое тело, похороненное под деревом. Чтобы рассчитать время смерти, они сосчитали кольца деревьев.

Кольца деревьев образуются потому, что деревья растут медленнее зимой и быстрее летом. Таким образом, вы можете рассчитать возраст дерева путем подсчета колец. Также вы можете увидеть природные явления, такие как дождливый или сухой сезон.

введите описание изображения здесь

Вызов

Учитывая целое число в 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 лет*
Хуан Карлос Оропеза

@vihan не понимаю вопроса.
Хуан Карлос Оропеза

@vihan извините до сих пор не понимаю, как разделить на два решить проблему. Если у вас есть взломать, чтобы решить это, я, вероятно, не знаю об этом
Хуан Карлос Оропеза

Размер - это площадь, периметр или длина каждой стороны?
бета-распад

Ответы:


6

K5, 27 30 26 25 22 байта

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

Этот подход итеративно «оборачивает» ядро ​​(начиная с "0") со всех четырех сторон, используя какой-либо другой символ ( {4(|+y,)/x}). Последовательность сезонных упаковок определяется по модулю 3 ( 3!). Немного неудобно заставить базовый корпус выстроиться в ряд.

редактировать:

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

Эта альтернатива строит весь прямоугольный массив сразу из предоставленного исключенного range ( !), обращенного и объединенного с самим собой после отбрасывания item ( t,1_|t:|). Затем мы берем декартово произведение Maximum ( 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, но это полная программа, а не просто функция?
Алекс А.

Это и полная программа, и функция. Это пример того, что называется «молчаливое определение». Различие в любом случае крайне произвольно.
Джон

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?
Хуан Карлос Оропеза

9
@JuanCarlosOropeza Не очень эффективно. Я использовал QuickTime Player для захвата экрана, QuickTime Player 7 для экспорта видео в изображения PNG, GraphicConverter для преобразования их в GIF и ezgif.com для оптимизации результатов.
брезгливый оссифраж

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)

Если мы думаем о дереве как о координатной сетке, символ at (i,j)определяется max(abs(i),abs(j))%3или эквивалентно max(i,-i,j,-j)%3. Для каждой строки iмы соединяем и печатаем символы в этой строке.


Вы можете сократить это, поместив оператор range прямо в третью строку.
Итан Брауэр

@EthanBrouwer Я использую Rдважды, и это больше, чем 5 символов, поэтому назначение выигрывает.
xnor

Touche! Я видел только первый. Виноват. :)
Итан Брауэр

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 байта

Спасибо Луису Мендо за помощь в бритье на 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'ed версию, чтобы сгенерировать матрицу "seed":I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Luis Mendo

О, круто! Спасибо @LuisMendo
rayryeng - Восстановить Монику

2

Python 2, 134 байта

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 байт

Еще предстоит сделать, но пока базовая версия. Теперь с восхитительным соблюдением дополнительных спецификаций.

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

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 персонажа

(251 символьный код + 1 символьная опция командной строки.)

Ожидается ввод в одинарном формате.

: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

Использование оповещения для вывода - неправильный пропорциональный шрифт и результат ужасный. В приведенном ниже фрагменте предупреждения перенаправляется на отсекаемое тело, что дает лучший результат. Новая строка внутри обратных кавычек значительна и считается.

Попробуйте запустить фрагмент в 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>


Я пытаюсь запустить фрагмент кода, но ничего не происходит. Не знаю, если это потому, что я открываю переполнение стека в Chrome?
Хуан Карлос Оропеза

@JuanCarlosOropeza возможно это. Я написал: Test running the snippet in Firefoxно, очевидно, я просто шутил, Chrome (без версии Chrome) не соответствует EcmaScritpt 6, пропуская =>функции.
edc65

@JuanCarlosOropeza Я должен исправить себя. Новейшая версия Chrome имеет функцию стрелки, но не понимает оператора распространения .... Все еще далеко от ES6
edc65

0

Рубин, 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-битных систем.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.