원점에 가까운 삼각 격자 점


34

배경

삼각 격자 사진 아래 삼각 격자의 예는 측면 길이 1의 정삼각형 정기적 평면 타일링함으로써 형성된 격자이다.

삼각 격자 점은 삼각 격자를 형성하는 삼각형의 정점이다.

기원은 삼각 격자 점 중 하나 인면에 고정 된 점이다.

도전

음수가 아닌 정수가 주어지면 n원점으로부터의 유클리드 거리가보다 작거나 같은 삼각 격자 점의 수를 찾으십시오 n.

다음 그림은 예입니다 n = 7(편의를 위해 60도 영역 만 표시하고 점 A가 원점 인 경우).

테스트 사례

Input | Output
---------------
    0 |       1
    1 |       7
    2 |      19
    3 |      37
    4 |      61
    5 |      91
    6 |     127
    7 |     187
    8 |     241
    9 |     301
   10 |     367
   11 |     439
   12 |     517
   13 |     613
   14 |     721
   15 |     823
   16 |     931
   17 |    1045
   18 |    1165
   19 |    1303
   20 |    1459
   40 |    5815
   60 |   13057
   80 |   23233
  100 |   36295
  200 |  145051
  500 |  906901
 1000 | 3627559

힌트 :이 순서는 OEIS A003215아닙니다 .

규칙

대한 표준 규칙이 적용됩니다. 최단 제출이 이깁니다.

제출시 문제를 해결 한 방법을 포함하십시오.


7
OEIS A053416 은 반지름 아닌 지름 의 원에 포함 된 포인트 수의 시퀀스이므로 원하는 수의 n두 배입니다.
Neil

관련 위키 백과매스 월드 . xnor의 공식을 포함하고 증거가 아닙니다.
user202729

4
OEIS A004016 의 첫 번째 n^2+1항의 합계입니다 .
alephalpha

답변:


49

파이썬 2 , 43 바이트

f=lambda n,a=1:n*n<a/3or n*n/a*6-f(n,a+a%3)

온라인으로 사용해보십시오!

이것은 흑 마법입니다.

서면 증명을 위해 250 명의 담당자제공합니다 . 증거와 설명은Lynn의 답변을참조하십시오.


7
이것은 어떻게 작동합니까? 나는 좋은 30 분 동안 궁금해 왔습니다 ... 너무 단순 해 보이지만 재귀와 원 사이의 관계를 찾을 수 없습니다 ...
JungHwan Min

7
@JungHwanMin 내 증거는 평면 형상, 아이젠 슈타인 정수, 숫자 필드에 대한 인수 분해, 2 차 가역성, 산술 진행 및 교환 합계를 통한 서사시 여행입니다. 이 모든 것을 작성하는 것은 현재로서는 시간이없는 주요 사업이 될 것이므로 다른 누군가가 증거를 줄 것으로 기대하고 있습니다.
xnor

14
증거 . 이것은 Lynn보다 길지만 더 독립적입니다. Eisenstein 정수에 대한 인수 분해에 대한 검증되지 않은 주장을 사용하지 않습니다.
피터 테일러

2
@PeterTaylor 체다 스님? 다스와 드로이드처럼?

3
@Neil, 최초의 사람이 된 것을 축하합니다! 나는 아카데미에서 레벨 1 협상을위한 협상 칩으로 사용하기 위해 도메인을 등록했습니다.
피터 테일러

30

하스켈 , 48 바이트

f n=1+6*sum[(mod(i+1)3-1)*div(n^2)i|i<-[1..n^2]]

온라인으로 사용해보십시오!

xnor의 "black magic"공식을 사용합니다.

f(n)=1+6a=0n23a+1n23a+2

정확성에 대한 증거와 xnor가 43 바이트의 Python으로이를 표현하는 방법에 대한 설명은 여기를 참조하십시오 .

긴 이야기 짧은 우리가 계산 Eisenstein의 정수 규범 , 인수 분해에 의해 로 에이젠슈테인의 소수 및 계수 개수 솔루션 인수 분해에서 나옵니다. 우리는 솔루션의 수를1Nn2N=(x+yω)(x+yω)(x,y)

6×((# of divisors of N1 (mod 3))(# of divisors of N2 (mod 3)))

에서 사이의 모든 정수 를 한 번에 쉽게 계산할 수 있도록 영리한 트릭을 적용하십시오 . 이것은 위의 공식을 산출합니다. 마지막으로, 파이썬 골프 매직을 적용하여 xnor에서 찾은 아주 작은 솔루션으로 끝납니다.N 21n2


4
xnor가 "문제를 골라내는 데에는 몇 가지 깊이있는 수학적 통찰력이있다"고 말했을 때 나는 이것을 확실히 기대하지 않았다.
버블 러

29

Wolfram Language (Mathematica) , 53 51 50 바이트

@ 마일 덕분에 -1 바이트

Sum[Boole[x(x+y)+y^2<=#^2],{x,-2#,2#},{y,-2#,2#}]&

온라인으로 사용해보십시오!

어떻게?

이것을 생각하는 대신 :

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

다음과 같이 생각하십시오.

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

[[sqrt(3)/2, 0], [1/2, 1]]변환 행렬 을 적용하여 두 번째 숫자를 첫 번째 숫자로 변환합니다.

그런 다음 직교 좌표로 삼각형 격자에서 원을 찾아야합니다.

(sqrt(3)/2 x)^2 + (1/2 x + y)^2 = x^2 + x y + y^2

격자 점 x, yx^2 + x y + y^2 <= r^2

예를 들면 다음과 r = 3같습니다.

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


1
참고로, 공식 x^2+x y+y^2은 120 도의 코사인 법칙 에서 파생 될 수도 있습니다 .
Bubbler

3
x^2+x y+y^2-> x(x+y)+y^2바이트를 저장합니다
마일

공식 x^2 + xy + y^2은 또한 Eistenstein 정수의 표준에서 파생 될 수 있습니다 a^2 - ab + b^2. 부호를 제외 a하고 b는 부호가 ab같으므로 솔루션의 양이 같습니다.
orlp


7

CJam (24 바이트)

{_*_,f{)_)3%(@@/*}1b6*)}

이것은 익명 블록 (함수)으로 스택에서 하나의 인수를 취하고 결과를 스택에 남겨 둡니다. 온라인 테스트 스위트 . 가장 큰 두 가지 경우가 너무 느립니다.

설명

alephalpha 는 그 질문에 대한 주석에서

OEIS A004016 의 첫 번째 n ^ 2 + 1 항의 합입니다

XNOR의 응답 구현이 합 (난 아니지만 반드시 그 게시되지 증명 사용 여부를 명시 적으로)와 같은

f(n)=1+6a=0n23a+1n23a+2

이 공식의 정확성에 대한 나의 증거는 alephalpha의 OEIS 링크에서 수집 한 일부 정보를 기반으로합니다.

Gf : 1 + 6 * Sum_ {n> = 1} x ^ (3 * n-2) / (1-x ^ (3 * n-2))-x ^ (3 * n-1) / (1- x ^ (3 * n-1)). -Paul D. Hanna, 2011 년 7 월 3 일

관련 참조는 Hirschhorn의 논문입니다. 기본적인 증거는 복소수 (입방근의 근, 크기), 함수 생성의 개념, 의 미분, 미분의 연쇄 법칙에 대한 기본적인 이해 . 요약하면, 먼저 Jacobi의 삼중 제품 정체성 그러면 여기서 는 기본의 기본 큐브 루트입니다. 마지막 큰 단계는 이것을 사용하여xa

k=0(1qk+1)(1+xqk+1)(1+x1qk)=kZqk(k+1)/2xk
m,nZωmnqm2+mn+n2=k=1(1qk)31q3k
ω
m,nZqm2+mn+n2=1+6k0(q3k+11q3k+1q3k+21q3k+2)

코드 해부

{          e# Define a block. Stack: ... r
  _*       e#   Square it
  _,f{     e#   Map with parameter: invokes block for (r^2, 0), (r^2, 1), ... (r^2, r^2-1)
    )      e#     Increment second parameter. Stack: ... r^2 x with 1 <= x <= r^2
    _)3%(  e#     Duplicate x and map to whichever of 0, 1, -1 is equal to it (mod 3)
    @@/*   e#     Evaluate (r^2 / x) * (x mod 3)
  }
  1b6*     e#   Sum and multiply by 6
  )        e#   Increment to count the point at the origin
}

4

J , 27 바이트

[:+/@,*:>:(*++&*:)"{~@i:@+:

온라인으로 사용해보십시오!

JungHwan Min의 방법을 기반으로 합니다.

설명

[:+/@,*:>:(*++&*:)"{~@i:@+:  Input: n
                         +:  Double
                      i:     Range [-2n .. 2n]
                  "{~        For each pair (x, y)
                *:             Square both x and y
              +                Add x^2 and y^2
             +                 Plus
            *                  Product of x and y
        >:                   Less than or equal to
      *:                     Square of n
     ,                       Flatten
  +/                         Reduce by addition



3

젤리 ,  15  13 바이트

Dennis 덕분에 -2 (제로의 연결을 피하기 위해 제곱을 늘리십시오. 차이가 아닌 슬라이스 후 포스트 모듈로 슬라이스를 사용하여 머리를 피하십시오)

파이썬 응답 에서 xnor에 의해 노출 된 답변에 honing하는 "black magic"방법을 사용하지만 재귀보다는 반복을 사용합니다 (그리고 약간 적은 계산)

²:Ѐ‘$Im3S×6C

음이 아닌 정수를 받아들이고 양의 정수를 반환하는 모나드 링크.

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.

어떻게?

²:Ѐ‘$Im3S×6C - Main Link: non-negative integer, n     e.g. 7
²             - square                                     49
     $        - last two links as a monad:
    ‘         -   increment                                50
  Ѐ          -   map across (implicit range of) right with:
 :            -     integer division                       [49,24,16,12,9,8,7,6,5,4,4,4,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0]
      I       - incremental differences                    [-25,-8,-4,-3,-1,-1,-1,-1,-1,0,0,-1,0,0,0,-1,0,0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1]
       m3     - every third element                        [-25,-3,-1,0,0,-1,0,0,0,0,0,0,0,0,0,0,-1]
         S    - sum (vectorises)                           -31
          ×6  - multiply by six                           -186
            C - complement (1-X)                           187

2

자바 스크립트 (ES6), 65 바이트

이것은 @JungHwanMin의 솔루션 포트입니다 .

f=(n,y=x=w=n*2)=>y-~w&&(x*x+x*y+y*y<=n*n)+f(n,y-=--x<-w&&(x=w,1))

온라인으로 사용해보십시오!


원래 답변 (ES7), 70 바이트

그리드를 간단히 따라 가면서 일치하는 포인트를 계산합니다.

f=(n,y=x=n*=2)=>y+n+2&&(x*x*3+(y-x%2)**2<=n*n)+f(n,y-=--x<-n&&(x=n,2))

온라인으로 사용해보십시오!


xnor의 포팅은 더 짧습니다 : 42 바이트 ( 정수 나눔이라면; 46 true대신 출력 1; 46) 그리고 정수 분할을 골프화 할만큼 JavaScript를 잘 모르지만 ~~(a/b), 그것들을위한 더 짧은 방법이있을 것이라고 확신합니다.
Kevin Cruijssen


1

Pari / GP , 42 바이트

내장 사용 qfrep.

n->1+2*vecsum(Vec(qfrep([2,1;1,2],n^2,1)))

qfrep (q, B, {flag = 0}) : 완전하고 명확한 2 차 형태 q에 대해 1에서 B까지의 규범 벡터 수의 절반 인 벡터 플래그가 1이면 1에서 2B까지 짝수의 벡터를 계산합니다.

온라인으로 사용해보십시오!


0

C # (Visual C # 대화식 컴파일러) , 68 바이트

n=>{int g(int x,int y)=>x*x<y/3?1:x*x/y*6-g(x,y+y%3);return g(n,1);}

온라인으로 사용해보십시오!

불행히도 다른 사람들과 동일합니다. 나는 이것을 작성하는 더 좋은 방법이 있다는 것을 알고 있지만, C #에서 동시에 람다를 선언하고 호출하는 것은 내가하는 일이 아닙니다. 내 방어에는 있지만, 물론 그렇게하는 좋은 이유 (외부 코드 골프)는 생각할 수 없습니다. 그래도 누군가가 당신이 이것을 할 수있는 방법을 알고 있다면, 크레딧을 알려주거나 훔칠 수 있다고 생각합니다.



0

05AB1E , 15 바이트

nD>L÷¥ā3%ÏO6*±Ì

포트 @JonathanAllan 의 젤리 대답 차례로에서 파생, @ XNOR의 '블랙 매직'공식 .

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

n                # Square the (implicit) input-integer
 D>              # Duplicate it, and increase the copy by 1
   L             # Create a list in the range [1, input^2+1]
    ÷            # Integer divide input^2 by each of these integers
     ¥           # Take the deltas
      ā          # Push a list in the range [1, length] without popping the deltas itself
       3%        # Modulo each by 3
         Ï       # Only leave the values at the truthy (==1) indices
          O      # Take the sum of this list
           6*    # Multiply it by 6
             ±   # Take the bitwise NOT (-n-1)
              Ì  # And increase it by 2
                 # (after which the result is output implicitly)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.