삼각 울람 나선


21

우리는 울람 나선에 대해 몇 가지 도전 을 했습니다 . 그러나 충분하지 않습니다.

이 도전에서 우리는 삼각형 Ulam 나선 (일반적인 사각형 Ulam 나선과 반대로)을 그릴 것입니다. 다음은 나선 모양의 스케치입니다.

여기에 이미지 설명을 입력하십시오

우리가 알고 있듯이, Ulam 나선 은 모든 자연수를 바깥 쪽 나선으로 정렬 하고 소수만 표시합니다. 위의 스케치에서 검은 색 (소수점)으로 표시되는 숫자 만 표시됩니다.

도전

숫자 N 을 입력으로 받아들이고 해당 숫자까지 삼각형 Ulam 나선을 표시합니다.

  • 입력은 stdin 또는 함수 인수 일 수 있습니다.
  • 위 그림에서와 같이 나선은 양의 방향 (시계 반대 방향)으로 회전해야합니다.
  • 위 그림의 120도 회전은 유효하며 입력에 따라 회전이 다를 수 있습니다. 그러나 허용되는 유일한 회전이 120도이므로 암시 적 삼각형의 가장 낮은면은 수평이어야합니다.
  • 코드는 기본 데이터 유형으로 수행하는 중간 계산에서 허용되는 N 까지 이론적으로 (충분한 시간과 메모리가 제공됨) 실행되어야합니다 . double충분하다; 큰 정수 유형이 필요하지 않습니다.
  • 모든 내장 기능이 허용됩니다.
  • 나는 내 자신의 대답을 받아들이지 않을 것입니다 (어쨌든 그것이 가장 짧을 것이라고 생각하지는 않습니다 ...).

출력 형식

다음 중 하나를 선택하십시오.

  1. 소수에 마커 (점, 원, 십자형, 원하는 것)가 있고 그래프 에 숫자가 아닌 그래프 는 표시하지 않습니다. 두 축의 스케일이 같을 필요는 없습니다. 즉, 내포 된 삼각형은 등변 일 필요는 없습니다. 축, 격자 선 및 축 레이블은 선택 사항입니다. 소수의 마커 만 필요합니다.

    N = 12의 출력 예 는 다음과 같습니다 (위의 스케치와 비교). 두 번째 줄거리는 N = 10000에 해당하는 더 흥미로운 예 입니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

  1. 위에서 알려진 이미지 형식 (예 : png, tiff, bmp) 으로 이미지 파일 을 생성하십시오.
  2. 같은 행에서 숫자 위치를 구분하기위한 공백과 함께 소수와 소수를위한 공백을 선택한 소수 자릿수를 사용하여 나선을 ASCII art 로 표시합니다 . 선행 또는 후행 공백 또는 줄 바꿈이 허용됩니다. 예를 들어, 문자로 사용 하는 N = 12의 경우o

                 o
                · ·
               · o ·
                o · ·
               · o · o
    

    물론 o소수 의 마크 만 실제로 표시됩니다. 기본 ·이 아닌 at는 참조 용으로 여기에 표시됩니다.

승리 기준

실제 보상은 놀라운 패턴 코드 골프, 가장 짧은 코드 승리 를 직접 보는 것입니다 .


2
앞으로는 [그래픽 출력]과 [아스키 아트] 중 하나만 선택하여 제출물을 비교할 수 없도록하는 것이 좋습니다. 그러나 어쨌든 좋은 도전. :)
— Alex A.

@AlexA. 감사! 나는 그것을 고려할 것이다. 줄리아가 대답할까요? ;-)
— Luis Mendo 2016 년

와우, 현상금에 감사드립니다, 그러나 당신은 당신의 자신의 대답을 받아 들여야합니다. 그것은 이다 짧은. :)
— Martin Ender

그것은 가치가있다! 답변을 받아들이는 것에 대한 도전 규칙 중 하나는 "나 자신의 답변을 받아들이지 않겠다"였습니다. 나는이 문제를 생각하면이 조금 :-) 부정 행위 같았다 그래서 필연적으로, 복잡한 번호 및 그래픽 기능을 염두에 MATL했다
— 루이스 Mendo

답변:


13

CJam, 49 42 바이트

Lri{)mp0S?}%{1$,)/(a@Wf%z+\L*}h;eeSff*W%N*

STDIN에서 단일 정수로 입력하십시오. 0소수 를 위한 ASCII 그리드로 출력합니다 . 나선의 회전은 일정하지 않습니다. 가장 많은 수의 나선이 항상 맨 아래 줄에 있습니다.

여기에서 테스트하십시오.

설명

기본 아이디어는 계산하는 동안 삼각형을 울퉁불퉁 한 2D 배열로 나타내는 것입니다. 선을 뒤집고 모든 행을 왼쪽에 정렬 하여이 배열을 얻습니다.

   4
  5 3
 6 1 2
7 8 9 A

로 표현 될 것이다

[[7 8 9 A]
 [6 1 2]
 [5 3]
 [4]]

선을 대칭 시켰으므로 시계 방향 으로 나선을 굴 리려고 합니다. 편리합니다. 삼각형을 시계 반대 방향으로 돌리고 다음 하위 목록을 순서대로 추가하기 만하면됩니다. 모든 줄을 뒤집어 바꾸어 거친 배열을 회전시킬 수 있습니다.

                                                           [[B C D E F]
[[7 8 9 A]         [[A 9 8 7]           [[A 2 3 4]          [A 2 3 4]
 [6 1 2]   reverse  [2 1 6]   transpose  [9 1 5]   prepend  [9 1 5]
 [5 3]      ---->   [3 5]      ------>   [8 6]      ---->   [8 6]
 [4]]               [4]]                 [7]]               [7]]

여기 코드가 있습니다. 내가 주목하고 싶은 세부 사항은 삼각형 레이아웃을 만드는 마지막 비트입니다. 나는 그것이 다소 근사하다고 생각합니다. :)

L     e# Push an empty array. This will become the spiral.
ri    e# Read input and convert to integer N.
{     e# Map this block over 0 to N-1...
  )   e#   Increment to get 1 to N.
  mp  e#   Test for primality.
  0S? e#   Select 0 or a space correspondingly.
}%
{     e# While the list we just created is not empty yet...
  1$  e#   Copy the spiral so far.
  ,)  e#   Get the number of lines and increment.
  /   e#   Split the list into chunks of that size.
  (a@ e#   Pull off the first chunk, wrap it in an array, pull up the spiral.
  Wf% e#   Reverse the lines of the spiral.
  z   e#   Transpose the spiral.
  +   e#   Prepend the new line.
  \L* e#   Swap with the remaining chunks and join them back together into a single list.
}h
;     e# Discard the empty list that's left on the stack.
ee    e# Enumerate the spiral. This turns each line into a pair of 0-based index
      e# and the line itself.
Sff*  e# Multiply each element of each pair with a space. For the enumeration index i,
      e# this produces a string of i spaces - the required indentation (keeping in
      e# mind that our spiral is still upside down). For the line itself, this
      e# riffles the cells with spaces, creating the required gaps between the cells.
      e# All of this works because we always end the spiral on the bottom edge.
      e# This ensures that the left edge is always complete, so we don't need
      e# different indentation such as in the N=12 example in the challenge.
W%    e# Reverse the lines to make the spiral point upwards.
N*    e# Join the lines with linefeeds.

1
네가 처음이 될 줄 알았어!
— Luis Mendo

@LuisMendo 그리드 인덱스 계산이 번거로울 것이라고 생각했기 때문에 실제로이 것을 건너 뛰려고했지만 선을 추가하면서 전체 삼각형을 회전시킬 수 있다는 것을 깨달았습니다.
— Martin Ender

1
CJam 프로그램에 대한 여러분의 설명을 항상 이해 하고 있습니다. 이해 하기 쉽기 때문에이 프로그램이 얼마나 복잡하고 짧은 지 놀랍습니다.
— ETHproductions

10

MATL , 48 36 바이트

:1-H*X^.5+Y[2j3/*YP*ZeYsG:Zp)'.'2$XG

사용 현재 버전 (9.3.0)를 .

온라인으로 사용해보십시오! 온라인 컴파일러가 그래픽 출력을 ASCII로 변환하는 방법을 모르지만 온라인 컴파일러에서 지원하는 Octave 기능 덕분에 대략적인 ASCII 플롯이 생성됩니다!

편집 (2016 년 4 월 4 일) : 기능 Y[이 k릴리스 13.0.0부터 이름이 바뀌 었습니다 . 온라인 컴파일러에 대한 링크는이 변경 사항을 통합하므로 코드를 테스트 할 수 있습니다.

예

>> matl
 > :1-H*X^.5+Y[2j3/*YP*ZeYsG:Zp)'.'2$XG
 > 
> 20000

그래픽 출력을 생성합니다 (MATLAB 버전 표시).

여기에 이미지 설명을 입력하십시오

설명

이 코드는 복소수를 사용하여 경로와 나선을 추적합니다. 도전 과제의 첫 번째 그림에서 볼 수 있듯이 나선형의 각 직선 다리는 길이가 1, 2, 3, 4 ...로 증가하고 방향이 120도, 240도, 0도, 120도를 증가시키는 세그먼트입니다. ..

코드는 먼저 각 정수에서 다음 정수까지 개별 복소 변위를 생성합니다. 이 복잡한 변위는 크기 1과 각도 2*pi/3를 4*pi/3갖거나0 (라디안)를. 따라서 그것들은 허수 지수로 쉽게 생성 될 수 있습니다. 이를 위해 정수 시퀀스 0,1,2,2,3,3,3,4,4,4,4 ...가 먼저 사용됩니다.

이 정수 시퀀스는 "n appear n times"시퀀스 ( OEIS A002024 )와 거의 같으며 0,1,2,3, ... 인 floor(sqrt(2*n)+.5)곳에서 얻을 수 있습니다 n. 에 의해 곱 2j*pi/3경우,j , 허수 단위이며 원하는 복잡한 변위를 생성한다.

나선의 정수에 해당하는 위치를 계산하기 위해 변위가 누적됩니다. 나선의 첫 번째 정수인 1,는 임의로 1복잡한 평면의 위치 에 있습니다 .

마지막으로, 비 프라임 숫자에 해당하는 위치는 버리고 나머지는 복소 평면에 그려집니다.

:1-H*X^.5+Y[     % floor(sqrt(2*n)+.5) for n from 0 to N-1, where N is implicit input
2j3/*YP*Ze       % exp(2j*pi/3* ... )
Ys               % cumulative sum. Produces complex positions
G:               % vector 1,2...,N, where N is previous input
Zp               % logical index to select only prime numbers
)                % use that index to keep only complex positions of primes
'.'2$XG          % plot using marker '.'

내가 더 읽어야 할 것
— Brain Guider

온라인으로 해보십시오! MATL에 대한 그래픽 출력을 지원합니까?
— Alex A.

TIO가 그래픽 출력을 지원하지 않는다고 생각 했습니까? 그렇다면 MATL이 이미지를 .png웹 페이지에 자동으로 파일로 덤프하여 @AlexA
— Luis Mendo가

이봐! 나는 간단한 테스트 ( plot(1:5))를했고 텍스트 그래픽 출력을 생성합니다! matl.tryitonline.net/#code=NTpYRw&input= @AlexA. 이건 어떻습니까??
— Luis Mendo

4
우와! 대단해!
— Alex A.

8

그리기로 완료해야합니다

LaTeX / PGF, 527 594 바이트

\documentclass{standalone}\usepackage{pgf}\let\z\let\z\e\advance\z\f\ifnum\z\h\the\z\a\newcount\a\i\a\j\a\l\a\x\a\y\a\p\a\q\a\n\i=1\l=1\p=-1\q=1\def\m#1{\e\i by1\e\j by1\e\x by\h\p\e\y by\h\q\pgfmathparse{isprime(\h\i)}\f\pgfmathresult=1\pgfpathcircle{\pgfpoint{\h\x cm}{\h\y cm}}3pt\fi\f\j=\l\e\l by1\j=0\f\p=1\p=-1\q=1\else\f\p=-1\p=0\q=-1\else\p=1\q=0\fi\fi\fi\f#1>0\e#1by-1\m#1\fi}\begin{document}\begin{pgfpicture}\pgftransformcm10{cos(60)}{sin(60)}\pgfpointorigin\n=4000\m\n\pgfusepath{fill}\end{pgfpicture}\end{document}

527 바이트는 위와 같이 전체 문서입니다. PDF 파일을 생성합니다.

기본 아이디어 : 글쎄, 그립니다. 삼각 격자에 행렬 변환 을 사용 합니다 . 유일한 문제는 점들이 변환에 의해 영향을 받고 확장된다는 것입니다. 그래서 나는 타원 마커를 선택합니다 :) 그 의미는 두 번째 이미지 (n = 250, 5pt)에서 분명합니다.

또 다른 경고 : TeX의 최대 스택 크기 때문에 5000 미만의 비트 만 처리 할 수 ​​있습니다. 첫 번째 이미지는 n = 4000입니다. 분명히 스택 크기를 늘릴 수 있습니다 는 있지만 시도하지 않았습니다.

PGF를 사용합니다 isprime().

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

언 골프 드 :

\documentclass[border=10cm]{standalone}

\usepackage{pgf}

\newcount\ulami
\newcount\ulamj
\newcount\ulamlen

\newcount\ulamx
\newcount\ulamy
\newcount\ulamdx
\newcount\ulamdy

\ulami=1 %
\ulamj=0 %
\ulamlen=1 %
\ulamdx=-1 %
\ulamdy=1 %
\ulamx=0 %
\ulamy=0 %

\def\ulamplot#1{%
  \advance\ulami by 1 %
  \advance\ulamj by 1 %

  \advance\ulamx by \the\ulamdx %
  \advance\ulamy by \the\ulamdy %

  \pgfpathmoveto{\pgfpoint{\the\ulamx cm}{\the\ulamy cm}}

  \pgfmathparse{isprime(\the\ulami)}
  \let\r=\pgfmathresult
  \ifnum\r=1
    \pgfpathcircle{\pgfpoint{\the\ulamx cm}{\the\ulamy cm}}{5pt}
  \fi

  \ifnum\ulamj=\the\ulamlen %
    \advance\ulamlen by 1 %
    \ulamj=0 %
    \ifnum\ulamdx=1 %
      \ulamdx=-1 %
      \ulamdy=1 %
    \else%
      \ifnum\ulamdx=-1 %
        \ulamdx=0 %
        \ulamdy=-1 %
      \else%
        \ulamdx=1 %
        \ulamdy=0 %
      \fi
    \fi
  \fi

  \ifnum#1>0 %
    \advance#1 by -1 %
    \ulamplot{#1}%
  \fi
}

\begin{document}

\begin{pgfpicture}
  \pgfmathsetmacro{\x}{cos(60)}
  \pgfmathsetmacro{\y}{sin(60)}
  \pgftransformcm{1}{0}{\x}{\y}{\pgfpointorigin}

  \pgfpathmoveto{\pgfpointorigin}
  \color{blue}
  \newcount\ulamn
  \ulamn=400
  \ulamplot{\ulamn}
  \pgfusepath{stroke,fill}
\end{pgfpicture}

\end{document}

1
와우. LaTeX에서이 작업을 수행 한 적이 없었습니다.
— Luis Mendo

lualatex해당 주석을 올바르게 이해하면 동적으로 할당하는 컴파일러를 사용 하거나 스택 할당을 무시해야합니다. 따라서 답을 제한하는 것이 아니라 실행할 구현의 대부분입니다.
— Andras Deak

죄송합니다. 확인한 결과 입력 스택 크기 제한은 이전 의견에서 언급 한 메모리 할당과 관련이 없습니다. (
— Andras Deak

@AndrasDeak 괜찮습니다. 찾아 주셔서 감사합니다. 분명히 스택 크기를 늘리는 방법 을 찾았 지만 직접 시도하지는 않았습니다 (아직).

@ CamilStaps 덕분에 다른 유사한 게시물을 찾았지만 시도하지 않았습니다. 어쨌든, 나는 Christian Feuersänger의 게시물을 캐논으로 사용합니다 :)
— Andras Deak

2

수학, 94 바이트

ListPlot@Accumulate[Join@@Table[ReIm@Exp[2i Pi/3I],{i,2#^.5},{i}]][[Prime@Range@PrimePi@#-1]]&

결과

%[10000]

여기에 이미지 설명을 입력하십시오


2

파이썬, 263 바이트

파이썬에 익숙하지 않아서 개선의 여지가 있습니다 :)

from matplotlib.pyplot import*
from math import*
def f(m):
 s=[];X=[];Y=[];i=x=y=0
 while len(s)<m:i+=1;s+=[i%3*pi*2/3]*i
 for i in range(m):
  x+=cos(s[i]);y+=sin(s[i]);j=i+2
  if all(map(lambda a:j%a>=1,range(2,int(j**.5+1)))):X+=[x];Y+=[y]
 scatter(X,Y);show()

예:

f(100000)

여기에 이미지 설명을 입력하십시오


다음과 같이 단축 s=[];X=[];Y=[];i=1;x=0;y=0할 수 있습니다s=X=Y=[];i=1;x=y=0;
— rp.beltran

끝에 여분의 세미콜론을 무시하십시오. 8 바이트를 절약해야합니다.
— rp.beltran

@ rp.beltran. 작동하지 않습니다. 객체가 동일한 값을 공유한다는 사실과 관련이 있다고 생각합니다. 만 추가 할 수 있습니다 x=y=0.
— lambruscoAcido

내 나쁜, 당신 말이 맞아 파이썬이 목록을 참조로 전달하는 것을 잊었습니다. 숫자는 변경할 수 없으므로 정수로 처리하는 것이 안전합니다.
— rp.beltran

1

R, 137 바이트

소수에 대해서도 내장 함수 만 사용합니다. 반복 대신 벡터화 된 접근 방식을 사용하면 빠르지 만 많은 수를 처리 할 수 ​​없습니다.

골프 :

g=function(m){M=1:m;s=rep(M,M)[M]%%3*pi*2/3;k=cumsum;j=sapply(seq(s)+1,function(n)n<4|all(n%%2:n^.5>=1));plot(k(cos(s))[j],k(sin(s))[j])}

언 골프 드 :

g=function(m) {
  M = 1:m
  s = rep(M,M)[M] %% 3 * pi * 2/3
  k=cumsum
  j=sapply(seq(s)+1,function(n)n<4|all(n%%2:n^.5>=1)) # primes
  plot(k(cos(s))[j],k(sin(s))[j])    # cumulated coordinates
}

예:

g(10000)

여기에 이미지 설명을 입력하십시오


예제 결과를 추가 할 수 있습니까?
— Luis Mendo

@LuisMendo. 확실한. 플롯을 추가하는 방법 만 알아 내야했습니다.
— lambruscoAcido
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.