아리스토텔레스의 수 문제 해결


21

아리스토텔레스의 숫자 퍼즐은 각 축을 따라 총계가 38이되도록 1에서 19 사이의 고유 한 정수로 육각 격자에 19 개의 각 셀을 채우는 것입니다.

다음과 같이 게임 보드를 그릴 수 있습니다.

아리스토텔레스 그리드

그리고 퍼즐은 본질적으로 다음 15 가지 방정식 세트에 대한 솔루션입니다.

((a + b + c) == 38 && (d + e + f + g) == 38 && (h + i + j + k + l) == 
   38 && (m + n + o + p) == 38 && (q + r + s) == 38 && (a + d + h) == 
   38 && (b + e + i + m) == 38 && (c + f + j + n + q) == 
   38 && (g + k + o + r) == 38 && (l + p + s) == 38 && (c + g + l) == 
   38 && (b + f + k + p) == 38 && (a + e + j + o + s) == 
   38 && (d + i + n + r) == 38 && (h + m + q) == 38)

여기서 각 변수는 세트에서 고유 한 숫자입니다 {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}.

여러 가지 가능한 솔루션이 있으며 19!정수 조합 이 가능하므로 순진한 무차별 대입은 비실용적입니다.

규칙 :

  1. 답을 하드 코딩하거나 다른 곳에서 답을 찾지 마십시오. 코드는 자체적으로 코드를 찾아야합니다
  2. 속도는 중요하지 않지만 결과를 표시해야하므로 1000 년이 걸리는 코드는 도움이되지 않습니다.
  3. 모든 답변 찾기
  4. 로테이션에서 동일한 답변을 동일한 것으로 취급
  5. 매력적인 벌집으로 결과를 출력하면 총 바이트 수의 5 %를 공제하십시오.
  6. 가장 적은 바이트가 이깁니다

그것에 대한 해결책을 기대하고 좋은 질문입니다.
ProgrammerDan

순환 답변을 독창적 인 것으로 생각하십니까? 예를 들어, a, b, c = 1, 18, 19가 특정 솔루션을 색인한다고 가정하고 c, g, l = 1, 18, 19를 설정하고 다른 모든 값이 일치하도록 "회전"하면이 값을 고유 한 것으로 간주합니까 해결책?
ProgrammerDan

@ProgrammerDan 회전 된 답변은 동일합니다. 나는 명확히 할 것이다.
Michael Stern

1
육각형은 단순한 회전보다 대칭이 더 많습니다. 회전과 반사의 조합에서 동일한 답변은 어떻습니까?
피터 테일러

자체 구성 맵을 사용하여이 솔루션에 대한 솔루션을보고 싶습니다.
Ant P

답변:


3

하스켈 295 289

import Data.List
t=38
y a b=[max(19-b)(a+1)..19]
w=y 0 t
x=filter((==w).sort)$[[a,b,c,d,e,f,g,h,i,t-a-e-o-s,k,l,m,t-d-i-r,o,p,q,r,s]|a<-[1..14],c<-y a a,l<-y a c,s<-y a l,q<-y a s,h<-y c q,e<-w,let{f=t-g-e-d;i=t-b-e-m;o=t-r-k-g;k=t-p-f-b;b=t-a-c;g=t-l-c;p=t-l-s;r=t-q-s;m=t-q-h;d=t-a-h}]

산술을 사용하여 중간 헥스를 얻는 또 다른 비슷한 대답. 다른 솔루션과 달리, 합이> 0 인 합계는 테스트하지 않고 정렬 된 육각형이 [1..19] 범위와 동일한 지 테스트합니다. a, c 및 h는 고유 한 회전 / 미러링 솔루션 만 허용되도록 제한됩니다. 몇 초 후에 솔루션이 나타난 다음 1 분 정도 기다렸다가 더 이상 없다고 결정합니다.

ghci 사용법 :

ghci> x
[[3,19,16,17,7,2,12,18,1,5,4,10,11,6,8,13,9,14,15]]

몇 글자를 면도하도록 수정되었습니다. 'y 0 t'는 [1..19]를 생성합니다.


1
실제로 나는 내 C 답변에서 같은 일을하고있다 :) 젠장 Haskell이 작업을위한 완벽한 도구라는 것을 어떻게 알 수 없습니까 : P +1
Niklas B.

x>0배열을 증가시키는 대신 음수를 포함하여 목록을 정렬하기 때문에 수표 를 놓칠 수 있습니까? 반면에, y a bHaskell이 수행하도록 범위 (my )를 제한해야 하므로 몇 가지 문자가 필요합니다. 그러나 내장 언어가 내장되어있어 똑같은 방식으로 일하는 것을 이길 수있는 다른 언어가 있습니다 (Mathematica).
bazzargh

예, 불행히도 C로 정렬하는 것은 Haskell만큼 간단하지 않습니다. Mathematica의 문제점은 컴파일되지 않아서 너무 느리다는 것입니다. (
Niklas B.

나는 다른 언어가 더 좋을지라도 항상 Haskell에서 연습을 위해 이것을합니다.
bazzargh

나는 실제로 하스켈을 부업으로 프로그램하기 때문에 여기서 사용하지도 않을 것입니다. : D 실제 / 불순한 세상에서도 정말 위대한 언어입니다
Niklas B.

10

자바 (1517-75.85) = 1441.15 ( 1429-71.45) = 1357.55 (1325-66.25 ) = 1258.75

재미있었습니다.

쾌적한 벌집 모양으로 모든 독특한 솔루션을 미러링 및 회전 인쇄 (따라서 5 % 감소)

런타임 : 4 년 된 랩톱에서 ~ 0.122 초 (122 밀리 초)

Golfed 코드 ( 편집 , 내가 바보 내 printfs을 반복 깨달았다 최대 골프에 대해 하나의 printf로 감소) ( 새 편집 영리한 작은 기능, 다른 마이크로 최적화로 설정 함수를 호출 감소)

import java.util.*;class A{boolean c(Set<Integer>u,int z){return!u.contains(z);}Set<Integer>b(Set<Integer>c,int...v){Set<Integer>q=new HashSet<Integer>(c);for(int x:v)q.add(x);return q;}void w(){Set<Integer>U,t,u,v,w,y,z;int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,X,Z;X=20;Z=38;for(a=1;a<X;a++)for(b=1;b<X;b++)if(b!=a)for(c=1;c<X;c++)if(c!=a&&c!=b&&a+b+c==Z){U=b(new HashSet<Integer>(),a,b,c);for(d=1;d<X;d++)if(c(U,d))for(h=1;h<X;h++)if(h!=d&&c(U,h)&&a+d+h==Z){t=b(U,a,b,c,d,h);for(m=1;m<X;m++)if(c(t,m))for(q=1;q<X;q++)if(q!=m&&c(t,q)&&h+m+q==Z){u=b(t,m,q);for(r=1;r<X;r++)if(c(u,r))for(s=1;s<X;s++)if(s!=r&&c(u,s)&&q+r+s==Z){v=b(u,r,s);for(p=1;p<X;p++)if(c(v,p))for(l=1;l<X;l++)if(l!=p&&c(v,l)&&s+p+l==Z){w=b(v,p,l);for(g=1;g<X;g++)if(c(w,g)&&l+g+c==Z)for(e=1;e<X;e++)if(e!=g&&c(w,e))for(f=1;f<X;f++)if(f!=e&&f!=g&&c(w,f)&&d+e+f+g==Z){y=b(w,g,e,f);for(i=1;i<X;i++)if(c(y,i))for(n=1;n<X;n++)if(n!=i&&c(y,n)&&d+i+n+r==Z&&b+e+i+m==Z){z=b(y,i,n);for(o=1;o<X;o++)if(c(z,o))for(k=1;k<X;k++)if(k!=o&&c(z,k)&&m+n+o+p==Z&&r+o+k+g==Z&&b+f+k+p==Z)for(j=1;j<X;j++)if(c(z,j)&&j!=o&&j!=k&&a+e+j+o+s==Z&&c+f+j+n+q==Z&&h+i+j+k+l==Z){System.out.printf("%6d%4d%4d\n\n%4d%4d%4d%4d\n\n%2d%4d%4d%4d%4d\n\n%4d%4d%4d%4d\n\n%6d%4d%4d\n\n",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s);return;}}}}}}}}}public static void main(String[]a){(new A()).w();}}

무차별 대입은지나 갔지만 아주 작은 솔루션 집합 만 존재한다는 사실을 현명하게 사용하면 반복 기반의 대답으로 이어졌습니다. 반복의 각 루프 내에서 아직 "할당되지 않은"정수만 고려합니다. Java의 HashSet을 사용하여 이전에 사용한 숫자에 대한 O (1) 조회를 얻습니다. 마지막으로 정확히 12 개의 솔루션이 있지만 회전과 미러링을 모두 할인하면 하나의 고유 한 솔루션으로 축소되므로 첫 번째 솔루션이 발견되면 인쇄하여 종료합니다. 이 솔루션에 어떻게 접근하고 있는지 좀 더 명확하게 보려면 github에서 덜 골프 한 코드를 확인하십시오 .

즐겨!


글쎄, 당신은 스포일러에 거짓말을하고, 더 많은 해결책이 있기 때문에, 당신의 대답은 유효하지 않습니다.
ST3

강력한 주장, 당신은 그것을 증명하기 위해 자신의 답변으로 백업 할 수 있습니까? 나는 내 스포일러에 의도적 인 거짓말이 있는지 확실히 모른다.
ProgrammerDan

첫 번째 해결책이 발견되면 인쇄하고 규칙 번호를 종료 합니다. 3은 모든 답을 찾도록 지시합니다. OP가 말한 것처럼 19가 실제로 19인지 확실하지 않지만 이전에 비슷한 작업을 수행 했으므로 하나 이상이 있음을 알고 있습니다.
ST3

스포일러 전체 를 읽어야 합니다. 12 가지 해결책을 찾았습니다. 그런 다음 질문에 첨부 된 전체 의견 을 읽어야합니다 . OP는 WRT 회전과 동일한 답변은 동일하므로 건너 뛰어야한다고 말합니다. 다른 사람이 같은 WRT 미러링에 대한 답변을 건너 뛸지 물었습니다. OP가이 쿼리에 응답하지 않았지만 현재까지의 다른 솔루션은 모두 "예"라고 가정합니다. 따라서 내 솔루션은 완벽하고 완전하며 여기에 "거짓말"이 없습니다. 그러나 12 가지 솔루션을 모두 보려면 return;명령문을 제거하십시오 .
ProgrammerDan

마지막으로 이것은 코드 골프입니다. 임의의 return;명령문을 추가하면 코드 길이가 7 증가한다는 사실을 고려하면 진정한 대답에 단순히 서로 회전 / 미러링 된 12 가지 솔루션이 모두 포함되어 있으면 추가 할 수 없습니다. 정신 이상을 배제 할 수는 없지만,이 경우 추가 return;는 의도적 인 것이며, 전체 질문 및 의견 대화 상자를 기반으로 설명 했듯이, 고발을하기 전에 검토해야합니다. 감사!
ProgrammerDan

8

C, 366 바이트 ( C ++ 541450 )

#define R(i)for(int i=19;i;--i)
#define X(x)if(x>0&&!V[x]++)
#define K(X)X(a)X(b)X(c)X(d)X(e)X(f)X(g)X(h)X(i)X(j)X(k)X(l)X(m)X(n)X(o)X(p)X(q)X(r)X(s)
Q(x){printf("%d ",x);}
T=38,V[99];main(){R(h)R(c)R(s)R(a)R(l)R(q)R(e){int d=T-a-h,b=T-a-c,g=T-c-l,p=T-l-s,r=T-q-s,m=T-h-q,f=T-g-e-d,i=T-b-e-m,n=T-d-i-r,o=T-p-n-m,k=T-g-o-r,j=T-h-i-k-l;R(C)V[C]=0;K(X)K(+Q),exit(0);}}

로 컴파일하십시오 gcc -std=c99 -O3.

모든 고유 솔루션 모듈로 회전 및 미러링을 a b c d ...한 줄에 하나씩 형식으로 인쇄합니다 .

런타임 : 컴퓨터에서 0.8 초

최대 정리 성을 위해 h-> c-> s-> a-> l-> q-> e 순서로 셀을 열거합니다. 실제로 위의 버전은 해당 변수에 대해 20 ^ 7 할당마다 시도합니다. 그런 다음 다른 모든 셀을 계산할 수 있습니다. 유일한 솔루션 모듈로 회전 / 미러링이 있습니다. 이전 덜 C ++ 버전 (때문에 가지 치기에) golfed과 ~ 20 배 더 빠르게 찾을 수 있습니다 Github에서에


나는 여기서 주로 산술 접근법을 좋아합니다. 브라보! +1
ProgrammerDan

1

MATLAB : 333 320 자

이것은 재귀를 사용하지 않는 꽤 벙어리 근사한 힘입니다. 에 부분 솔루션이 빌드되어 z끝에 인쇄됩니다. 각 열은 솔루션입니다. 요소는 위에서 아래로 나열됩니다. 런타임은 1-2 시간입니다.

z=[];
a='abc adh hmq qrs spl lgc defg beim mnop dinr rokg pkfb hijkl aejos cfjnq';while a[k,a]=strtok(a);n=length(k);x=nchoosek(1:19,n)';s=[];for t=x(:,sum(x)==38)s=[s,perms(t)'];end
m=0.*s;m(19,:)=0;m(k(1:n)-96,:)=s(1:n,:);y=[];for p=m for w=z m=[];l=w.*p~=0;if p(l)==w(l) y(:,end+1)=w+p.*(~l);end
end
end
z=[m,y];end
z

Matlab 내에서 실행 :

>> aristotle;
>> z(:,1)

ans =

    9
   11
   18
   14
    6
    1
   17
   15
    8
    5
    7
    3
   13
    4
    2
   19
   10
   12
   16
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.