독특한 곱셈 나선


13

이것은 Calvin 's Hobbies 최근 곱셈 테이블 도전 에서 영감을 받았습니다 .

정수 N를 입력으로 사용하고 NxN 고유 곱셈 나선을 인쇄하거나 반환 하는 함수 또는 프로그램을 작성하십시오 . 코드는 이론적으로 0에서 1000 사이의 N에 대해 작동해야합니다 (출력이 어려울 수 있음). 출력은 다음 절차에 따라 생성 된 테이블과 동일해야합니다.

  1. NxN 곱셈표를 작성하십시오. 예를 들어 N = 3 :

    1 2 3
    2 4 6
    3 6 9
    
  2. 왼쪽 상단에서 시계 방향으로 나선을 따라 방문한 숫자를 적어 둡니다. 이미 방문한 번호를 방문하면 0으로 바꾸십시오.

몇 가지 예가 더 명확해질 수 있습니다.

n = 0:
0

n = 1:
1

n = 2:       //   Spiral order:
1  2         //   1  2
0  4         //   4  3

n = 3:
1  2  3      //   1  2  3
0  4  6      //   8  9  4
0  0  9      //   7  6  5

n = 4:
1  2  3  4   //   1   2   3   4
0  0  6  8   //  12  13  14   5
0  0  9 12   //  11  16  15   6
0  0  0 16   //  10   9   8   7

n = 5:
1   2   3   4   5
0   0   6   8  10
0   0   9  12  15
0   0   0  16  20
0   0   0   0  25

n = 10:
1   2   3   4   5   6   7   8   9  10
0   0   0   0   0  12  14  16  18  20
0   0   0   0  15   0  21  24  27  30
0   0   0   0   0   0  28  32  36  40
0   0   0   0  25   0  35   0  45  50
0   0   0   0   0   0  42  48  54  60
0   0   0   0   0   0  49  56  63  70
0   0   0   0   0   0   0  64  72  80
0   0   0   0   0   0   0   0  81  90
0   0   0   0   0   0   0   0   0 100

숫자는 다음과 같습니다.

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

합리적인 출력 형식이 허용되지만 N-N-N 행렬이어야하며 목록 일 수는 없습니다. N을 쉽게 구별 할 수있는 1xN 열 또는 Nx1 행이 있으므로 아래와 같은 형식이 허용됩니다.

[[1 2 3][0 4 6][0 0 9]]   <-- OK

[[1 0 0][2 4 0][3 6 9]]   <-- OK

ans =                     <-- OK
    1  2  3
    0  4  6
    0  0  9   

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


나는 작은 눈으로 eratosthenes의 수정 된 체를 감시합니다! 다른 곳에서 본 패턴을 사용할 수 있다고 확신합니다.
애디슨 크럼프

2
n=0곱셈 테이블에서 0이없는 곳에 출력이있는 이유는 무엇입니까? n=1출력 1을 이해할 수 있지만 왜 0을 포함합니까?
톰 카펜터

@TomCarpenter, 그것은 나쁜 결정 이었을지 모르지만, "N = 0은 어떻습니까?"라는 질문이 있다는 것을 알았으므로 N = 0-> 0 규칙을 만들었습니다. 돌이켜 보면 N> 0이라고 말하는 것이 더 좋았지 만 지금은 너무 늦었습니다. = /
Stewie Griffin

2
@StewieGriffin 출력은 NxN 행렬이어야하므로에 대한 출력은 0x0 행렬 n=0이어야합니다. 그렇지 않으면 질문이 일치하지 않습니다.
alephalpha

답변:



8

Mathematica 123122117 98 92 73 바이트

alephalpha에 의해 LegionMammal978 및 또 다른 19 덕분에 24 바이트가 절약되었습니다!


놀랍게도,이 표에서, 정수의 여러 인스턴스 n는 테이블 자체에서와 같이 나선형에서 동일한 상대 순서를 갖습니다! 숫자의 첫 번째 모양은 n테이블에서 해당 숫자가 가장 먼저 나타나는 셀에 있습니다 (행별로 테이블을 채울 때). 이것은 결과가 나선 구속 조건을 전혀 무시할 수 없음을 의미합니다. (아래 설명 참조)

ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&

ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&[10]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {0, 0, 0, 0, 0, 12, 14, 16, 18, 20}, {0, 0, 0, 0, 15, 0, 21, 24, 27, 30}, {0, 0, 0, 0, 0, 0, 28, 32, 36, 40}, {0, 0, 0, 0, 25, 0, 35, 0, 45, 50}, {0, 0, 0, 0, 0, 0, 42, 48, 54, 60}, {0, 0, 0, 0, 0, 0, 49, 56, 63, 70}, {0, 0, 0, 0, 0, 0, 0, 64, 72, 80}, {0, 0, 0, 0, 0, 0, 0, 0, 81, 90}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}}


Grid[%]

고음


설명

우리는 임의의 자릿수 n의 위치의 나선형 순서가 함수에 의해 반환 된 row-col 위치의 순서와 동일하다는 사실을 이용합니다 Positions.

각 숫자의 첫 번째 발생 위치 (나선형 또는 테이블 위치 별 순서에 관계없이)는로 반환 된 첫 번째 요소 Position입니다. 첫 번째 발생 셀은 그대로 남아 있습니다. 숫자의 나머지 인스턴스는 0으로 대체됩니다.

이 경우 어떻게 작동하는지 살펴보고의 사례를 살펴 보겠습니다 n==18. 아이디어는 곱셈 테이블로 시작하는 것입니다.

(t = Table[k Range@#, {k, #}] &[10]) // Grid

각 번호의 행 열 위치를 찾으십시오. 예를 들어, 18은 열 2, 열 9 (첫 번째 인스턴스)에 있습니다. 3 열, 6 열; 6 열, 3 열; 및 9 행, Col 2를 포함한다. 이들은 각각의 나선 순서 위치를 갖는다 (44, 58, 68, 82}).

Position[t, 18]

{{2, 9}, {3, 6}, {6, 3}, {9, 2}}

다음 표와 같이.

표 2

18의 마지막 3 개 인스턴스는 0으로 교체해야합니다. 쉽게 볼 수 있도록 큰 굵은 파란색 0을 사용합니다.

ReplacePart[%, {{3, 6}, {6, 3}, {9, 2}} -> Style[0, {Blue, Bold, 16}]]// Grid

표 3


글을 쓰지 않는 이유가 Function있습니까?
LegionMammal978

1
중첩 된 순수 함수에 문제가 있었지만이 반복에는 필요하지 않습니다. 감사.
DavidC

줄 바꿈을 제외한 117 바이트를 계산합니다.
LegionMammal978


더 많은 골프 :ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&
alephalpha

2

파이썬, 99 95 90 89 87 81 바이트

골프 코드 :

n=range(1,input()+1);m=[]
for x in n:l=[(x*y,0)[x*y in m]for y in n];m+=l;print l

언 골프 드 :

n=range(1,input()+1);
m=[]
for x in n:
  l=[(x*y,0)[x*y in m]for y in n];
  m+=l;
  print l

산출:

10 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
[0, 0, 0, 0, 0, 12, 14, 16, 18, 20]
[0, 0, 0, 0, 15, 0, 21, 24, 27, 30] 
[0, 0, 0, 0, 0, 0, 28, 32, 36, 40]
[0, 0, 0, 0, 25, 0, 35, 0, 45, 50] 
[0, 0, 0, 0, 0, 0, 42, 48, 54, 60]
[0, 0, 0, 0, 0, 0, 49, 56, 63, 70] 
[0, 0, 0, 0, 0, 0, 0, 64, 72, 80]
[0, 0, 0, 0, 0, 0, 0, 0, 81, 90] 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 100]

입력 바이트 면도에 대한 고맙습니다 @valuah
CSᵠ

2

MATLAB, 96 88 87 86 79 바이트

이것은 79 바이트 코드이며 출력 예를 따릅니다 (특히 n = 0의 경우).

n=input('');m=+(n>0);for i=1:n;a=i*(1:i);for j=a;m(m==j)=0;end;m(1:i,i)=a;end;m

이것은 75 바이트이며 n = 0을 제외하고는 동일한 동작을 가지며 질문의 의미에 따라 빈 배열을 생성합니다 (N x N 배열 = 0 x 0 = 빈 배열).

n=input('');m=[];for i=1:n;a=i*(1:i);for j=a;m(m==j)=0;end;m(1:i,i)=a;end;m

이것은 Octave 에서도 작동합니다 . 여기에서 온라인으로 사용해 볼 수 있습니다 . 코드는 이미 'multspiral.m'이라는 파일로 추가되었습니다. 따라서 Octave 프롬프트에서 입력 multspiral하고 Enter를 누르십시오. 그런 다음 테이블 크기를 입력해야합니다 (예 : 4). 그러면 출력이 인쇄됩니다.


어떻게 작동합니까?

먼저 필요한 경우 입력 번호를받습니다 (예 : 6, 4 등).

n=input('');

그럼 우리를위한 경우를 처리 n=0하고 n=1-이 특별한 대우를 부여 그들은 내가 배열을 생성하기 위해 사용하고있는 규칙을 따르지 않는 두 가지로 -이 모호한에없는 경우 5 바이트가 짧아 질 수 실제로 n=0경우.

m=+(n>0);

그런 다음의 모든 값에 n>2대해 행렬이 올바른 크기로 커질 때까지 반복합니다.

for i=2:n;

사이에 세 개의 간단한 차이가 실제로 있습니다 nn+1모든이 n>=2. 이것들은:

  1. 새로운 열이 숫자를 포함하는 배열의 가장 오른쪽에 추가됩니다 n(1:n). 이것은 다음과 같이 쉽게 계산됩니다.

     a=i*(1:i);
    
  2. 새 열에 추가 될 요소는 항상 새 열보다 나선형으로 나중에 나오므로 기존 행렬에서 제거해야합니다 (0으로 설정). 새 열에있는 현재 행렬의 모든 요소를 ​​0으로 설정하기 위해 중첩 된 for 루프를 사용하여 제거됩니다.

    for j=a;
        m(m==j)=0;
    end;
    
  3. 새 열에있는 것을 제외한 모든 요소가 0이되는 가장 새로운 행 맨 아래가 있습니다. 의도적으로 생성 된 범위를 벗어난 인덱스로 인해 새 열이 추가되면 0으로 자동으로 채워집니다. MATLAB의 강력한 기능 중 하나는 특별한 처리없이 배열을 확장 할 수 있으므로 새 행과 열을 간단하게 추가 할 수 있다는 것입니다 와:

    m(1:i,i)=a;
    

마지막으로 우리는 for 루프의 끝을가집니다. 일단 도달하면 행렬 m에 출력이 포함됩니다. 출력 형식을 유연하게 사용할 수 m있으므로 세미콜론없이 새 줄로 표시함으로써 행렬이 표시됩니다.

end;
m

예를 들어 프로그램을 실행하면 숫자 10을 입력하면 다음과 같은 결과가 나타납니다.

m =
     1     2     3     4     5     6     7     8     9    10
     0     0     0     0     0    12    14    16    18    20
     0     0     0     0    15     0    21    24    27    30
     0     0     0     0     0     0    28    32    36    40
     0     0     0     0    25     0    35     0    45    50
     0     0     0     0     0     0    42    48    54    60
     0     0     0     0     0     0    49    56    63    70
     0     0     0     0     0     0     0    64    72    80
     0     0     0     0     0     0     0     0    81    90
     0     0     0     0     0     0     0     0     0   100

1

하스켈, 103 99 바이트

import Data.Lists
f 0=[[0]]
f n=chunksOf n$foldr(\c d->c:replace[c][0]d)[][a*b|a<-[1..n],b<-[1..n]]

사용 예 : f 4-> [[1,2,3,4],[0,0,6,8],[0,0,9,12],[0,0,0,16]].

난 그냥 발견 한 Data.Lists목록 (예에 좋은 기능을 가지고 모듈 replace) 및 재수출을 Data.List, Data.List.Split하고 Data.List.Extras.


1

루비, 67 63 61 바이트

->n{s,x=1..n,{};s.map{|c|s.map{|r|x[v=c*r]==1?0:(x[v]=1;v)}}}

63 바이트

->n{s,x=1..n,{};s.map{|c|s.map{|r|e=x[v=c*r]==1?0:v;x[v]=1;e}}}

67 바이트

->n{s,x=1..n,[];s.map{|c|s.map{|r|e=x.include?(v=c*r)?0:v;x<<v;e}}}

용법:

->n{s,x=1..n,{};s.map{|c|s.map{|r|x[v=c*r]==1?0:(x[v]=1;v)}}}[10]
=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 0, 0, 0, 0, 12, 14, 16, 18, 20], [0, 0, 0, 0, 15, 0, 21, 24, 27, 30], [0, 0, 0, 0, 0, 0, 28, 32, 36, 40], [0, 0, 0, 0, 25, 0, 35, 0, 45, 50], [0, 0, 0, 0, 0, 0, 42, 48, 54, 60], [0, 0, 0, 0, 0, 0, 49, 56, 63, 70], [0, 0, 0, 0, 0, 0, 0, 64, 72, 80], [0, 0, 0, 0, 0, 0, 0, 0, 81, 90], [0, 0, 0, 0, 0, 0, 0, 0, 0, 100]]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.