Golf um gerador de diagrama de Venn

26

Golf um gerador de diagrama de Venn

insira a descrição da imagem aqui

Para comemorar adequadamente o 180º aniversário de John Venn , hoje sua tarefa será criar um programa que produza um diagrama de Venn !

Entrada:

Um número inteiro positivo Nque definirá o intervalo de números que aparece no diagrama (de zero a N) e três conjuntos de números positivos.

Saída:

Um diagrama de Venn de 3 conjuntos mostrando todos os números inteiros de 0 a Ne os relacionamentos dos conjuntos, exibindo-os nas regiões apropriadas do diagrama, semelhantes a este .

Notas

  1. Use stdin(ou qualquer que seja o equivalente do seu idioma) para obter os valores.
  2. Você pode definir o formato de entrada para os conjuntos e para N(Separado por vírgula, barra ou o que for melhor para você).
  3. Os números que não aparecem em nenhum dos conjuntos, mas estão dentro do intervalo especificado, devem aparecer no diagrama, mas não dentro de nenhuma região.
  4. Os conjuntos não precisam ser nomeados.
  5. A saída pode ser um desenho ou ascii-art.
  6. O diagrama pode ter qualquer forma, desde que os limites sejam inequivocamente distinguíveis (se você escolher a arte ASCII, usar + (ou similar) para cruzar os limites é essencial, por exemplo).
  7. As regiões podem, mas não precisam ser sombreadas.
  8. Quaisquer funções internas ou bibliotecas de terceiros que geram diagramas de Venn não são permitidas.
  9. Aplicam-se brechas padrão .

Isso é , então o código mais curto, em bytes, vence.

William Barbosa
fonte
Parece que você deveria ter adicionado uma nota de que as soluções precisam ser dimensionadas para tamanhos de entrada arbitrários. Atualmente, apenas alguns deles fazem isso (tanto quanto eu posso dizer apenas os ASCII). Não gosto de alterar as regras após o início do concurso, mas sem esse requisito, alguém provavelmente poderia abusar dele com um layout simples que funciona apenas para um caractere em cada conjunto (se eu fizesse isso, provavelmente cortaria o tamanho do código para um terço).
Martin Ender
@ MartinBüttner Sim, alguns deles são muito ruins. Mas adicionar uma observação agora que existem 7 respostas parece uma má ideia. Deve adicionar a nota e comentar sobre a postagem de todos para que eles saibam que o diagrama deve escalar bem até X?
William Barbosa
Definir um limite ainda permitirá apenas codificar esse limite. Eu acho que o dimensionamento adequado é realmente a parte mais difícil do desafio. Portanto, deixe-o como está ou altere-o para dizer que ele deve lidar com tamanhos de conjuntos arbitrários (o que tecnicamente nem é uma alteração, já que você não limitou os tamanhos de entrada, acho que os tamanhos das entradas arbitrárias devem ser assumidos de qualquer maneira) .
Martin Ender
@ Ryan Observe que eu declaro "exibindo-as nas regiões apropriadas do diagrama" na seção de saída. Algumas respostas (o seu incluído) não exibir a seção mais interna corretamente se a referida secção tem mais de 5 elementos, então eu acho que é inválido
William Barbosa
Xkcd
sergiol 28/04

Respostas:

8

Mathematica 343 264

UnGolfed

m=Input[]; data=Input[];


(* The circles to represent set boundaries *)
{R1,R2,R3}=Circle[#,5]&/@{{-2,8.5},{2,8.5},{0,5}};

(*converts  {1,0,1} to base 10, ie, the number 5.
bool[x_]:=FromDigits[Boole[x],2]

(* determines the region in which each number from 0 to `m` resides *)
encode[num_]:=bool[Table[MemberQ[data[[k]],num],{k,3}]]

(*Centroid of each region; the first is a location for numbers in none of the three sets *)
points={{7,4},{0,2},{4,10},{3,6},{-4,10},{-3,6},{0,11},{0,7}}

(* Plots the venn diagram with numbers in regions *)
Graphics[{
Text@@@({#[[1]],points[[#[[2]]+1]]}&/@({#[[All,1]],#[[1,2]]}&/@GatherBy[{#,encode[#]}&/@Range[0,m],Last])),
Opacity[.1],R1,R2,R3
}]

Assumindo que 10foi entrada me {{1,2,3,4,5,9},{1,2,3,6,8},{7,2,9}}foi entrada para d,

novo diagrama de venn


Golfe 264

Fiquei surpreso que todo o cálculo pudesse ser realizado dentro da Graphicsprópria função. Com exceção das entradas, é uma linha.

m=Input[];d=Input[]
Graphics@{Text@@@({#[[1]],{{7,4},{0,2},{4,10},{3,6},{-4,10},{-3,6},{0,11},{0,7}}[[#[[2]]+1]]}&/@({#[[All,1]],#[[1,2]]}&/@GatherBy[{#,FromDigits[Boole[Table[d[[k]]~MemberQ~#,{k,3}]],2]}&/@Range[0,m],Last])),Circle[#,5]&/@{{-2,8.5},{2,8.5},{0,5}}}
DavidC
fonte
+1 para a aparência dos círculos. Estou surpreso que eles pareçam tão bem em cinza. A dispersão dos números é estranha. Você está usando RandomSamplepara escolher o local?
Level River St
Gray funciona porque a opacidade é de 10%. RandomSample foi usado para escolher o local. Depois que um local é escolhido, ele é removido do conjunto de candidatos para escolhas adicionais. Eu brinquei com outros métodos (por exemplo, empregando o centróide de uma sub-região, mas não gostei dos resultados). BTW, eu gosto da sua abordagem para colocar etiquetas.
5134
Para salvar os caracteres, mudei para Circles, para que os discos cinza acabem. A maior parte da economia advém do fato de todos os membros de uma região estarem plotados no centro dessa região.
DavidC
45

Ruby, 654 590 566 542 505 bytes

Isso foi divertido. Eu usei ASCII. Ainda não consegui testar todas as combinações possíveis; por isso, se você encontrar um caso de teste com falha, informe-me.

require'set'
u=(0..gets.to_i).to_set
a,b,c=eval(gets).map &:to_set
i=' '
m,M,n,N,o,O,p,P,q,Q,r,R,s,S=[a-b-c,b-a-c,c-a-b,a&b-c,b&c-a,a&c-b,a&b&c].map{|u|[t=u.to_a*i,t.size]}.flatten
H,V,X=?─,?│,?┼
puts'┌'+H*(A=[1+M+[P,S].max,1+R].max)+?┐+(u-a-b-c).to_a*i,V+i*M+?┌+(b=H*(T=-M+U=A-1)+X+H*(B=[N,Q].max))+?┐,V+m+V+p+i*(T-P)+V+n+i*(B-N)+V,'│┌'+H*(K=M-1)+X+b+X+H*(C=[O-B-1,0].max)+?┐,(v=V*2+i*K)+V+s+i*(T-S)+V+q+i*(B-Q)+V+i*C+V,v+?└+b+?┘+i*C+V,V*2+r+i*(U-R)+V+o+i*(-O+D=B+C+1)+V,'└┼'+H*U+?┘+i*D+V,' └'+H*(A+D)+?┘

Espera a entrada em STDIN no seguinte formato

10
[[1,2,3,4,5,9],[1,2,3,6,8],[7,2,9]]

E então te recompensará com essa beleza

┌───────┐0 10
│   ┌───┼───┐
│4 5│1 3│6 8│
│┌──┼───┼───┼┐
││  │2  │   ││
││  └───┼───┘│
││9     │7   │
└┼──────┘    │
 └───────────┘

Eu não acho que posso me incomodar em adicionar uma versão não destruída. Veja a versão original no histórico de edições para obter uma versão um pouco mais legível.

Isso certamente poderia ser ainda mais aprimorado, tornando os limites definidos menos rígidos ou até mantendo-os fixos, como alguns gráficos, mas eu prefiro que pareça agradável e seja feito "corretamente", apesar de ser jogado.

Martin Ender
fonte
Se você não tivesse chegar cap de hoje você chegar ao 10K clube hoje com esta resposta, que pena
William Barbosa
@WilliamBarbosa Talvez me dê as votações necessárias amanhã. ;)
Martin Ender
Esse é um belo diagrama de Venn. Suponho que a aparência do diagrama seja a principal razão de todos os seus votos positivos. O que acontece com conjuntos maiores? Eu estou supondo que permanece a mesma altura e fica cada vez mais amplo?
Level River St
@steveverrill sim exatamente. cada um dos 8 subconjuntos é impresso apenas como uma lista delimitada por espaço na posição correta. os limites são sempre da mesma forma e a largura de cada seção é determinada como o mínimo possível para caber tudo dentro. é claro, poderia parecer melhor se eu calculasse a quebra de linha para manter cada subconjunto aproximadamente quadrado, mas, novamente, isso é código-golfe, afinal;). Também parece ainda melhor sem o espaçamento adicional entre linhas
Martin Ender
1
Viu os pequenos ângulos e deu uma olhada dupla, pensando que era APL ou algo assim. :)
hoosierEE
15

BBC BASIC, 243 caracteres ASCII (tamanho do arquivo tokenizado 211 bytes)

Faça o download do emulador em http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Golfe

  INPUT"N",n
  DIMs(n+1)
  FORi=0TO2PRINT"S";i
  REPEATINPUTx:s(x)=s(x)+2^i:UNTILx>n
  NEXTMODE4r=360CIRCLE460,r,r
  CIRCLE640,664,r
  CIRCLE820,r,r
  FORi=0TO7FORx=0TOn:IFs(x)=i PRINT;x
  NEXTREADa
  VDU28,a+1792;a+5;
  NEXT
  DATA19,4873,2572,4893,2586,5907,3091,34

O BBC Basic é muito arbitrário sobre quais novas linhas / espaços em branco você pode eliminar. Além de remover novas linhas desnecessárias, há outro truque aqui que não está na versão não destruída: eu atribuo a janela de visualização (veja a explicação abaixo em comentários não destruídos) no final do ciclo de plotagem, não no começo. Isso significa que os elementos fora do conjunto são plotados no canto superior esquerdo e o cursor está preso em uma viewport no canto superior direito no final do programa. A razão para isso é eliminar o VDU26.

Ungolfed

Cada conjunto de números é encerrado pelo usuário digitando o número N + 1 (uma escolha um pouco incomum, para evitar erros causados ​​pela tentativa de escrever fora do intervalo de uma matriz.) Em seguida, passa de um modo de texto para um modo gráfico. e plota o diagrama de Venn.

Os dados de entrada são armazenados em uma matriz, uma célula para cada valor a ser exibido. Os dados são armazenados como um valor de 3 bits: 1 para o Set0 + 2 para o Set1 + 4 para o Set2, fornecendo um número no intervalo de 0 a 7. O BBC basic não tem operador de turno, portanto, o operador de energia é usado: em 2^ivez de 1<<iem C por exemplo.

Após plotar os círculos, um loop externo passa por cada uma das oito regiões, movendo-se para as coordenadas necessárias (conforme uma tabela de dados.) Um loop interno imprime todos os números nessa região (aqueles com o valor de 3 bits correspondente no array.)

  INPUT"N",n                                 :REM create an array called s() with range 0..n+1
  DIMs(n+1)
  FORi=0TO2
    PRINT"S";i                               :REM prompt the user for data for set 0, set 1 and set 2.
    REPEATINPUTx:s(x)=s(x)+2^i:UNTILx>n      :REM input numbers and store as a bit table. Repeat until user enters n+1.
  NEXT
  MODE4                                      :REM change to graphics mode.
  r=360
  CIRCLE460,r,r                              :REM plot a circle at x,y,r.
  CIRCLE640,664,r                            :REM for the bottom two circles y=r.
  CIRCLE820,r,r
  FORi=0TO7                                  :REM for each region of the venn diagram
    READa                                    :REM read a 2 byte value for the  coordinates of the top left corner of a text viewport from the DATA statement: x+256y
    VDU28,a+1792;a+5;                        :REM create a 5x7 viewport (limits each region to 7 numbers.) 1792=7*256
    FORx=0TOn:IFs(x)=i PRINT;x               :REM print all numbers in the array belonging to that region
    NEXT
  NEXT
  VDU26                                      :REM Restore the viewport to the whole screen, to ensure the command prompt does not mess up the display at the end of the program.
  DATA34,19,4873,2572,4893,2586,5907,3091

Montagem de entrada e saída típicas (versão não destruída)

Na versão golfed, a posição dos números fora dos sets é trocada com o prompt de comando >.

insira a descrição da imagem aqui

Level River St
fonte
Isso funciona para entradas arbitrariamente grandes?
Martin Ender
@ MartinBüttner, em princípio, sim, o algoritmo pode fazê-lo, mas a tela o decepciona (como é provável que seja o problema de outras soluções). Eu insisto nos comentários do programa que cada região é limitada a 7 números antes de começar a rolar ( os números estão em uma coluna vertical, como pensei que o embrulho ficaria horrível.) O emulador que estou usando pode lidar com resoluções de tela muito mais altas, mas optei por um dos modos "autênticos" da tela da BBC, bastante limitados. Se alguém portar isso para Java, o único limite prático será a capacidade humana de ler o diagrama.
Level River St
Ah, sim, eu queria saber se os círculos se adaptariam ao tamanho da entrada ... é claro que minha solução também será ilegível para entradas grandes se o seu terminal quebrar as linhas, mas desde que seja exibido com barras de rolagem, ele pode lidar com qualquer entrada Tamanho.
Martin Ender
2
mesmo que isso foi portado para Java você tem que adicionar o código para fazer os círculos maiores para mais texto
Sparr
14

Javascript 1235

http://jsfiddle.net/44a4L/7/

Testado no google chrome v36.

A entrada é obtida nas variáveis ​​upper, set1, set2 e set3.

Atualização: agora é dimensionado automaticamente, dependendo do tamanho da entrada.

function t(e,t){z.getElementById(e).innerHTML+=" "+t}z=document;s=200+upper*20;z.body.innerHTML+="<style>#m{width:"+s+"px;height:"+s+"px;}div{position:absolute;text-align:center;border-radius:50%;}#s1{left:calc(15% + 15px);top:30px;bottom:30%;right:calc(15% + 15px);background-color:rgba(255,0,0,0.4);padding:10%;}#s2{left:30px;bottom:30px;top:30%;right:30%;background-color:rgba(0,255,0,0.4);padding-right:40%;padding-top:30%;}#s3{right:30px;bottom:30px;top:30%;left:30%;background-color:rgba(0,0,255,0.4);padding-left:40%;padding-top:30%;}#s123{left:40%;top:40%;right:40%;bottom:40%;}#s12{left:20%;top:35%;right:65%;bottom:50%;}#s13{right:20%;top:35%;left:65%;bottom:50%;}#s23{left:40%;right:40%;bottom:15%;top:70%;}</style><div id=m><div id=s1 class=s></div><div id=s2 class=s></div><div id=s3 class=s></div><div id=s123 class=v></div><div id=s12 class=v></div><div id=s13 class=v></div><div id=s23 class=v></div></div>";for(i=0;i<=upper;i++){i1=i2=i3=false;if(set1.indexOf(i)!=-1)i1=true;if(set2.indexOf(i)!=-1)i2=true;if(set3.indexOf(i)!=-1)i3=true;if(i1&&i2&&i3)t("s123",i);else if(i1&&i2)t("s12",i);else if(i1&&i3)t("s13",i);else if(i2&&i3)t("s23",i);else if(i1)t("s1",i);else if(i2)t("s2",i);else if(i3)t("s3",i);else t("m",i)}

Saída de amostra:

Venn

rdans
fonte
Muito bom! Consegui apertar um pouco mais, veja jsfiddle.net/44a4L/2 - veja a função "t", CSS e body.innerHTML. A mesma lógica. Tenho certeza de que ainda pode ser espremido.
Nenotlep
Este é o mais bonito até agora, é uma pena que não seja bem dimensionado. Três elementos dentro da área mais interna fazem com que ela se quebre. Você planeja fazê-lo escalar de alguma forma?
William Barbosa
@WilliamBarbosa scaling já está implementado
rdans
2
Linda! Impressionante! Espetacular! (Tiveram de utilizar mais do que um superlativo porque SE odeia brevidade.)
Scott Leadley
4

Python - 603

import re
n,a,b,c=eval(input())
h=set(range(n+1))-a-b-c
g=a&b&c
d,e,f=a&b-g,b&c-g,a&c-g
l,m=set(a),set(b)
a-=b|c
b-=l|c
c-=l|m
for t in'abcdefgh':exec("%s=' '.join(map(str,%s))"%(2*(t,)))
l=len
x,y,z=max(l(a),l(f)+2,3),l(max(d,g)),max(l(b),l(e)+2,l(c)-l(f+g)-2,3)
j=[0]*4
for t in'abcdefg':exec("%s=%s.ljust([x,z,x+y+z-2,y,z-2,x-2,y][ord('%s')-97])+'|'"%(3*(t,)))
s='\d| '
w=re.sub
for r in (1,3):q=r//2;j[r]=['','| '][q]+'|'+[a+d+b,f+g+e][q]+['',' |'][q];j[r-1]=w('\|','+',w(s,'-',j[r]))
j[0]+=h
o=j[2]
j[2]='| +'+j[2][3:-3]+'+ |'
p='  |'+c
q='  '+w('\|','+',w(s,'-',p))[2:]
for l in j+[o,p,q]:print(l)

A entrada é N seguida pelos três conjuntos, separados por vírgulas (por exemplo 8, {1,2,4}, {2,3,4,5}, {4,6,8}). Ele gera um conjunto na arte ACSII como o seguinte:

+---+-+---+0 7
|1  | |3 5|
| +-+-+-+ |
| |2|4| | |
+-+-+-+-+-+
  |6 8  |
  +-----+
faubi
fonte
Haha, duas soluções quase idênticas em 5 minutos. (3 horas após o desafio foi publicado ...)
Martin Ender
1
Consulte a nota número 6. Suas arestas e limites de cruzamento precisam ter um caractere diferente, como "+".
William Barbosa
4

HTML + JavaScript (E6) 752775

Formato de entrada: max set1 set2 set3 (cada conjunto é uma lista de números separados por vírgula)

Exemplo: 10 1,2,3,4,5,9 1,2,3,6,8 7,2,9

Captura de tela

Exemplo 2: 30 2,4,6,8,10,12,14,16,18,30 3,6,9,12,15,18,21,30 5,10,15,20,25,30

Captura de tela do Chrome

Todas as seções são dimensionadas automaticamente, graças à renderização em html.

<html><body><script>
i=prompt().split(' ');
r=",,,,,,,, class=',></i>".split(c=',')
for (j=-1;j++<i[0];r[h]+=j+' ')for(h=k=0;++k<4;)if((c+i[k]+c).search(c+j+c)+1)h+=k+(k>2);
document.write(
"<style>div{1row}p{position:relative;text-align:center;padding:7;1cell}i{position:absolute;top:0;3:0;4:0;left:0}.a{2top-left5b{2top-45c{23-left5d{23-45x{6880,9.y{680,89.z{60,889</style>"
.replace(/\d/g,x=>'09display:table-9border-9bottom9right9-radius:60px}.9background:rgba(930px9255,9.3)}'.split(9)[x])
+"<div><p8x a'/><p8x'>1</p><p><i8y a'9<i8x b'93</p><p8y'>2</p><p8y b'/></div><div><p8x c'/><p8z a'><i8x'95</p><p8z'><i8x d'9<i8y c'97</p><p8z b'><i8y'96</p><p8y d'/></div><div><p/><p8z c'/><p8z'>4</p><p8z d'/></div>0"
.replace(/\d/g,x=>r[x]))
</script></body></html>

Versão Javascript E5 Funciona no Chrome e MSIE 10 (talvez 9)

<html><body><script>
i=prompt().split(' ');
r=",,,,,,,, class=',></i>".split(c=',')
for (j=-1;j++<i[0];r[h]+=j+' ')for(h=k=0;++k<4;)if((c+i[k]+c).search(c+j+c)+1)h+=k+(k>2);
document.write(
"<style>div{1row}p{position:relative;text-align:center;padding:7;1cell}i{position:absolute;top:0;3:0;4:0;left:0}.a{2top-left5b{2top-45c{23-left5d{23-45x{6880,9.y{680,89.z{60,889</style>"
.replace(/\d/g,function(x){return '09display:table-9border-9bottom9right9-radius:60px}.9background:rgba(930px9255,9.3)}'.split(9)[x]})
+"<div><p8x a'/><p8x'>1</p><p><i8y a'9<i8x b'93</p><p8y'>2</p><p8y b'/></div><div><p8x c'/><p8z a'><i8x'95</p><p8z'><i8x d'9<i8y c'97</p><p8z b'><i8y'96</p><p8y d'/></div><div><p/><p8z c'/><p8z'>4</p><p8z d'/></div>0"
.replace(/\d/g,function(x){return r[x]}))
</script></body></html>

Não (tão) jogou golfe

<html>
<style>
div {   display:table-row; }
p {
    position: relative;
    text-align: center;
    padding: 30px;
    display: table-cell;
}
i {
    position: absolute;
    top:0;bottom:0;right:0;left:0;
}
.a { border-top-left-radius: 60px; }
.b { border-top-right-radius: 60px; }
.c { border-bottom-left-radius: 60px; }
.d { border-bottom-right-radius: 60px; }
.x { background: rgba(255,255,0,.3) }
.y { background: rgba(255,0,255,.3) }
.z { background: rgba(0,255,255,.3) }
</style>
<body>
<div>
<p class='x a'/><p class='x'><b id='b1'></b></p><p><i class='y a'></i><i class='x b'></i><b id='b3'></b></p><p class='y'><b id='b2'></b></p><p class='y b'/>
</div>    
<div>
<p class='x c'/><p class='z a'><i class='x'></i><b id='b5'></b></p><p class='z'><i class='x d'></i><i class='y c'></i><b id='b7'></b></p><p class='z b'><i class='y'></i><b id='b6'></b></p><p class='y d'/>
</div>        
<div>
<p/><p class='z c'/><p class='z'><b id='b4'></b></p><p class='z d'/>
</div>    
<b id='b0'></b>    
<script>
i=prompt().split(' ')
r=',,,,,,,'.split(c=',')
for (j=-1; j++<i[0];)
{
    for(h = k = 0; ++k < 4;)
    {
    if( (c+i[k]+c).search(c+j+c) >= 0)
      h += k + (k>2); // bit mask 1 or 2 or 4
  }
  r[h] += j + ' ';
}        
for (j = 0; j < 8; j++)
    document.getElementById('b'+j).innerHTML=r[j]
</script>
</html>
edc65
fonte
3

Python 3-353

# 353 bytes, input format like: 6 1,2,3 2,3,4 1,3,4
import sys
from turtle import*
_,n,*q=sys.argv
n=set(range(int(n)))
a,b,c=map(set,map(eval,q))
for x,y in(0,0),(-115,-185),(115,-185):goto(x,y),pd(),circle(200),up()
for x,y,s in(200,331,n-a-b-c),(-101,278,a-b-c),(-254,-49,b-a-c),(95,-49,c-a-b),(-172,164,a&b-c),(58,164,a&c-b),(-49,-39,b&c-a),(-49,52,a&b&c):goto(x,y),write(s or'',font=None)
ht()
done()

Mais alguém brincou com o Logo quando criança?

Amostra: python3 turtletest.py 15 1,2,3,4,5,9,10,12 1,3,4,6,7,9 1,2,7,8,9

insira a descrição da imagem aqui

Jason S
fonte
a fonte / círculos serão dimensionados para entrada arbitrariamente grande?
Sparr
Não, ainda estou pensando nisso.
Jason S
@JasonS Ainda está pensando?
Jonathan Frech
3

perl 388b 346b 488b

Isso tem uma saída semelhante a outra entrada:

@a=split($",<>);
$n=pop @a;
@a=map[split(',')],@a;
for$i(0..2){$b{$_}+=1<<$i foreach@{$a[$i]}}
push@{$c[$b{$_}]},$_ for(0..$n);
$l|=length($d[$_]=join($",@{$c[$_]}))for(0..$n);
print$h=(("+-"."-"x$l)x3)."+
";
sub j{sprintf"% ".(sprintf"%ds",$l+($_[0]<4)+($_[0]==7)),$d[$_[0]]}
sub r{join('|',map{j($_)}@_)}
$h=~s/\+-/|+/;
$h=~s/-\+$/+|/;
print "|".r(1,3,2)."|
".$h;
$h=~s/[|+]{2}/++/g;
print "||".r(5,7,6)."||
".$h;
$h=~s/\+\+/ +/;
$h=~s/\+\+/+ /;
$h=~s/-\+-/---/g;
$l=$l*3+3;print " |".j(4)."|
",$h,$d[0]

Teste de execução e saída:

# echo "1,2,3,7,13 2,3,8,11,13,6,9 3,4,5,11,12,13,14 15" | perl venn.pl ;echo
+----------------+----------------+----------------+
|             1 7|               2|           6 8 9|
|+---------------+----------------+---------------+|
||               |            3 13|             11||
++---------------+----------------+---------------++
 |                                       4 5 12 14|
 +------------------------------------------------+ 
Sparr
fonte
Hum, não tenho certeza se o layout é realmente inequívoco se você não viu a entrada.
Martin Ender
Você está certo, isso não é Venn-y suficiente
William Barbosa
@WilliamBarbosa ok, I fez parecer que a entrada da faubiguy
Sparr
2

T-SQL 2095

Supõe que @N é um int contendo N. Supõe que @A, @B e @C são tabelas que contêm os três conjuntos de números. Não tentei jogar golfe demais.

DECLARE @D INT=@N,@E INT=0,@F CHAR='/',@G CHAR='\',@H CHAR='-',@I CHAR='|',@J CHAR='+'DECLARE @ TABLE(Z INT,Y INT,X INT,W INT,V INT,U INT,T INT,S INT)INSERT INTO @(Z)SELECT A.P FROM @A A JOIN @B B ON A.P=B.P JOIN @C C ON A.P=C.P INSERT INTO @(Y)SELECT A.P FROM @A A JOIN @B B ON A.P=B.P LEFT JOIN @C C ON A.P=C.P WHERE C.P IS NULL INSERT INTO @(X)SELECT C.P FROM @C C JOIN @A A ON C.P=A.P LEFT JOIN @B B ON C.P=B.P WHERE B.P IS NULL INSERT INTO @(W)SELECT B.P FROM @B B JOIN @C C ON B.P=C.P LEFT JOIN @A A ON B.P=A.P WHERE A.P IS NULL INSERT INTO @(V)SELECT A.P FROM @A A LEFT JOIN @B B ON A.P=B.P LEFT JOIN @C C ON A.P=C.P WHERE C.P IS NULL AND B.P IS NULL INSERT INTO @(U)SELECT C.P FROM @C C LEFT JOIN @A A ON C.P=A.P LEFT JOIN @B B ON C.P=B.P WHERE B.P IS NULL AND A.P IS NULL INSERT INTO @(T)SELECT B.P FROM @B B LEFT JOIN @C C ON B.P=C.P LEFT JOIN @A A ON B.P=A.P WHERE A.P IS NULL AND C.P IS NULL WHILE @N>=0BEGIN INSERT INTO @(S)SELECT @N WHERE @N NOT IN(SELECT*FROM @A UNION SELECT*FROM @B UNION SELECT*FROM @C)SET @N-=1 END DECLARE @Z TABLE(A CHAR(5),B CHAR(5),C CHAR(5),D CHAR(5),E CHAR(5),F CHAR(5),G CHAR(5),H CHAR(5))INSERT INTO @Z SELECT @F,@H,@F,@H,@G,@H,@G,''WHILE @E<=@D BEGIN INSERT INTO @Z SELECT @I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT V FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT X FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT U FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT S FROM @)),'')SET @E+=1 END INSERT INTO @Z SELECT @F,@H,@J,@H,@G,'',@I,''SET @E=0WHILE @E<=@D BEGIN INSERT INTO @Z SELECT @I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT Y FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT Z FROM @)),''),@I,'',@I,''SET @E+=1 END INSERT INTO @Z SELECT @G,@H,@J,@H,@F,'',@I,''SET @E=0WHILE @E<=@D BEGIN INSERT INTO @Z SELECT @I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT T FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT W FROM @)),''),@I,'',@I,''SET @E+=1 END INSERT INTO @Z SELECT @G,@H,@G,@H,@F,@H,@F,''SELECT*FROM @Z

Versão menos golfe:

--finding the sets
DECLARE @D INT=@N,@E INT=0,@F CHAR='/',@G CHAR='\',@H CHAR='-',@I CHAR='|',@J CHAR='+'
DECLARE @ TABLE(Z INT,Y INT,X INT,W INT,V INT,U INT,T INT,S INT)
INSERT INTO @(Z)
SELECT A.P FROM @A A JOIN @B B ON A.P=B.P JOIN @C C ON A.P=C.P 
INSERT INTO @(Y)
SELECT A.P FROM @A A JOIN @B B ON A.P=B.P LEFT JOIN @C C ON A.P=C.P WHERE C.P IS NULL 
INSERT INTO @(X)
SELECT C.P FROM @C C JOIN @A A ON C.P=A.P LEFT JOIN @B B ON C.P=B.P WHERE B.P IS NULL 
INSERT INTO @(W)
SELECT B.P FROM @B B JOIN @C C ON B.P=C.P LEFT JOIN @A A ON B.P=A.P WHERE A.P IS NULL 
INSERT INTO @(V)
SELECT A.P FROM @A A LEFT JOIN @B B ON A.P=B.P LEFT JOIN @C C ON A.P=C.P WHERE C.P IS NULL AND B.P IS NULL 
INSERT INTO @(U)
SELECT C.P FROM @C C LEFT JOIN @A A ON C.P=A.P LEFT JOIN @B B ON C.P=B.P WHERE B.P IS NULL AND A.P IS NULL 
INSERT INTO @(T)
SELECT B.P FROM @B B LEFT JOIN @C C ON B.P=C.P LEFT JOIN @A A ON B.P=A.P WHERE A.P IS NULL AND C.P IS NULL 
WHILE @N>=0
BEGIN 
    INSERT INTO @(S)
    SELECT @N WHERE @N NOT IN(SELECT*FROM @A UNION SELECT*FROM @B UNION SELECT*FROM @C)
    SET @N-=1 
END

--displaying the venn diagram
DECLARE @Z TABLE(A CHAR(5),B CHAR(5),C CHAR(5),D CHAR(5),E CHAR(5),F CHAR(5),G CHAR(5),H CHAR(5))
INSERT INTO @Z 
SELECT @F,@H,@F,@H,@G,@H,@G,''
WHILE @E<=@D 
BEGIN 
    INSERT INTO @Z 
    SELECT @I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT V FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT X FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT U FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT S FROM @)),'')
    SET @E+=1 
END 
INSERT INTO @Z 
SELECT @F,@H,@J,@H,@G,'',@I,''
SET @E=0
WHILE @E<=@D 
BEGIN 
    INSERT INTO @Z 
    SELECT @I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT Y FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT Z FROM @)),''),@I,'',@I,''
    SET @E+=1 
END 
INSERT INTO @Z 
SELECT @G,@H,@J,@H,@F,'',@I,''
SET @E=0
WHILE @E<=@D 
BEGIN 
    INSERT INTO @Z 
    SELECT @I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT T FROM @)),''),@I,ISNULL((SELECT CONVERT(CHAR,@E,5) WHERE @E IN(SELECT W FROM @)),''),@I,'',@I,''
    SET @E+=1 
END 
INSERT INTO @Z 
SELECT @G,@H,@G,@H,@F,@H,@F,''
SELECT*FROM @Z
marcações
fonte