{1,2,…, n}의 토폴로지 수를 계산하십시오.


9

직무

n매개 변수 / 입력으로 사용 되는 기능 / 프로그램을 작성 하고 세트에서 토폴로지 수 (아래에 설명 됨)를 인쇄 / 반환합니다 {1,2,...,n}.

토폴로지 정의

X를 유한 세트로 설정 하고 X 의 전력 세트 의 서브 세트 인 T (즉, X의 서브 세트를 포함하는 세트) 인 T가 다음 조건을 만족 한다고 가정하십시오 .

  1. X와 빈 세트 는 T에 있습니다.

  2. 두 세트 U와 V가 T에 있으면이 두 세트의 합집합 은 T에 있습니다.

  3. 두 세트 U와 V가 T에 있으면이 두 세트의 교집합 은 T에 있습니다.

... T는 X에서 토폴로지라고합니다.

명세서

  1. 귀하의 프로그램은 다음 중 하나입니다 :

    • n매개 변수로 받는 함수
    • 또는 입력하는 프로그램 n

    set의 (고유 한) 토폴로지 수를 인쇄하거나 반환합니다 {1,2,...,n}.

  2. n 11보다 작은 음이 아닌 정수이며 (물론 프로그램이 n보다 큰 n을 처리하는 경우 아무런 문제가 없습니다) 출력은 양의 정수입니다.

  3. 프로그램은 토폴로지 수를 직접 계산하는 모든 종류의 라이브러리 함수 나 기본 함수를 사용해서는 안됩니다.

입력 예 (n 값) : 7

출력 / 반환 예 : 9535241

여기 또는 여기 에서 반환 값을 확인할 수 있습니다 .

물론 가장 짧은 코드가 승리합니다.


우승자는 결정되지만 더 짧은 코드가 표시되면 우승자를 변경할 수 있습니다.


금세기에 결과를 제공해야합니까, 아니면 정확성의 증거로 충분합니까?
피터 테일러

@Peter 사실, 얼마나 오래 걸릴지 모르겠습니다. 따라서 프로그램의 정확성에 대한 증거는 충분하지만 여전히 n이 4 ~ 5와 같이 작 으면 프로그램은 적절한 시간을 제공해야합니다.
JiminP

@ JiminP, n = 12에 대해 계산하는 것이 그 당시의 종이 가치가 있었고 알려진 공식은 없습니다. 4 또는 5 동안 나는 그것이 몇 분 안에 무차별 적으로 가능하다고 생각합니다.
피터 테일러

2 ^ X의 부적절한 서브 세트도 토폴로지입니까?
FUZxxl 2016 년

@FUZxxl : 예. 나는 이것이 불연속 토폴로지 라고 생각합니다 .
JiminP 2016 년

답변:


4

하스켈, 144 자

import List
import Monad
p=filterM$const[True,False]
f n=sum[1|t<-p$p[1..n],let e=(`elem`t).sort,e[],e[1..n],all e$[union,intersect]`ap`t`ap`t]

사양의 거의 직접 구현, 모듈로 일부 모나드 마술.

에 대해 매우 느립니다 n > 4.


5

파이썬, 147 자

N=input()
S=lambda i,K:1+sum(0if len(set(j&k for k in K)-K)-1 else S(j+1,K|set(j|k for k in K))for j in range(i,2**N))
print S(1,set([0,2**N-1]))

N <= 6의 경우 빠르며 N = 7의 경우 느리며 N> = 8이 완료되지 않을 수 있습니다.

개별 세트는 정수 비트 마스크로, 토폴로지는 비트 마스크 세트로 표시됩니다. bitmasks> =로 세트를 S(i,K)시작 K하고 추가하여 형성 할 수있는 고유 한 토폴로지 수를 계산합니다 i.


0

Zsh, 83 자

이 솔루션은 요구 사항의 문자와 일치하지만 물론 정신은 아닙니다. 의심 할 여지없이 숫자를 더 많이 압축하는 방법이 있습니다.

a=(0 3 S 9U 5CT 4HO6 5ODFS AMOZQ1 T27JJPQ 36K023FKI HW0NJPW01R);echo $[1+36#$a[$1]]

-1

파이썬, 131 자

lambda n:sum(x&(x>>2**n-1)&all((~(x>>i&x>>j)|x>>(i|j)&x>>(i&j))&1 for i in range(2**n)for j in range(2**n))for x in range(2**2**n))

확장 버전 :

def f(n):
    count = 0
    for x in range(2**2**n): # for every set x of subsets of [n] = {1,...,n}
        try:
            assert x & 1 # {} is in x
            assert (x >> 2 ** n - 1) & 1 # [n] is in x
            for i in range(2**n): # for every subset i of [n]...
                if x >> i & 1: # ...in x
                    for j in range(2**n): # for every subset j of [n]...
                        if x >> j & 1: # ...in x
                            assert (x >> (i | j)) & 1 # their union is in x
                            assert (x >> (i & j)) & 1 # their intersection is in x
            count += 1
        except AssertionError:
            pass
    return count

예를 들어, n = 3이라고 가정합니다. [n]의 가능한 부분 집합은 다음과 같습니다.

0b000
0b001
0b010
0b011
0b100
0b101
0b110
0b111

여기서 i 번째 비트는 i가 서브 세트에 있는지 여부를 나타냅니다. 서브 세트 세트 를 인코딩하기 위해 , 이들 서브 세트 각각은 해당 세트에 속하거나 속하지 않는 것을 알 수있다. 따라서 예를 들어

x = 0b10100001
0b000 # 1
0b001 # 0
0b010 # 1
0b011 # 0
0b100 # 0
0b101 # 0
0b110 # 0
0b111 # 1

x에 {}, {2} 및 {1,2,3}이 포함되어 있음을 나타냅니다.


이것이 어떻게 작동하는지 설명해 주시겠습니까?
Ad Hoc Garf Hunter

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