Могут ли квадратные годичные кольца генерироваться из простых чисел?

33

Видимо да! В три простых шага.

Шаг 1

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

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

  • Initiallize т к п .
  • Пока 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 Конечно, пока оно отображает изображение на экране или создает файл, оно действительно. На самом деле я привел примеры с чем-то похожим на то, что вы упоминаете. Просто будьте осторожны с масштабированием значений. Например, недопустимо, если все значения выше 1 имеют одинаковый цвет, как это imshowделает Matlab (и, возможно, Matplotlib)
Luis Mendo
хорошая точка зрения. Не уверен, что imshowделает это.
Дилнан
1
@ kamoroso94 Пожалуйста, смотрите здесь
Луис Мендо
1
Да, очень ясно
Кристофер

Ответы:

3

Дьялог АПЛ, 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 благодаря Ремко, 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
Adriaan
источник
8

Wolfram Language (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]]&

Попробуйте онлайн!


Сгенерированное изображение:

спиральный

Замкнутая формула формулы спирального значения взята непосредственно из этого моего ответа .

user202729
источник
5
#/2-.5сохраняет байт.
user202729
8
Ха-ха, ты предлагаешь это себе?
Луис Мендо
6
@ user202729 Кажется, не работает.
user202729
18
Я не хотел прерывать ваш внутренний диалог :-P
Луис Мендо
Отложите определение pдо тех пор, пока оно вам не понадобится:...,{y,p=(1-#)/2,-p},{x,p,-p}
Мартин Эндер
7

MATLAB: 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);
Wolfie
источник
6

MATLAB - 126 121 * байт

Я попытался использовать более векторизованный подход, чем Adriaan, и смог сбрить больше байтов. Вот однострочное решение:

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

gnovice
источник
Ницца! Мне нравится, как вы используете, 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)
user2699
источник
1
Возможно 294 байта (не проверено).
Джонатан Фрех
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
Bolce Bussiere
источник
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:

п = 101

plannapus
источник