Гольф генератор Венна Диаграммы

26

Гольф генератор Венна Диаграммы

введите описание изображения здесь

Чтобы правильно отпраздновать 180-летие Джона Венна , сегодня ваша задача - создать программу для вывода диаграммы Венна !

Входные данные:

Целое положительное число, Nкоторое будет определять диапазон чисел, отображаемых на диаграмме (от нуля до N), и три набора целых положительных чисел.

Выход:

Диаграмма Венна с тремя наборами, показывающая все целые числа от 0 до Nи отношения множеств, отображая их в соответствующих областях диаграммы, аналогично этой .

Заметки

  1. Используйте stdin(или любой другой эквивалент вашего языка), чтобы получить значения.
  2. Вы можете определить формат ввода для наборов и для N(разделенных запятой, косой чертой или любым другим, который вам больше подходит).
  3. Числа, которые не появляются ни в одном из наборов, но находятся в указанном диапазоне, должны появляться на диаграмме, но не внутри какой-либо области.
  4. Наборы не должны быть названы.
  5. На выходе может быть рисунок или ascii-art.
  6. Диаграмма может иметь любую форму, если границы однозначно различимы (например, если вы выбрали искусство ASCII, важно использовать + (или аналогичный) для пересечения границ).
  7. Области могут быть, но не должны быть затенены.
  8. Любые встроенные функции или сторонние библиотеки, которые генерируют диаграммы Венна, запрещены.
  9. Применяются стандартные лазейки .

Это , поэтому выигрывает самый короткий код в байтах.

Уильям Барбоза
источник
Похоже, вы должны были добавить примечание, что решения должны масштабироваться для произвольных входных размеров. В настоящее время только немногие из них делают это (насколько я могу судить только ASCII). Я не люблю менять правила после начала конкурса, но без этого требования кто-то мог бы действительно злоупотребить им с помощью простого макета, который работает только для одного символа в каждом наборе (если бы я это сделал, я бы, вероятно, сократил размер кода). до трети или около того).
Мартин Эндер
@ MartinBüttner Да, некоторые из них плохо масштабируются. Но добавление примечания теперь, когда есть 7 ответов, кажется плохой идеей. Следует добавить примечание и прокомментировать каждый пост, чтобы они знали, что диаграмма должна масштабироваться до X?
Уильям Барбоза
Установка предела все еще позволяет жестко запрограммировать этот предел. Я думаю, что правильное масштабирование на самом деле является самой сложной частью задачи. Так что либо оставьте все как есть, либо измените его, указав, что он должен иметь дело с произвольными размерами набора (что технически даже не является изменением, поскольку вы не ограничивали входные размеры, я думаю, что входные размеры arbirtrary должны быть приняты в любом случае) ,
Мартин Эндер
@Ryan Обратите внимание, что в разделе «Вывод» я заявляю «отображая их в соответствующих областях диаграммы». Некоторые ответы (включая ваш) не отображают самый внутренний раздел правильно, если в указанном разделе более 5 элементов, поэтому я думаю, что он недействителен
Уильям Барбоза
Соответствующий xkcd: xkcd.com/1810
sergiol

Ответы:

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

Предполагая, 10был вход для mи {{1,2,3,4,5,9},{1,2,3,6,8},{7,2,9}}был вход для d,

новая диаграмма Венна


Гольф 264

Я был удивлен, что все вычисления могут быть выполнены внутри самой Graphicsфункции. За исключением входов, это однострочник.

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
источник
+1 за появление кругов. Я удивлен, что они так хорошо выглядят в сером. Разброс чисел странный, хотя. Вы используете, RandomSampleчтобы выбрать место?
Уровень Ривер Ст
Серый работает, потому что непрозрачность составляет 10%. RandomSample использовался, чтобы выбрать местоположение. Как только местоположение было выбрано, оно удаляется из набора кандидатов на дополнительные выборы. Я играл с другими методами (например, используя центроид субрегиона, но результаты мне не понравились). Кстати, мне нравится ваш подход к подгонке этикеток.
DavidC
Для сохранения символов я перешел на Circles, чтобы серые диски пропали. Большая часть экономии происходит из-за того, что все члены региона расположены в центре этого региона.
DavidC
45

Рубин, 654 590 566 542 505 байт

Это было весело Я использовал ASCII. Я еще не смог протестировать каждую возможную комбинацию, поэтому, если вы обнаружите сбойный тестовый пример, пожалуйста, дайте мне знать.

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

Ожидается ввод на STDIN в следующем формате

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

И тогда наградит вас этой красотой

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

Я не думаю, что я могу быть обеспокоен тем, чтобы добавить версию без гольфа. Пожалуйста , обратите внимание на оригинальную версию в истории редактирования для нескольких более читаемой версии.

Это, конечно, может быть сделано в дальнейшем, сделав границы набора менее узкими или даже оставив их неподвижными, как делают некоторые из графических, но я предпочитаю, чтобы это выглядело хорошо и было сделано "правильно", несмотря на то, что играли в гольф.

Мартин Эндер
источник
Если бы вы не достигли сегодняшней кепки, вы бы получили сегодня 10К клуб с таким ответом, как жаль
Уильям Барбоза
@WilliamBarbosa Может быть, это даст мне необходимые отзывы завтра. ;)
Мартин Эндер
Это красивая диаграмма Венна. Я предполагаю, что появление диаграммы - главная причина всех ваших голосов. Что происходит с большими сетами? Я предполагаю, что это остается той же высоты и становится все шире и шире?
Уровень Река St
@steveverrill да, именно так. каждое из 8 подмножеств просто печатается в виде списка с разделителями-пробелами в правильной позиции. границы всегда имеют одинаковую форму, и ширина каждой секции определяется как минимально возможная, чтобы вместить все внутри. конечно, это может выглядеть лучше, если бы я вычислял разрыв строки, чтобы держать каждое подмножество примерно квадратным, но опять же, в конце концов, это код-гольф;). также это выглядит еще лучше без дополнительного интервала между линиями
Мартин Эндер
1
Видел малоугловых персонажей и делал двойной дубль, думая, что это APL или что-то в этом роде. :)
hoosierEE
15

BBC BASIC, 243 символа ASCII (токенизированный размер файла 211 байт)

Загрузите эмулятор на 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 очень произвольно говорит о том, какие символы новой строки / пробелы вы можете устранить. Помимо удаления ненужных новых строк, здесь есть еще один трюк, которого нет в версии без заглядывания: я назначаю область просмотра (см. Объяснение ниже в комментариях без заглавных букв) в конце цикла построения, а не в начале. Это означает, что элементы вне набора отображаются в верхнем левом углу, а курсор попадает в область просмотра в правом верхнем углу в конце программы. Причиной этого является устранение VDU26.

Ungolfed

Каждый набор чисел завершается тем, что пользователь вводит число N + 1 (немного необычный выбор, чтобы избежать ошибок, вызванных попыткой записи вне диапазона массива.) Затем он переходит из текстового режима в графический режим. и строит диаграмму Венна.

Входные данные хранятся в массиве, по одной ячейке для каждого отображаемого значения. Данные хранятся в виде 3-битного значения: 1 для Set0 + 2 для Set1 + 4 для Set2, что дает число в диапазоне от 0 до 7. BBC basic не имеет оператора сдвига, поэтому вместо 2^iнего используется оператор power: вместо 1<<iin С например.

После построения окружностей внешний цикл проходит через каждую из восьми областей, перемещаясь к требуемым координатам (согласно таблице данных). Внутренний цикл печатает все числа в этой области (с соответствующими 3-битными значениями в массив).

  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

Монтаж типичного ввода и вывода (негольфированная версия)

В версии для игры в гольф позиция чисел вне наборов заменяется командной строкой >.

введите описание изображения здесь

Уровень реки St
источник
Это работает для произвольно больших входов?
Мартин Эндер,
@ MartinBüttner в принципе, да, алгоритм может это сделать, но дисплей подводит его (что, вероятно, является проблемой других решений). Я намекаю в комментариях программы, что каждая область ограничена 7 числами, прежде чем она начнет прокручиваться ( числа расположены в вертикальном столбце, так как я думал, что перенос будет выглядеть ужасно.) Эмулятор, который я использую, может работать с гораздо более высокими разрешениями экрана, но я выбрал один из «подлинных» режимов микро экрана BBC, который довольно ограничен. Если кто-то перенесет это на Java, единственным практическим ограничением будет способность человека читать диаграмму.
Уровень Река St
Ах да, мне просто интересно, будут ли круги адаптироваться к размеру ввода ... конечно, мое решение также будет нечитаемым для больших вводов, если ваш терминал обернет строки, но пока он отображается с полосами прокрутки, он может обрабатывать любой ввод размер.
Мартин Эндер
2
даже если бы это было перенесено на Java, вам нужно было бы добавить код, чтобы сделать круги больше для большего объема текста
Sparr
14

Javascript 1235

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

Проверено в Google Chrome v36.

Вход берется в переменные upper, set1, set2 и set3.

Обновление: теперь автоматически масштабируется в зависимости от размера ввода.

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

Образец вывода:

Венна

rdans
источник
Довольно мило! Я смог сжать его немного крепче, см. Jsfiddle.net/44a4L/2 - посмотрите на функцию "t", CSS и body.innerHTML. Та же логика, хотя. Я уверен, что это все еще можно сжать.
Ненотлеп
Пока это самый красивый, жаль, что он плохо масштабируется. Три элемента в самой внутренней области заставляют это сломаться. Планируете ли вы как-нибудь масштабировать его?
Уильям Барбоза
Масштабирование @WilliamBarbosa теперь реализовано
rdans
2
Великолепный! Оглушающий! Захватывающий! (Пришлось использовать более одной превосходной степени, потому что SE ненавидит краткость.)
Скотт Лидли
4

Питон - 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)

На входе N следуют три набора, разделенные запятыми (например 8, {1,2,4}, {2,3,4,5}, {4,6,8}). Это выводит набор в искусстве ACSII как следующее:

+---+-+---+0 7
|1  | |3 5|
| +-+-+-+ |
| |2|4| | |
+-+-+-+-+-+
  |6 8  |
  +-----+
faubi
источник
Ха-ха, два почти идентичных решения в течение 5 минут. (3 часа после того, как вызов был опубликован ...)
Мартин Эндер
1
Пожалуйста, обратитесь к примечанию № 6. Ваши края и границы пересечения должны быть другого символа, например, «+».
Уильям Барбоза
4

HTML + JavaScript (E6) 752 761

Формат ввода: max set1 set2 set3 (каждый набор представляет собой разделенный запятыми список чисел)

Пример: 10 1,2,3,4,5,9 1,2,3,6,8 7,2,9

Скриншот

Пример 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

Скриншот Chrome

Все размеры разделов автоматически благодаря 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>

Версия Javascript E5 Работает в Chrome и MSIE 10 (возможно, 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>

Не так

<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
источник
3

Питон 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()

Кто-нибудь еще играл с Logo в детстве?

Образец: python3 turtletest.py 15 1,2,3,4,5,9,10,12 1,3,4,6,7,9 1,2,7,8,9

введите описание изображения здесь

Джейсон С
источник
будет ли шрифт / круги масштабироваться для произвольно большого ввода?
Спарр
Нет, все еще думаю об этом.
Джейсон С
@JasonS Все еще думаешь?
Джонатан Фрех
3

Perl 388b 346b 488b

Это имеет вывод, похожий на другую запись:

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

Тестовый прогон и вывод:

# 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
источник
Хм, я не уверен, что макет действительно однозначный, если вы не видели вход.
Мартин Эндер
Вы правы, это не Венна-й достаточно
Уильям Барбоса
@WilliamBarbosa хорошо, я сделал это выглядит как запись faubiguy в
Sparr
2

T-SQL 2095

Предполагается, что @N - это int, содержащее N. Предполагается, что @A, @B и @C - это таблицы, содержащие три набора чисел. Не пытался играть в гольф слишком много.

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

Менее гольф-версия:

--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
bmarks
источник