프라임에서 사각형 트리 링을 생성 할 수 있습니까?


33

분명히 그렇습니다! 세 단계 만 거치면됩니다.

1 단계

하자 F ( n은 (이하의 소수 또는 수와 동일)에 소수 계량 함수를 나타내는 N ).

정수 시퀀스 s ( n )을 다음과 같이 정의하십시오 . 각 양의 정수 n 에 대해

  • Initiallize t를N .
  • 만큼 t는 도 1도 소수 대체 t를 하여 F ( t ) 및 반복 처리.
  • 반복 횟수는 s ( n )입니다.

반복 프로세스는 모든 n에 대해 f ( n ) < n 이므로 종료 됩니다.

예를 들어 n = 25를 고려하십시오 . 우리는 t = 25를 초기화합니다 . 이것은 소수 나 1이 아니기 때문에 f (25), 즉 9를 계산합니다. 이것이 t 의 새로운 값이됩니다 . 이것은 소수도 아니고 1이므로 계속 진행합니다. f (9)는 4입니다. 우리는 다시 계속합니다 : f (4)는 2입니다. 이것이 소수이므로 여기에서 멈 춥니 다. 우리는 3 번의 반복을 수행했습니다 (25 ~ 9, 4 ~ 2, 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이 주어지면 유한 시퀀스 s (1), s (2), ..., s ( N 2 )를 감아 NxN 배열 (행렬)을 만들어 사각형 바깥 쪽 나선을 만듭니다. 예를 들어, 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 단계

NxN 배열을 회색 맵 또는 취향에 맞는 다른 컬러 맵이 있는 이미지 로 나타냅니다. 숫자의 순서는 시각적으로 명백한 색상 순서와 일치하도록 맵은 점진적이어야합니다. 아래의 테스트 사례는 일부 색상 맵을 보여줍니다.

도전

홀수 양의 정수 N이 주어지면 위에서 설명한 이미지를 생성하십시오.

규칙

  • 나선은 바깥 쪽이어야하지만 시계 방향 또는 시계 반대 방향 일 수 있으며 오른쪽 (위의 예에서와 같이), 왼쪽, 아래쪽 또는 위쪽으로 움직일 수 있습니다.

  • 가로 축과 세로 축의 축척이 같을 필요는 없습니다. 또한 축 레이블, 색상 막대 및 유사한 요소는 선택 사항입니다. 나선이 선명하게 보이는 한 이미지가 유효합니다.

  • 표준 수단으로 이미지를 출력 할 수 있습니다 . 특히, 이미지가 화면에 표시되거나 그래픽 파일이 생성되거나 RGB 값의 배열이 출력 될 수 있습니다. 파일이나 배열을 출력하는 경우, 표시 될 때의 모습에 대한 예를 게시하십시오.

  • 입력 수단과 형식은 평소처럼 유연합니다 . 프로그램 또는 기능을 제공 할 수있다 . 표준 허점은 금지되어 있습니다.

  • 바이트 단위의 최단 코드가 이깁니다.

테스트 사례

다음 이미지 (전체 해상도를 보려면 클릭)는 N의 여러 값에 해당합니다 . 위의 예와 같이 시계 방향의 오른쪽 우선 나선형이 사용됩니다. 이미지는 또한 여러 유효한 색상 맵을 보여줍니다.

  • N = 301 : 여기에 이미지 설명을 입력하십시오

  • N = 501 : 여기에 이미지 설명을 입력하십시오

  • N = 701 : 여기에 이미지 설명을 입력하십시오


값의 배열을 s(n)수정하지 않고 일부 플로팅 함수 / 패키지에 공급할 수 있다면 ( imshow예를 들어 matplotlib에서 이것을 처리 할 수 있다고 생각합니다 ) 이것이 허용 가능한 출력 형식입니까?
dylnan

@dylnan 물론, 화면에 이미지를 표시하거나 유효한 파일을 생성하는 한 가능합니다. 사실 나는 당신이 언급 한 것과 비슷한 것으로 예제를 생성했습니다. 값의 스케일링에주의하십시오. 예를 들어 Matlab (및 Matplotlib)에서와 같이 1 이상의 모든 값에 동일한 색상이 지정된 경우 허용 imshow되지 않습니다.
Luis Mendo

좋은 지적. 그런지 확실 imshow하지 않습니다.
dylnan

1
@ kamoroso94 여기를
Luis Mendo

1
매우 분명합니다
Christopher

답변:


3

Dyalog 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 바이트

Ander와 Andras 덕분에 12 바이트를 깎았 고,이 두 가지를 결합한 Luis에게 감사드립니다. Remco 덕분에 16 개 면도, flawr 덕분에 6 개 면도

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

Wolfram Language (Mathematica) 124 바이트

12 바이트를 절약 한 Martin Ender 에게 감사 합니다!

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바이트를 저장합니다.
user202729

8
하하, 당신은 당신에게 그것을 제안하고 있습니까?
Luis Mendo

6
@ user202729 작동하지 않는 것 같습니다.
user202729

18
나는 당신의 내면의 대화를 방해하지 않았습니다 :-P
Luis Mendo

p필요할 때까지 정의를 연기하십시오 ....,{y,p=(1-#)/2,-p},{x,p,-p}
Martin Ender

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.m에서 코드 + 파일의 경우 64 + 1 바이트

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

I45 바이트 를 정의하는 명령 창

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물론 익명으로 함수 를 만들려고했지만 물론 카운트를 크게 줄였습니다. 그러나 두 가지 문제가 있습니다.

    1. MATLAB에는 중단 조건을 제공하는 삼항 연산자가 없으므로 익명 함수를 사용할 때는 무한 재귀를 피하기가 어렵습니다. 3 항의 정렬 연산자 (아래 참조)를 보팅하려면 조건이 두 번 필요하므로 바이트 비용이 발생합니다.

    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) * 바이트

나는 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)))

* 참고 : 불필요한 반복의 메트릭 크 래튼을 허용하려는 경우 행 while any(i), 변경하고 5 바이트를 절약 할 수 있습니다 for m=v, .


좋은! 나는 당신 cumsum이 벡터화하고 피하는 방법을 좋아합니다nnz(primes(...)
Luis Mendo

1
내가 올바르게 이해하면 필요한 것보다 많은 시간을 반복하는 것이 아프지 않습니다 (속도 비용). 그래서 당신은 대체 할 수 있습니다 while any(i)for m=M. 코드를 실행하는 데 몇 시간이 걸리는지 누가 걱정하는지 :-)
Luis Mendo

2
@LuisMendo : 물론이지? 이미 필요한 것보다 한 번 더 반복됩니다. 또 다른 n^2반복이 해칠 것입니다! ;)
gnovice

1
그 정신이야! 빠른 실행 버전을 유지할 수도 있지만 바이트 수는 짧습니다.
Luis Mendo

2

파이썬 3, 299 265 바이트

Jonathan Frech와 NoOneIsHere의 형식 제안으로 5 바이트를 절약했습니다. 한 번만 호출 된 함수 정의를 제거하여 추가 34 바이트를 제거했습니다.

파이썬은 소수를 결정하거나 배열을 나선형으로 만드는 명령이 없기 때문에 다른 것보다 조금 더 깁니다. 그러나 약 1 분 동안 비교적 빠르게 실행됩니다 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과 사이의 공백을 제거 할 수 있습니다 *.
NoOneIsHere2

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.