ASCII-Art Venn Diagram

8

1

Given two lists that contain no duplicate elements a and b, find the crossover between the two lists and output an ASCII-Art Venn Diagram. The Venn Diagram will use a squarified version of the traditional circles for simplicity.

Example

Given:

a = [1, 11, 'Fox', 'Bear', 333, 'Bee']
b = ['1', 333, 'Bee', 'SchwiftyFive', 4]

Output (Order is 100% arbitrary, as long as the Venn Diagram is correct):

+-----+----+-------------+
|11   |333 |SchwiftyFive |
|Fox  |Bee |4            |
|Bear |1   |             |
+-----+----+-------------+

The program may either consider '1' == 1 or '1' != 1, up to your implementation. You may also choose to just handle everything as strings, and only accept string input.


Given:

a=[]
b=[1,2,3]

Output (Notice how the two empty parts still have the right-pad space):

+-+-+--+
| | |1 |
| | |2 |
| | |3 |
+-+-+--+

Given:

a=[1]
b=[1]

Output:

+-+--+-+
| |1 | |
+-+--+-+

Rules

  • Elements of the Venn Diagram are left-aligned and padded to the max length entry plus 1.
  • The ordering of the elements within sub-sections of the Venn-Diagram are arbitrary.
  • Corners of the Venn Diagram (where | meets -) must be represented by a +.
  • You are garuanteed that a.join(b).length() > 0, if both are empty, you may do whatever.
    • You may even print a picture of Abe Lincoln, don't care.
  • This is , and .

Bonus

Charcoal renders boxes like this naturally, but the whole set theory part... Don't know how well it does that. +100 bounty for the shortest charcoal submission before I am able to add a bounty to the question (2 days from being asked).

Magic Octopus Urn

Posted 2017-05-11T19:02:47.280

Reputation: 19 422

3Personally, I feel that being able to support '1' == 1 is a bit too much of a stretch – user41805 – 2017-05-11T19:07:16.067

@KritixiLithos fair enough, updated the challenge spec so that it doesn't hurt those who have started. It is now your choice on how you want string to integer comparison to work, both choices being equally valid submissions. – Magic Octopus Urn – 2017-05-11T19:09:10.940

1Can we assume that the input will only contain strings? – Rod – 2017-05-11T19:10:08.083

Related. – Martin Ender – 2017-05-11T19:12:13.180

@Rod well, to be honest, yeah, sure; lets just go with that. – Magic Octopus Urn – 2017-05-11T19:24:01.577

In the first example, why does the middle box have two right-padding spaces? – L3viathan – 2017-05-11T21:57:29.657

1@L3viathan one mobile edit and your post is over. – Magic Octopus Urn – 2017-05-11T22:13:53.380

Answers

2

Python 2, 221 210 212 bytes

m=map
A,B=m(set,input())
d=A-B,B&A,B-A
e=[max(m(len,s))+1for s in d]
p,i,n='+|\n'
o=b=p+p.join(m('-'.__mul__,e))+p+n
while sum(m(len,d)):o+=i+i.join(m(str.ljust,[len(s)and s.pop()or''for s in d],e))+i+n
print o+b

Try it online!

Rod

Posted 2017-05-11T19:02:47.280

Reputation: 17 588

Slightly wrong, you're missing the one space char right-pad. – Magic Octopus Urn – 2017-05-11T20:40:18.807

@carusocomputing fixed – Rod – 2017-05-11T21:41:54.113

2

PHP>=7.1, 287 Bytes

<?for([$a,$b]=$_GET,$x=max(($m=array_map)(count,$r=[($d=array_diff)($a,$b),array_intersect($a,$b),$d($b,$a)]));$n<3;$n++)for(sort($r[+$n]),$i=-1;$i<=$x;$i++){$o[$i].="|+"[$b=$i<0||$i==$x].str_pad($b?"":$r[+$n][$i],max($m(strlen,$r[+$n]))+1," -"[$b]).("|+"[$b][$n<2]);}echo join("
",$o);

Online Version

Expanded

for([$a,$b]=$_GET, # store input arrays in shorter variables
$x=max(($m=array_map)(count,   # get maximum of 
$r=[($d=array_diff)($a,$b),array_intersect($a,$b),$d($b,$a)])); #the set array
$n<3;$n++)
  for(sort($r[+$n]),$i=-1;$i<=$x;$i++){ # sort array to remove keys
    $o[$i].="|+"[$b=$i<0||$i==$x].   # concat line $b boolean for first and last line beginning char 
    str_pad($b?"":$r[+$n][$i]   # string of item in array if not first or last line
    ,max($m(strlen,$r[+$n]))+1  # fill till maximum length of items in array
    ," -"[$b]) # with char depends on first/last line or item line
    .("|+"[$b][$n<2]); # make end of string if last array is reach
}
echo join("   
",$o); #Output

Jörg Hülsermann

Posted 2017-05-11T19:02:47.280

Reputation: 13 026

2

Charcoal, 106 89 87 bytes:

A⟦⟧ςA⟦⟧λA⟦⟧ρA⟦⟧τWS⊞ςιWS⊞⎇№ςιτριFς⊞⎇№τι⟦⟧λιF⟦λτρ⟧«Fι«↓Pκ»MLι↑←A⁺⌈EιLκ³ζURζ⁺⌈⟦LλLτLρ⟧²Mζ→

Try it online! Note that link is to verbose code for explanatory purposes, with the -sl option that shows the equivalent native Charcoal code. Takes input as newline-separated strings with a blank line after each set.

Edit: Saved 11 bytes thanks to @ASCII-only. Previous version actually had a bug when the last word in the first set was not in the second set and also the first column was the tallest, which manifested as an apparently inability to optimise away a temporary. Saved 2 bytes by optimising two Move commands (the deverbosifier now does this automatically but the resulting code was always valid so the answer is still competing).

Edit: I don't think Multiprint used to work with multiline output but it does currently and making use of that would save 6 bytes, plus a further 4 bytes because current Charcoal preinitialises the u variable to the empty list: Try it online!

Neil

Posted 2017-05-11T19:02:47.280

Reputation: 95 035

Oh, if you want to print without moving the cursor, use Multiprint ()

– ASCII-only – 2017-05-11T22:45:14.380

Okay, 95 bytes, remember to remove commas/semicolons to remove delimiter in non-verbose form (will fix later), also Map exists (sorry, will document asap)

– ASCII-only – 2017-05-11T23:29:46.183

@ASCII-only Huh, well, I'm sure I tried Multiprint at some point, so I don't know why I wasn't able to get it to work. Also, thanks for Map, it helped me optimise the answer a bit more. Finally, I think Charcoal sometimes lets you use without an which would save a byte here, or is that a bug? – Neil – 2017-05-12T00:10:10.777

Directions without an are intentional (but always remember a direction with a variable after is a directional print) – ASCII-only – 2017-05-12T00:14:42.673

@ASCII-only Good, but that means that my Move(:Left); could just be instead of the M← that -dv generates. – Neil – 2017-05-12T00:25:18.533

1Okay, done, now all we need to do is wait for Dennis to pull for the better Move deverbosifying (it also now removes more unneeded separators so you'll be able to add the commas back in if you want) – ASCII-only – 2017-05-12T00:43:45.070

@ASCII-only Looks like it's live, thanks! – Neil – 2017-05-16T00:01:55.220