Чи можуть утворюватися квадратні кільця з дерев?


33

Мабуть, так! У три легких кроки.

Крок 1

Нехай f ( n ) позначає функцію підрахунку простих чисел (кількість простих значень менше або дорівнює n ).

Визначте цілу послідовність s ( n ) наступним чином. Для кожного натурального числа n ,

  • Ініціалізуйте t до n .
  • Поки t не є простим і не 1, замініть t на f ( t ) і повторіть.
  • Кількість ітерацій s ( n ).

Ітераційний процес гарантовано закінчується, оскільки f ( n ) < n для всіх n .

Розглянемо для прикладу n = 25. Ми ініціалізуємо t = 25. Оскільки це не є простим і не 1, обчислюємо f (25), що дорівнює 9. Це стає новим значенням для t . Це не є простим, ані 1, тому ми продовжуємо: f (9) - 4. Ми продовжуємо знову: f (4) - 2. Оскільки це простий, ми зупиняємося тут. Ми зробили 3 ітерації (від 25 до 9, потім до 4, потім до 2). Таким чином s (25) дорівнює 3.

Перші 40 членів послідовності такі. Послідовність відсутня в OEIS.

0 0 0 1 0 1 0 2 2 2 0 1 0 2 2 2 0 1 0 3 3 3 0 3 3 3 3 3 0 3 0 1 1 1 1 1 0 2 2 2

Крок 2

Давши непарне додатне ціле число N , побудуйте масив N × N (матрицю), намотавши кінцеву послідовність s (1), s (2), ..., s ( N 2 ), щоб утворити квадратну зовнішню спіраль . Наприклад, для N = 5 спіраль дорівнює

s(21)   s(22)   s(23)   s(24)   s(25)
s(20)   s(7)    s(8)    s(9)    s(10)
s(19)   s(6)    s(1)    s(2)    s(11)
s(18)   s(5)    s(4)    s(3)    s(12)
s(17)   s(16)   s(15)   s(14)   s(13)

або, замінюючи значення,

 3       3       0       3       3
 3       0       2       2       2
 0       1       0       0       0
 1       0       1       0       1
 0       2       2       2       0

Крок 3

Представляйте масив N × N у вигляді зображення із сірою кольоровою картою або за допомогою іншої кольорової карти на ваш смак. Карта повинна бути поступовою, щоб порядок чисел відповідав деякому візуально очевидному порядку кольорів. Наведені нижче тестові приклади показують деякі приклади кольорових карт.

Змагання

Давши непарне додатне ціле число N , створіть зображення, описане вище.

Правила

  • Спіраль повинна бути назовні, але може бути за годинниковою стрілкою або проти годинникової стрілки і може починати рухатися праворуч (як у наведеному вище прикладі), вліво, вниз або вгору.

  • Масштаби горизонтальної та вертикальної осей не повинні бути однаковими. Крім того, мітки осі, кольорова смуга та подібні елементи необов’язкові. Поки спіраль добре видно, зображення є дійсним.

  • Зображення можна виводити будь-яким із стандартних засобів . Зокрема, зображення може відображатися на екрані, або створюватися графічний файл або виводитися масив значень RGB. Якщо виводите файл або масив, будь ласка, опублікуйте приклад того, як він виглядає при відображенні.

  • Засоби введення та формат гнучкі, як зазвичай . Може бути надана програма або функція . Стандартні лазівки заборонені .

  • Виграє найкоротший код у байтах.

Тестові справи

Наступні зображення (натисніть для повного дозволу) відповідають кілька значень N . Використовується спіраль, спрямована на годинник, як вперше, як у прикладі вище. Зображення також ілюструють кілька дійсних кольорових карт.

  • N = 301: введіть тут опис зображення

  • N = 501: введіть тут опис зображення

  • N = 701: введіть тут опис зображення


Якщо масив значень s(n)можна подати в якусь графічну функцію / пакет без зміни (я думаю, що imshowв matplotlib міг би це вчинити, наприклад), це прийнятна форма виводу?
dylnan

@dylnan Звичайно, якщо вона розміщує зображення на екрані або створює файл, який є дійсним. Насправді я створив приклади із чимось подібним до того, що ви згадуєте. Будьте обережні з масштабуванням значень. Наприклад, неприйнятно, якщо всі значення вище 1 даються того ж кольору, що і Matlab (і, можливо, Matplotlib's)imshow робить
Луїс Mendo

влучне зауваження. Не впевнений, чи imshowтак це.
ділнан

1
@ kamoroso94 Дивіться тут
Луїс Мендо

1
Так, зрозуміло
Крістофер

Відповіді:


3

Діалог APL, 94 байти

'P2'
2⍴n←⎕
9
(⍪0){×≢⍵:(≢⍺)((⍉∘⌽⍺,↑)∇↓)⍵⋄⍺}2↓{⍵⌊1+⍵[+\p]}⍣≡9×~p←1=⊃+/(≠⍨,≠⍨,~⍴⍨(×⍨n)-2×≢)¨,\×⍳n

передбачає ⎕IO=0

вихід для n = 701 (перетворений з .pgm в .png):

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


10

MATLAB - 197 185 178 175 184 163 162 148 142 140 байт

Поголив 12 байт, завдяки Андеру та Андрасу, і велике спасибі Луїсу за те, що вони об'єднали їх. Поголений 16 завдяки Remco, 6 завдяки flawr

function F(n)
p=@primes
s=@isprime
for a=2:n^2
c=0
if~s(a)
b=nnz(p(a))
while~s(b)
b=nnz(p(b))
c=c+1
end
end
d(a)=c
end
imagesc(d(spiral(n)))

Результат для N=301( F(301)):

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

Пояснення:

function F(n)
p=@primes % Handle
s=@isprime % Handle
for a=2:n^2 % Loop over all numbers
    c=0 % Set initial count
    if~s(a) % If not a prime
        b=nnz(p(a)) % Count primes
        while~s(b) % Stop if b is a prime. Since the code starts at 2, it never reaches 1 anyway
            b=nnz(p(b)) % count again
            c=c+1 % increase count
        end
    end
    d(a)=c % store count
end
imagesc(d(spiral(n))) % plot

8

Мова Вольфрама (Mathematica) , 124 байти

Дякуємо Мартіну Ендеру за збереження 12 байт!

Image[#/Max@#]&[Array[(n=0;Max[4#2#2-Max[+##,3#2-#],4#
#-{+##,3#-#2}]+1//.x_?CompositeQ:>PrimePi[++n;x];n)&,{#,#},(1-#)/2]]&

Спробуйте в Інтернеті!


Згенероване зображення:

Спіраль

Закрита форма формула спірального значення , отримане безпосередньо з цієї відповіді шахти.


5
#/2-.5зберігає байт.
користувач202729

8
Ха-ха, ти це пропонуєш собі?
Луїс Мендо

6
@ user202729 Здається, це не працює.
користувач202729

18
Я не хотів переривати ваш внутрішній діалог:
Луїс Мендо,

Відкладіть визначення, pпоки вам це не потрібно:...,{y,p=(1-#)/2,-p},{x,p,-p}
Мартін Ендер,

7

МАТЛАБ: 115 114 110 байт

Один вкладиш (запускається в R2016b + як функція у сценарії ) 115 байт

I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)));function k=s(n,k);if n>1&~isprime(n);k=s(nnz(primes(n)),k+1);end;end

Поміщення функції в окремий файл, як це запропонував flawr, та використання 1 додаткового байта на додаткове правило файлу

У файлі s.m64 + 1 байт для коду + файл

function k=s(n,k);if n>1&~isprime(n);k=s(nnz(primes(n)),k+1);end

Вікно команди для визначення I, 45 байт

I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)))

Всього: 110 байт


Для цього використовується рекурсія замість whileциклічного циклу, як це роблять інші реалізації MATLAB ( gnovice , Adriaan ). Запустити його як сценарій (у R2016b чи новішій версії), це визначає функціюI яку можна виконувати якI(n) .

Структурована версія:

% Anonymous function for use, i.e. I(301)
% Uses arrayfun to avoid for loop, spiral to create spiral!
I=@(N)imagesc(arrayfun(@(x)s(x,0),spiral(N)));

% Function for recursively calculating the s(n) value
function k=s(n,k)
    % Condition for re-iterating. Otherwise return k unchanged
    if n>1 && ~isprime(n)
        % Increment k and re-iterate
        k = s( nnz(primes(n)), k+1 );
    end
end

Приклад:

I(301)

сюжет

Примітки:

  • Я намагався зробити sфункцію також анонімною, звичайно, це значно зменшило б кількість. Однак є 2 питання:

    1. Нескінченну рекурсію важко уникнути при використанні анонімних функцій, оскільки MATLAB не має потрійного оператора, який би запропонував перерву. Постановка на потрійний оператор сортів (див. Нижче) також коштує байтів, оскільки нам потрібна умова вдвічі.

    2. Ви повинні передати анонімну функцію собі, якщо вона є рекурсивною (див. Тут ), яка додає байти.

    Найближчим до цього я прийшов наступними рядками, можливо, це можна змінити на роботу:

    % Condition, since we need to use it twice 
    c=@(n)n>1&&~isprime(n);
    % This uses a bodged ternary operator, multiplying the two possible outputs by
    % c(n) and ~c(n) and adding to return effectively only one of them
    % An attempt was made to use &&'s short-circuiting to avoid infinite recursion
    % but this doesn't seem to work!
    S=@(S,n,k)~c(n)*k+c(n)&&S(S,nnz(primes(n)),k+1);

6

MATLAB - 126 121 * байт

Я спробував більш векторизований підхід, ніж Адріан, і зміг поголити більше байтів. Ось однолінійне рішення:

function t(n),M=1:n^2;c=0;i=1;s=@isprime;v=cumsum(s(M));while any(i),i=M>1&~s(M);c=c+i;M(i)=v(M(i));end;imagesc(c(spiral(n)))

І ось красиво відформатоване рішення:

function t(n),
  M = 1:n^2;
  c = 0;
  i = 1;
  s = @isprime;
  v = cumsum(s(M));
  while any(i),         % *See below
    i = M > 1 & ~s(M);
    c = c+i;
    M(i) = v(M(i));
  end;
  imagesc(c(spiral(n)))

* Примітка: якщо ви готові , щоб дозволити метричну crapton непотрібних повторень, ви можете змінити рядок , while any(i), щоб for m=v, і зберегти 5 байт.


Приємно! Мені подобається, як ти використовуєш cumsumвекторизацію та уникненняnnz(primes(...)
Луїс Мендо

1
Якщо я правильно розумію, це не завадить повторити більше разів, ніж потрібно (ціною швидкості). Так ви можете замінити while any(i)на for m=M. Кому байдуже, якщо на коду потрібні години :-)
Луїс Мендо

2
@LuisMendo: Звичайно, чому б і ні? Це вже повторюється ще раз, ніж потрібно, що ще n^2чи так повторить ітерації! ;)
gnovice

1
Це дух! Ви також можете зберегти більш швидку працюючу версію, але кількість байтів - це коротша
Луїс Мендо,

2

Python 3, 299 265 байт

Збережено 5 байт завдяки форматуванням пропозицій Джонатана Фреха та NoOneIsHere. Видалено додаткові 34 байти, видаливши визначення функції, яке було викликане лише один раз.

Це трохи довше, ніж деякі інші, через те, що python не має команди для визначення переваги, або спіральний масив. Однак він працює досить швидко, приблизно за хвилину n = 700.

from pylab import*
def S(n):
 q=arange(n*n+1);t=ones_like(q)
 for i in q[2:]:t[2*i::i]=0
 c=lambda i:0 if t[i]else 1+c(sum(t[2:i]));S=[c(x)for x in q]
 t=r_[[[S[1]]]]
 while any(array(t.shape)<n):m=t.shape;i=multiply(*m)+1;t=vstack([S[i:i+m[0]],rot90(t)])
 return t

Перевірте це за допомогою

n = 7
x = S(n)
imshow(x, interpolation='none')
colorbar()
show(block=False)


1
Одне швидке: ви можете видалити пробіл між importі *.
NoOneIsHere

2

J, 121 байт

load 'viewmat'
a=:3 :'viewmat{:@((p:inv@{.,>:@{:)^:(-.@((=1:)+.1&p:)@{.)^:_)@(,0:)"0(,1+(i.@#+>./)@{:)@|:@|.^:(+:<:y),.1'

Визначає функцію:

a=:3 :'viewmat{:@((p:inv@{.,>:@{:)^:(-.@((=1:)+.1&p:)@{.)^:_)@(,0:)"0(,1+(i.@#+>./)@{:)@|:@|.^:(+:<:y),.1' | Full fuction
                                                                     (,1+(i.@#+>./)@{:)@|:@|.^:(+:<:y),.1  | Creates the number spiral
              {:@((p:inv@{.,>:@{:)^:(-.@((=1:)+.1&p:)@{.)^:_)@(,0:)"0                                      | Applies S(n) to each element
       viewmat                                                                                             | View the array as an image

2

R, 231 байт

function(n){p=function(n)sum(!n%%2:n)<2;M=matrix(0,n,n);M[n^2%/%2+cumsum(c(1,head(rep(rep(c(1,-n,-1,n),l=2*n-1),rev(n-seq(n*2-1)%/%2)),-1)))]=sapply(1:(n^2),function(x){y=0;while(x>2&!p(x)){x=sum(sapply(2:x,p));y=y+1};y});image(M)}

Трохи менше гольфу:

function(n){
    p=function(n)sum(!n%%2:n)<2 #"is.prime" function
    M=matrix(0,n,n)             #empty matrix
    indices=n^2%/%2+cumsum(c(1,head(rep(rep(c(1,-n,-1,n),l=2*n-1),rev(n-seq(n*2-1)%/%2)),-1)))
    values=sapply(1:(n^2),function(x){
        y=0
        while(x>2&!p(x)){
            x=sum(sapply(2:x,p))
            y=y+1
            }
        y})
    M[indices]=values
    image(M) #Plotting
}

Анонімна функція. Виведення у графічному вікні. Шкала на червоній шкалі з найтемнішим відтінком дорівнює 0, а більш чіткі відтінки збільшують значення.

Результат для n = 101:

n = 101

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.