Golf un générateur de diagramme de Venn


26

Golf un générateur de diagramme de Venn

entrez la description de l'image ici

Afin de célébrer correctement le 180e anniversaire de John Venn , votre tâche consistera aujourd'hui à créer un programme qui génère un diagramme de Venn !

Contribution:

Un entier positif Nqui définira la plage de nombres apparaissant dans le diagramme (de zéro à N) et trois ensembles d'entiers positifs.

Sortie:

Un diagramme de Venn à 3 ensembles montrant tous les entiers de 0 à Net les relations des ensembles en les affichant dans les régions appropriées du diagramme, semblable à celui-ci .

Remarques

  1. Utilisez stdin(ou l'équivalent de votre langue) pour obtenir les valeurs.
  2. Vous pouvez définir le format d'entrée pour les ensembles et pour N(Séparé par une virgule, une barre oblique ou tout ce qui vous convient le mieux).
  3. Les nombres qui n'apparaissent dans aucun des ensembles mais qui se trouvent dans la plage spécifiée doivent apparaître sur le diagramme, mais pas dans aucune région.
  4. Les ensembles n'ont pas besoin d'être nommés.
  5. La sortie peut être un dessin ou un art ascii.
  6. Le diagramme peut avoir n'importe quelle forme tant que les limites peuvent être distinguées sans ambiguïté (si vous avez choisi l'art ASCII, l'utilisation de + (ou similaire) pour franchir les limites est essentielle, par exemple).
  7. Les régions peuvent mais ne doivent pas être ombrées.
  8. Toutes les fonctions intégrées ou bibliothèques tierces qui génèrent des diagrammes de Venn sont interdites.
  9. Des échappatoires standard s'appliquent .

C'est le , donc le code le plus court, en octets, gagne.


Il semble que vous auriez dû ajouter une note indiquant que les solutions doivent évoluer pour des tailles d'entrée arbitraires. Actuellement, seuls quelques-uns d'entre eux le font (pour autant que je sache uniquement ceux ASCII). Je n'aime pas changer les règles après le début du concours, mais sans cette exigence, quelqu'un pourrait probablement vraiment en abuser avec une mise en page simple qui ne fonctionne que pour un caractère dans chaque jeu (si je le faisais, je réduirais probablement la taille du code à un tiers environ).
Martin Ender

@ MartinBüttner Oui, certains d'entre eux sont assez mauvais. Mais ajouter une note maintenant qu'il y a 7 réponses semble être une mauvaise idée. Doit ajouter la note et les commenter sur le post de tout le monde pour leur faire savoir que le diagramme doit bien évoluer jusqu'à X?
William Barbosa

La définition d'une limite permettra toujours de coder en dur cette limite. Je pense qu'une mise à l'échelle appropriée est en fait la partie la plus difficile du défi. Donc, laissez-le tel quel ou changez-le pour dire qu'il doit traiter des tailles de jeu arbitraires (ce qui n'est techniquement même pas un changement, car vous n'avez pas limité les tailles d'entrée, je pense que les tailles d'entrée arbitraires devraient être supposées de toute façon) .
Martin Ender

@Ryan Notez que je déclare "en les affichant dans les régions appropriées du diagramme" dans la section de sortie. Certaines réponses (les vôtres incluses) n'affichent pas correctement la section la plus intérieure si cette section contient plus de 5 éléments, donc je pense qu'elle n'est pas valide
William Barbosa

Réponses:


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

En supposant que l' 10entrée était met {{1,2,3,4,5,9},{1,2,3,6,8},{7,2,9}}était entrée pour d,

nouveau diagramme de venn


Golfé 264

J'ai été surpris que tout le calcul puisse être effectué dans la Graphicsfonction elle-même. À l'exception des entrées, il s'agit d'un monoligne.

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

+1 pour l'apparence des cercles. Je suis surpris qu'ils soient si beaux en gris. La dispersion des nombres est cependant étrange. Vous utilisez RandomSamplepour choisir l'emplacement?
Level River St

Le gris fonctionne car l'opacité est de 10%. RandomSample a été utilisé pour choisir l'emplacement. Une fois qu'un emplacement a été choisi, il est supprimé de l'ensemble des candidats pour des choix supplémentaires. J'ai joué avec d'autres méthodes (par exemple en utilisant le centroïde d'une sous-région, mais je n'ai pas aimé les résultats). BTW, j'aime votre approche de l'ajustement des étiquettes.
DavidC

Pour enregistrer des caractères, je suis passé à Circles, donc les disques gris ont disparu. La plupart des économies proviennent du fait que tous les membres d'une région sont tracés au centre de cette région.
DavidC

45

Rubis, 654 590 566 542 505 octets

C'était amusant. J'ai utilisé ASCII. Je n'ai pas encore pu tester toutes les combinaisons possibles, donc si vous trouvez un cas de test glitchy, faites le moi savoir.

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)+?┘

Il attend l'entrée sur STDIN dans le format suivant

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

Et vous récompensera ensuite avec cette beauté

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

Je ne pense pas que je puisse être dérangé pour ajouter une version non golfée. Veuillez consulter la version originale dans l'historique des modifications pour une version un peu plus lisible.

Cela pourrait certainement être joué plus loin en rendant les limites fixées moins serrées ou même en les maintenant fixes comme le font certaines des graphiques, mais je préfère que cela soit joli et se fasse "correctement" malgré le golf.


Si vous n'aviez pas atteint le plafond d'aujourd'hui, vous atteindriez le club 10K aujourd'hui avec cette réponse, quel dommage
William Barbosa

@WilliamBarbosa Peut-être que cela me donnera les votes positifs nécessaires demain. ;)
Martin Ender

C'est un joli diagramme de Venn. Je suppose que l'apparence du diagramme est la principale raison de tous vos votes positifs. Que se passe-t-il pour les ensembles plus grands? Je suppose qu'il reste à la même hauteur et devient de plus en plus large?
Level River St

@steveverrill oui exactement. chacun des 8 sous-ensembles est simplement imprimé comme une liste délimitée par des espaces dans la bonne position. les limites sont toujours de la même forme et la largeur de chaque section est déterminée comme étant le minimum possible pour tout rentrer à l'intérieur. bien sûr, cela pourrait sembler plus agréable si je calculais un saut de ligne pour garder chaque sous-ensemble à peu près carré, mais là encore c'est du code-golf après tout;). il semble aussi encore mieux sans l'espacement supplémentaire entre les lignes
Martin Ender

1
J'ai vu les petits personnages d'angle et fait une double prise, pensant que c'était APL ou quelque chose. :)
hoosierEE

15

BBC BASIC, 243 caractères ASCII (taille du fichier tokenisé 211 octets)

Téléchargez l'émulateur sur http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Golfé

  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 est très arbitraire sur les nouvelles lignes / espaces que vous pouvez éliminer. En plus de supprimer les nouvelles lignes inutiles, il y a une autre astuce ici qui n'est pas dans la version non golfée: j'affecte la fenêtre d'affichage (voir l'explication ci-dessous dans les commentaires non golfés) à la FIN de la boucle de traçage, pas au début. Cela signifie que les éléments en dehors de l'ensemble sont tracés en haut à gauche et que le curseur est piégé dans une fenêtre en haut à droite à la fin du programme. La raison en est d'éliminer le VDU26.

Non golfé

Chaque ensemble de nombres est terminé par l'utilisateur entrant le nombre N + 1 (un choix légèrement inhabituel, c'est pour éviter les erreurs causées en essayant d'écrire en dehors de la plage d'un tableau.) Ensuite, il passe d'un mode texte à un mode graphique et trace le diagramme de Venn.

Les données d'entrée sont stockées dans un tableau, une cellule pour chaque valeur à afficher. Les données sont stockées sous la forme d'une valeur de 3 bits: 1 pour Set0 + 2 pour Set1 + 4 pour Set2 donnant un nombre compris entre 0 et 7. BBC basic n'a pas d'opérateur shift, donc l'opérateur power est utilisé à la place: 2^iau lieu de 1<<iin C par exemple.

Après avoir tracé les cercles, une boucle externe parcourt chacune des huit régions, se déplaçant vers les coordonnées requises (selon un tableau de données.) Une boucle interne imprime tous les nombres de cette région (ceux avec la valeur correspondante de 3 bits dans le tableau.)

  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

Montage des entrées et sorties typiques (version non golfée)

Dans la version golfée, la position des numéros en dehors des ensembles est échangée avec l'invite de commande >.

entrez la description de l'image ici


Est-ce que cela fonctionne pour des entrées arbitrairement grandes?
Martin Ender

@ MartinBüttner en principe oui, l'algorithme peut le faire, mais l'affichage le laisse tomber (comme cela risque d'être le problème avec d'autres solutions.) Je laisse entendre dans les commentaires du programme que chaque région est limitée à 7 chiffres avant de commencer à défiler ( les chiffres sont dans une colonne verticale car je pensais que le wrapping serait horrible.) L'émulateur que j'utilise peut gérer des résolutions d'écran beaucoup plus élevées, mais j'ai opté pour l'un des modes de micro-écran BBC "authentiques" qui est assez limitant. Si quelqu'un le transfère à Java, la seule limite pratique sera la capacité humaine à lire le diagramme.
Level River St

Ah ouais, je me demandais simplement si les cercles s'adapteraient à la taille d'entrée ... bien sûr, ma solution sera également illisible pour les grandes entrées si votre terminal encapsule les lignes, mais tant qu'il est affiché avec des barres de défilement, il peut gérer n'importe quelle entrée Taille.
Martin Ender

2
même si cela a été porté sur java, vous devrez ajouter du code pour agrandir les cercles pour plus de texte
Sparr

14

Javascript 1235

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

Testé dans google chrome v36.

L'entrée est prise dans les variables supérieures, set1, set2 et set3.

Mise à jour: évolue désormais automatiquement en fonction de la taille de l'entrée.

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

Exemple de sortie:

Venn


Pas mal! J'ai pu le resserrer un peu plus, voir jsfiddle.net/44a4L/2 - regardez la fonction "t", CSS et body.innerHTML. Même logique cependant. Je suis sûr qu'il pourrait encore être pressé.
Nenotlep

C'est la plus belle à ce jour, c'est dommage qu'elle ne soit pas à l'échelle. Trois éléments à l'intérieur de la zone la plus intérieure le font casser. Prévoyez-vous de le faire évoluer d'une manière ou d'une autre?
William Barbosa

@WilliamBarbosa scaling is implement now
rdans

2
Magnifique! Étourdissant! Spectaculaire! (J'ai dû utiliser plus d'un superlatif parce que SE déteste la brièveté.)
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)

L'entrée est N suivie des trois ensembles, séparés par des virgules (par exemple 8, {1,2,4}, {2,3,4,5}, {4,6,8}). Il génère un ensemble dans l'art ACSII comme suit:

+---+-+---+0 7
|1  | |3 5|
| +-+-+-+ |
| |2|4| | |
+-+-+-+-+-+
  |6 8  |
  +-----+

Haha, deux solutions presque identiques en 5 minutes. (3 heures après l'annonce du challenge ...)
Martin Ender

1
Veuillez vous référer à la note numéro 6. Vos bords et les frontières qui traversent doivent être d'un caractère différent, tel que "+".
William Barbosa

4

HTML + JavaScript (E6) 752 761

Format d'entrée: max set1 set2 set3 (chaque ensemble est une liste de nombres séparés par des virgules)

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

Capture d'écran

Exemple 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

Capture d'écran de Chrome

Taille automatique de toutes les sections grâce au rendu 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 version Javascript E5 fonctionne dans Chrome et MSIE 10 (peut-être 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>

Pas (donc) joué au golf

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

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

Quelqu'un d'autre a-t-il joué avec Logo quand il était enfant?

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

entrez la description de l'image ici


la police / les cercles seront-ils mis à l'échelle pour une entrée arbitrairement grande?
Sparr

Non, je pense toujours à celui-là.
Jason S

@JasonS Vous pensez toujours?
Jonathan Frech

3

perl 388b 346b 488b

Cela a produit une sortie similaire à une autre entrée:

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

Test et sortie de test:

# 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|
 +------------------------------------------------+ 

Hm, je ne suis pas sûr que la disposition soit vraiment sans ambiguïté si vous n'avez pas vu l'entrée.
Martin Ender

Tu as raison, ce n'est pas assez venn-y
William Barbosa

@WilliamBarbosa ok, je l'ai fait ressembler à l'entrée de faubiguy
Sparr

2

T-SQL 2095

Suppose que @N est un entier contenant N. Suppose que @A, @B et @C sont des tableaux contenant les trois ensembles de nombres. Je n'ai pas trop essayé de jouer au golf.

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

Version moins golfée:

--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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.