Generador de diagramas de Golf a Venn

26

Generador de diagramas de Golf a Venn

ingrese la descripción de la imagen aquí

Para celebrar adecuadamente el 180 cumpleaños de John Venn , hoy su tarea será crear un programa que genere un diagrama de Venn .

Entrada:

Un entero positivo Nque definirá el rango de números que aparecen en el diagrama (de cero a N) y tres conjuntos de enteros positivos.

Salida:

Un diagrama de Venn de 3 conjuntos que muestra todos los enteros de 0 a Ny las relaciones de los conjuntos mostrándolos en las regiones apropiadas del diagrama, similar a este .

Notas

  1. Use stdin(o el equivalente de su idioma) para obtener los valores.
  2. Puede definir el formato de entrada para los conjuntos y para N(Separado por coma, barra inclinada o lo que sea mejor para usted).
  3. Los números que no aparecen en ninguno de los conjuntos pero que están dentro del rango especificado deben aparecer en el diagrama, pero no dentro de ninguna región.
  4. Los conjuntos no necesitan ser nombrados.
  5. La salida puede ser un dibujo o arte ascii.
  6. El diagrama puede tener cualquier forma siempre que los límites sean claramente distinguibles (si elige el arte ASCII, es esencial usar + (o similar) para cruzar los límites, por ejemplo).
  7. Las regiones pueden pero no tienen que estar sombreadas.
  8. No se permiten las funciones integradas o las bibliotecas de terceros que generan Diagramas de Venn.
  9. Se aplican lagunas estándar .

Este es el , por lo que el código más corto, en bytes, gana.

William Barbosa
fuente
Parece que debería haber agregado una nota de que las soluciones tienen que escalar para tamaños de entrada arbitrarios. Actualmente solo unos pocos lo hacen (por lo que puedo decir, solo los ASCII). No me gusta cambiar las reglas después de que el concurso ha comenzado, pero sin este requisito, alguien podría realmente abusar de él con un diseño simple que solo funcione para un personaje en cada conjunto (si lo hiciera, probablemente cortaría el tamaño del código a un tercio más o menos).
Martin Ender
@ MartinBüttner Sí, algunos de ellos escalan bastante mal. Pero agregar una nota ahora que hay 7 respuestas parece una mala idea. ¿Debería agregar la nota y comentar en la publicación de todos para hacerles saber que el diagrama debe escalar bien hasta X?
William Barbosa
Establecer un límite seguirá permitiendo codificar ese límite. Creo que la escala adecuada es en realidad la parte más difícil del desafío. Entonces, déjelo como está o cámbielo para decir que debe tratar con tamaños de conjuntos arbitrarios (que técnicamente ni siquiera es un cambio, ya que no limitó los tamaños de entrada, creo que los tamaños de entrada arbitrarios deberían suponerse de todos modos) .
Martin Ender
@Ryan Tenga en cuenta que afirmo "mostrándolos en las regiones adecuadas del diagrama" en la sección de salida. Algunas respuestas (incluida la suya) no muestran la sección más interna correctamente si dicha sección tiene más de 5 elementos, por lo que creo que no es válida
William Barbosa
Relevante xkcd: xkcd.com/1810
sergiol

Respuestas:

8

Mathematica 343 264

Sin golf

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

Suponiendo que 10se ingresó my {{1,2,3,4,5,9},{1,2,3,6,8},{7,2,9}}se ingresó para d,

nuevo diagrama de venn


Golfed 264

Me sorprendió que todo el cálculo pudiera llevarse a cabo dentro de la Graphicsfunción misma. Con la excepción de las entradas, es una línea.

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
fuente
+1 para la apariencia de los círculos. Me sorprende que se vean tan bien en gris. Sin embargo, la dispersión de los números es extraña. ¿Estás usando RandomSamplepara elegir la ubicación?
Level River St
El gris funciona porque la opacidad es del 10%. Se usó RandomSample para elegir la ubicación. Una vez que se ha elegido una ubicación, se elimina del conjunto de candidatos para selecciones adicionales. Jugué con otros métodos (por ejemplo, empleando el centroide de una subregión, pero no me gustaron los resultados). Por cierto, me gusta su enfoque para ajustar las etiquetas.
DavidC
Para guardar caracteres, cambié a Circles, por lo que los discos grises se han ido. La mayor parte del ahorro proviene del hecho de que todos los miembros de una región están trazados en el centro de esa región.
DavidC
45

Ruby, 654 590 566 542 505 bytes

Esto fue divertido. Yo usé ASCII. Todavía no pude probar todas las combinaciones posibles, así que si encuentras un caso de prueba con fallas, avísame.

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 la entrada en STDIN en el siguiente formato

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

Y luego te recompensará con esta belleza

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

No creo que pueda molestarme en agregar una versión sin golf. Eche un vistazo a la versión original en el historial de edición para obtener una versión algo más legible.

Ciertamente, esto podría desarrollarse aún más al hacer que los límites establecidos sean menos ajustados o incluso mantenerlos fijos como lo hacen algunos de los gráficos, pero prefiero que se vea bien y se haga "correctamente" a pesar de jugar al golf.

Martin Ender
fuente
Si no hubieras alcanzado el límite de hoy, llegarías al club de 10 km hoy con esta respuesta, qué pena
William Barbosa
@WilliamBarbosa Quizás mañana me dé los votos positivos necesarios. ;)
Martin Ender
Es un bonito diagrama de Venn. Supongo que la apariencia del diagrama es la razón principal de todos sus votos. ¿Qué pasa con los sets más grandes? ¿Supongo que se mantiene a la misma altura y se vuelve cada vez más ancho?
Level River St el
@steveverrill sí exactamente. Cada uno de los 8 subconjuntos se imprime como una lista delimitada por espacios en la posición correcta. los límites tienen siempre la misma forma, y ​​se determina que el ancho de cada sección es el mínimo posible para acomodar todo dentro. por supuesto, podría verse mejor si calculé el salto de línea para mantener cada subconjunto aproximadamente cuadrado, pero, de nuevo, esto es código golf después de todo;). también se ve aún mejor sin el espacio adicional entre líneas
Martin Ender
1
Vi los pequeños caracteres angulares e hice una doble toma, pensando que era APL o algo así. :)
hoosierEE
15

BBC BASIC, 243 caracteres ASCII (tamaño de archivo tokenizado 211 bytes)

Descargue el emulador en http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Golfed

  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

BBC Basic es muy arbitrario acerca de las nuevas líneas / espacios en blanco que puede eliminar. Además de eliminar nuevas líneas innecesarias, hay otro truco aquí que no está en la versión no oculta: asigno la ventana gráfica (vea la explicación a continuación en los comentarios no reflejados) al FIN del ciclo de trazado, no al principio. Esto significa que los elementos fuera del conjunto se trazan en la parte superior izquierda y el cursor queda atrapado en una ventana en la parte superior derecha al final del programa. La razón de esto es eliminar el VDU26.

Sin golf

El usuario termina cada conjunto de números ingresando el número N + 1 (una opción ligeramente inusual, esto es para evitar errores causados ​​al intentar escribir fuera del rango de una matriz). Luego cambia de un modo de texto a un modo de gráficos y traza el diagrama de Venn.

Los datos de entrada se almacenan en una matriz, una celda para cada valor que se mostrará. Los datos se almacenan como un valor de 3 bits: 1 para Set0 + 2 para Set1 + 4 para Set2 dando un número en el rango de 0 a 7. BBC basic no tiene operador de turno, por lo que se utiliza el operador de potencia: en 2^ilugar de 1<<ien C por ejemplo.

Después de trazar los círculos, un bucle externo atraviesa cada una de las ocho regiones, moviéndose a las coordenadas requeridas (según una tabla de datos). Un bucle interno imprime todos los números en esa región (aquellos con el valor de 3 bits correspondiente en el formación.)

  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

Montaje de entrada y salida típicas (versión no protegida)

En la versión de golf, la posición de los números fuera de los conjuntos se intercambia con el símbolo del sistema >.

ingrese la descripción de la imagen aquí

Level River St
fuente
¿Funciona esto para entradas arbitrariamente grandes?
Martin Ender
@ MartinBüttner, en principio, sí, el algoritmo puede hacerlo, pero la pantalla lo decepciona (como es probable que sea el problema con otras soluciones). Sugiero en los comentarios del programa que cada región está limitada a 7 números antes de que comience a desplazarse ( los números están en una columna vertical, ya que pensé que la envoltura se vería horrible.) El emulador que estoy usando puede manejar resoluciones de pantalla mucho más altas, pero he optado por uno de los modos de micropantalla "auténticos" de la BBC que es bastante limitante. Si alguien transfiere esto a Java, el único límite práctico será la capacidad humana de leer el diagrama.
Level River St
Ah sí, me preguntaba si los círculos se adaptarían al tamaño de entrada ... por supuesto, mi solución también será ilegible para entradas grandes si su terminal envuelve las líneas, pero siempre que se muestre con barras de desplazamiento puede manejar cualquier entrada tamaño.
Martin Ender
2
incluso si esto se transfiriera a Java, tendría que agregar código para agrandar los círculos para obtener más texto
Sparr
14

Javascript 1235

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

Probado en google chrome v36.

La entrada se toma en las variables upper, set1, set2 y set3.

Actualización: ahora se escala automáticamente según el tamaño de la 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)}

Salida de muestra:

Venn

rdans
fuente
¡Bastante agradable! Pude apretarlo un poco más, vea jsfiddle.net/44a4L/2 - mire la función "t", CSS y body.innerHTML. Sin embargo, la misma lógica. Estoy seguro de que aún podría exprimirse.
Nenotlep
Este es el más hermoso hasta ahora, es una pena que no se adapte bien. Tres elementos dentro del área más interna hacen que se rompa. ¿Planeas hacerlo escalar de alguna manera?
William Barbosa
La escala de @WilliamBarbosa se implementa ahora
rdans
2
¡Maravilloso! ¡Maravilloso! ¡Espectacular! (Tuve que usar más de un superlativo porque SE odia la brevedad).
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)

La entrada es N seguida de los tres conjuntos, separados por comas (p 8, {1,2,4}, {2,3,4,5}, {4,6,8}. Ej .). Produce un conjunto en el arte ACSII como el siguiente:

+---+-+---+0 7
|1  | |3 5|
| +-+-+-+ |
| |2|4| | |
+-+-+-+-+-+
  |6 8  |
  +-----+
faubi
fuente
Jaja, dos soluciones casi idénticas en 5 minutos. (3 horas después de que se publicó el desafío ...)
Martin Ender
1
Consulte la nota número 6. Sus bordes y límites de cruce deben ser un carácter diferente, como "+".
William Barbosa
4

HTML + JavaScript (E6) 752 761

Formato de entrada: max set1 set2 set3 (cada conjunto es una lista de números separados por comas)

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

Captura de pantalla

Ejemplo 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 pantalla de Chrome

Tamaño automático de todas las secciones gracias a la representación 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>

La versión Javascript E5 funciona en Chrome y MSIE 10 (quizás 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>

No (tan) golfizado

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

¿Alguien más jugó con Logo cuando era niño?

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

ingrese la descripción de la imagen aquí

Jason S
fuente
¿La fuente / círculos se escalarán para una entrada arbitrariamente grande?
Sparr
No, sigo pensando en eso.
Jason S
@JasonS ¿Sigues pensando?
Jonathan Frech
3

perl 388b 346b 488b

Esto tiene una salida similar a otra 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]

Prueba de funcionamiento y salida:

# 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
fuente
Hm, no estoy seguro de que el diseño sea realmente inequívoco si no has visto la entrada.
Martin Ender
Tienes razón, esto no es suficiente
William Barbosa
@WilliamBarbosa ok, hice que pareciera la entrada de faubiguy
Sparr
2

T-SQL 2095

Supone que @N es un int que contiene N. Supone que @A, @B y @C son tablas que contienen los tres conjuntos de números. No traté de jugar al golf demasiado.

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

Versión menos golfizada:

--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
comentarios
fuente