fundo
No momento em que escrevemos isso, o problema P vs NP ainda não foi resolvido, mas você deve ter ouvido falar do novo artigo de Norbert Blum reivindicando a prova de que P! = NP, que já é suspeito de estar errado (mas veremos).
O problema discutido neste artigo é o problema da camarilha . Pelo menos é o que li em um artigo de jornal, então me corrija se estiver errado, mas, de qualquer forma, gostaria que você escrevesse um programa que resolva a seguinte variante:
A tarefa
Suponha que tenhamos uma escola grande com muitos alunos. Cada um desses alunos tem alguns amigos nesta escola. Uma camarilha de estudantes é um grupo composto apenas por alunos que são amigos um do outro .
Seu programa receberá pares de alunos amigos como entrada. A partir dessas informações, o programa deve encontrar o tamanho da maior clique . Os alunos são identificados por IDs inteiros .
Se você preferir termos matemáticos, isso significa que você alimenta as bordas de um gráfico não direcionado, identificado por dois nós cada.
Entrada
Sua entrada será uma lista não vazia de pares inteiros positivos, por exemplo [[1,2],[2,5],[1,5]]
. Você pode receber esta entrada de qualquer forma sensata, por exemplo, como uma matriz de matrizes, como linhas de texto contendo dois números cada, etc ...
Saída
A saída esperada é um número único n >= 2
: o tamanho da maior clique. Com a entrada de exemplo acima, o resultado seria 3
, pois todos os alunos ( 1
, 2
e 5
) são amigos um do outro.
Casos de teste
[[1,2]]
=> 2
[[1,2],[3,1],[3,4]]
=> 2
[[1,2],[2,5],[1,5]]
=> 3
[[2,5],[2,3],[4,17],[1,3],[7,13],[5,3],[4,3],[4,1],[1,5],[5,4]]
=> 4 (the largest clique is [1,3,4,5])
[[15,1073],[23,764],[23,1073],[12,47],[47,15],[1073,764]]
=> 3 (the largest clique is [23,764,1073])
[[1296,316],[1650,316],[1296,1650],[1296,52],[1650,711],[711,316],[1650,52],
[52,711],[1296,711],[52,316],[52,1565],[1565,1296],[1565,316],[1650,1565],
[1296,138],[1565,138],[1565,711],[138,1650],[711,138],[138,144],[144,1860],
[1296,1860],[1860,52],[711,1639]]
=> 6 (the largest clique is [52,316,711,1296,1565,1650])
Você pode usar essa implementação de referência (estúpida) (imprime saída extra com -d
sinalizador) para verificar os resultados de outros casos de teste.
As regras
- Seu programa não precisa de um resultado definido com entrada inválida. Então você pode assumir que:
- você sempre terá pelo menos um par de IDs
- cada par consiste em dois IDs diferentes
- nenhum par aparece duas vezes (a troca dos locais dos IDs ainda seria o mesmo par)
- Seu algoritmo não tem permissão para definir um limite superior no tamanho da entrada. Limitações puramente técnicas e definidas pelo seu idioma / ambiente (como tamanho da pilha, tempo de computação etc.) são obviamente inevitáveis.
- As brechas padrão são proibidas.
- Isso é código-golfe , então o código mais curto, medido em bytes, vence.
- Se o seu algoritmo tiver complexidade de tempo polinomial, você pontua
-1
imediatamente, independentemente do tamanho do código, mas nesse caso, convém enviar sua solução para outro lugar. ;)
fonte
-1
é bem merecida ;)Respostas:
Geléia ,
15 1816 bytes+3 bytes para corrigir erros no meu método.
-2 bytes graças a milhas (observando que n × (n-1) ÷ 2 = nC2 )
Um link monádico que pega a lista de amizades (arestas) e retorna um número inteiro.
Experimente online! forma o conjunto de potência das bordas da memória, tornando-se ineficiente no espaço e no tempo (sim, isso é O (2 n ) pessoal)!
Quão?
fonte
Mathematica, 34 bytes
Basicamente, o FindClique faz o trabalho e "encontra uma maior clique no gráfico g".
Todo o resto é converter a lista de entrada em gráfico
Entrada
Saída
Entrada
Saída
thanx @Kelly Lowder por -10 bytes
fonte
Tr[1^#&@@FindClique[#<->#2&@@@#]]&
FindClique
ಠ ___ ಠGelatina , 20 bytes
Experimente online!
Claro que isso não merece o milhão: p
Isso teria superado o Pyth, se não fosse o
µ(...)µ
e os 2 bytesÐf
.fonte
J , 36 bytes
Experimente online!
É executado no tempo O (2 n ) em que n é o número de pares.
Uma solução mais rápida para 65 bytes é
Experimente online!
Explicação
fonte
Pitão, 19 bytes
Experimente aqui.
fonte
Python 2 , 180 bytes
Experimente online!
-2 graças a shooqie .
-1 graças ao Sr. Xcoder .
-3 graças a recursiva .
fonte
len
a uma variável(x not in y)
meios0**(x in y)
.0**
com-~-
.Pitão, 28 bytes
Experimente online
Explicação
fonte
Python 3 ,
162159 bytesExperimente online!
A função c assume vértices na forma de um conjunto de tuplas
classificadas({(x, y), ...} onde x é menor que y).Uma função chamada "entrada" está no cabeçalho do TIO para testar com dados na lista de formato de lista não classificada. Se clique, retorna comprimento. Se não for clique, retorna o tamanho máximo de clique dos vértices, menos um vértice para cada vértice nos vértices. Excede o tempo no último caso de teste no TIOAtualize: "ou (z, y) em x" parte adicionada para remover a dependência da classificação "f = lambda x: {i por s em x por i em s}" em vez de itertools.chain agrupado em conjunto.
- menos 3 bytes graças a @ Jonathan Allen
fonte
c
, de modo que pode removerc=
(você precisa colocarc=\
no final do cabeçalho e coloque olambda
no topo do bloco de código para TIO)s
e substituirs(...)
por{*...}
permitir a remoção de alguns espaços também.05AB1E , 19 bytes
Experimente online!
fonte
Gelatina , 28 bytes
Experimente online!
Solução mais rápida capaz de resolver o último caso de teste em um segundo no TIO.
fonte
n
só podem aparecer nas bases :)Java + Goiaba 23.0, 35 + 294 = 329 bytes
Esse algoritmo não está representado graficamente, mas está gerando todas as combinações de pares, de um tamanho específico. Alimento todas as combinações de pares em um multiset e verifico se todas elas têm o tamanho esperado (o número de entradas exclusivas - 1). Se o fizerem, encontrei uma camarilha e vou procurar uma maior.
Na biblioteca do Guava, eu uso o novo
combinations
método e o tipo de coleção de ferramentasMultiset
.Ungolfed
fonte
x
é polinomial " <- você tem certeza? Eu acho que esse é o método usado . O valor de retorno é umAbstractSet
com um iterador, e o seguintefor
ciclo irá chamar esse iteradorx!
vezes, se não me engano ...x < n
(comn
sendo o tamanho total do conjunto de entrada), én!/(x!(n-x)!)
, ainda não polinomial :)combinations
método que éX^n
(o que é inteiramente possível), posso obtê-lo? Enquanto isso, retiro minha reivindicação do "-1".Python 2 , 102 bytes
Experimente online!
fonte
Código da máquina 6502 (C64),
774703bytes(Eu só tinha que fazer isso, meu C64 pode fazer tudo ... hehe)
hexdump:
Demonstração online
Uso: Comece com
sys49152
e insira os pares um por linha, como por exemploO backsapce não é tratado durante a entrada (mas se você usar
vice
, basta copiar e colar sua entrada no emulador). Digite uma linha vazia para iniciar o cálculo.Isso é muito grande para postar uma lista de desmontagem explicativa aqui, mas você pode procurar a fonte de montagem no estilo ca65 . O algoritmo é muito ineficiente, gera todas as permutações possíveis dos nós e, com cada um deles, cria avidamente um clique, checando todas as bordas. Isso permite uma eficiência de espaço de O (n) (meio importante em uma máquina com essa pequena RAM), mas tem uma eficiência de tempo de execução horrível (*) . Os limites teóricos são de até 256 nós e até 8192 arestas.
Há uma versão maior (
883805 bytes) com melhores recursos:Demonstração online
Procurar fonte
(*) O último caso de teste leva algo entre 12 e 20 horas (eu estava dormindo quando finalmente terminou). Os outros casos de teste terminam na pior das hipóteses em alguns minutos.
fonte