Показати вік кілець з дерева


24

Вступ

Вчора я побачив пазл на день народження . З повагою !!

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

Дерев'яні кільця утворюються тому, що дерева ростуть повільніше взимку і швидше влітку. Таким чином, ви можете розрахувати вік дерева, підраховуючи кільця. Також можна побачити природні події, такі як сезон дощів чи сухих.

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

Виклик

Давши ціле число 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:|!

Ця альтернатива будує весь прямокутний масив одразу із передбаченого ексклюзивного діапазону ( !), перевернутого та з'єднаного з собою після відкидання елемента ( t,1_|t:|). Потім беремо декартовий продукт максимум ( 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*"
 "*********")

Я не знаю К, але це повна програма, а не лише функція?
Олексій А.

Це і повна програма, і функція. Це приклад того, що називається "мовчазне визначення". Відмінність все одно є надзвичайно довільною.
JohnE

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.

Тут скоро допомагають скорочені ключові слова. У другому рядку я використовую 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

Матлаб, 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)

Якщо ми думаємо про дерево як координатну сітку, символ у (i,j)значенні визначається max(abs(i),abs(j))%3рівним чи рівноцінним max(i,-i,j,-j)%3. Для кожного рядка iми з'єднуємо та друкуємо символи у цьому рядку.


Ви можете скоротити це, поставивши оператор діапазону прямо в третій рядок.
Етан Брауер

@EthanBrouwer я використовую Rдвічі, і це довше, ніж 5 символів, тому завдання виграє.
xnor

торкатися! Я бачив лише перший. Моє ліжко. :)
Етан Брауер

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

Пояснення без коду та код

%// 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редакцію для створення "насіннєвої" матриці:I=eye(2*input('')-1);a='0*+';a(mod(bwdist(I.*rot90(I),'chessboard'),3)+1)
Луїс Мендо

О, круто! Дякуємо @LuisMendo
Відновіть Моніку

2

Пітон 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

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>


Я намагаюся запустити фрагмент коду, але нічого не відбувається. Не знаєте, чи це тому, що я відкриваю переповнення стека в хромі?
Хуан Карлос Оропеза

@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.