Calcular o número de topologias em {1,2,…, n}

9

Tarefa

Escreva uma função / programa que tome ncomo parâmetro / entrada e imprima / retorne o número de topologias (demonstradas abaixo) no aparelho {1,2,...,n}.

Definição de Topologia

Seja X qualquer conjunto finito e assuma que T, que é um subconjunto do conjunto de potências de X (isto é, um conjunto contendo subconjuntos de X), satisfaz as seguintes condições :

  1. X e o conjunto vazio estão em T.

  2. Se dois conjuntos U e V estiverem em T, a união desses dois conjuntos estará em T.

  3. Se dois conjuntos U e V estiverem em T, a interseção desses dois conjuntos estará em T.

... então T é chamado de topologia no X.

Especificações

  1. Seu programa é:

    • uma função que assume ncomo parâmetro
    • ou um programa que insere n

    e imprime ou retorna o número de topologias (distintas) no aparelho {1,2,...,n}.

  2. n é qualquer número inteiro não negativo menor que 11 (é claro que não há problema se o seu programa lidar com n maior que 11) e a saída for um número inteiro positivo.

  3. Seu programa não deve usar nenhum tipo de função de biblioteca ou função nativa que calcule o número de topologia diretamente.

Exemplo de entrada (valor de n): 7

Exemplo de saída / retorno: 9535241

Você pode verificar seu valor de retorno aqui ou aqui .

Obviamente, o código mais curto vence.


O vencedor está decidido, no entanto, eu posso mudar o vencedor se um código menor aparecer.

JiminP
fonte
Tem que dar resultados neste século, ou é uma prova de correção boa o suficiente?
Peter Taylor
@ Peter De fato, não tenho idéia de quanto tempo vai demorar. Portanto, a prova de correção do programa é boa o suficiente, mas ainda assim o programa deve fornecer um resultado em um tempo razoável se n for pequeno, como 4 ~ 5.
JiminP
@JiminP, parece que calculá-lo para n = 12 valia um jornal naquela época e não existe uma fórmula conhecida. Por 4 ou 5, suspeito que seja possível em alguns minutos pela força bruta.
Peter Taylor
O subconjunto impróprio de 2 ^ X também é uma topologia?
FUZxxl
@FUZxxl: Sim. Eu acho que isso é chamado de topologia discreta .
JiminP

Respostas:

4

Haskell, 144 caracteres

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]

Quase uma implementação direta da especificação, modulo alguma mônada mágica.

Extremamente lento para n > 4.

hammar
fonte
5

Python, 147 caracteres

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]))

Rápido para N <= 6, lento para N = 7, improvável que N> = 8 seja concluído.

Conjuntos individuais são representados por máscaras de bits inteiras e topologias por conjuntos de máscaras de bits. S(i,K)calcula o número de topologias distintas que você pode formar iniciando Ke adicionando conjuntos com máscaras de bits> = i.

Keith Randall
fonte
0

Zsh, 83 caracteres

Esta solução corresponde à letra de seus requisitos (mas não, é claro, ao espírito). Sem dúvida, há uma maneira de comprimir os números ainda mais.

a=(0 3 S 9U 5CT 4HO6 5ODFS AMOZQ1 T27JJPQ 36K023FKI HW0NJPW01R);echo $[1+36#$a[$1]]
Gilles 'SO- parar de ser mau'
fonte
-1

Python, 131 caracteres

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))

Versão expandida:

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

Por exemplo, suponha que n = 3. Os possíveis subconjuntos de [n] são

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

onde o i-ésimo bit indica se i está no subconjunto. Para codificar conjuntos de subconjuntos, notamos que cada um desses subconjuntos pertence ou não ao conjunto em questão. Assim, por exemplo,

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

indica que x contém {}, {2} e {1,2,3}.

user76284
fonte
Você poderia explicar como isso funciona?
Ad Hoc Garf Hunter
@AdHocGarfHunter Adicionada uma versão expandida.
user76284 27/04