11
\$\begingroup\$

The code should take text from standard input:

The definition of insanity is quoting the same phrase again and again and not expect despair.

The output should be a PNG file containing the word cloud corresponding to that text:

enter image description here

The above word cloud was created using a specialized online application and it filtered the word The and other common words (of, is, and, not, and the). Since this is code golf, the common words will not be filtered and I leave secondary aesthetics of the word cloud to the choice of each coder. Unlike the image exampled here, no words should be excluded, common or otherwise. The definition of a word is defined below.

In this case a word is anything alpha-numeric; numbers are not acting as separators. So, for example, 0xAF qualifies as a word. Separators will be anything that is not alpha-numeric, including .(dot) and -(hyphen). Thus i.e. or pick-me-up would result in 2 or 3 words, respectively. Should be case sensitive - This and this would be two different words, ' would also be separator so wouldn and t will be 2 different words from wouldn't.

The tags should appear clustered but not overlapping and the font size should be directly proportional to the number of occurrences of that word in the text. The word should appear only once. Specific font color is not required in this case. Semantic association is not a requirement.

Hint - This other code golf could help: Count the words in a text and display them

\$\endgroup\$
12
  • \$\begingroup\$ Please explain what you consider a word cloud. Also I don't understand your output definitions. Can you please clarify what you mean by output should be printed with new line after each character? \$\endgroup\$
    – Howard
    Commented Mar 20, 2014 at 11:44
  • 3
    \$\begingroup\$ The sample image doesn't seem to match the requirements. It also creates a question about how many times each word should appear in the cloud, which you don't answer anywhere. \$\endgroup\$ Commented Mar 20, 2014 at 12:16
  • 2
    \$\begingroup\$ @TimSeguine I don't think code-golf submissions have any kind of reusability... \$\endgroup\$ Commented Mar 20, 2014 at 13:50
  • 1
    \$\begingroup\$ @TimSeguine Legitimate concern, but why would I need it when there are scores of free apps to do that. \$\endgroup\$ Commented Mar 20, 2014 at 13:57
  • 1
    \$\begingroup\$ Your word cloud creator also seems to have filtered of, is, and, not, and the. \$\endgroup\$
    – Doorknob
    Commented Mar 20, 2014 at 13:59

2 Answers 2

7
\$\begingroup\$

Output example

Python 3, 363 308 293 274 characters

import os,sys,re,collections as C
c=C.Counter()
n=sys.argv[1]
o="graph d{"
for w in re.findall("\w*",open(n).read()):c[w]+=1
for w,x in c.most_common(75)[1:]:o+="%s[fontsize=%s,shape=none];"%(w,x/5)
open(n+'.dot','w').write(o+"}")
os.system("fdp -Tpng %s.dot>%s.png"%(n,n))

Call it like this: python cloud.py file.txt. The script uses Graphviz's fdp force-directed graph generator to generate the image (it will spit out a GraphViz file to file.txt.dot and a PNG image file to file.txt.png). This means you'll need to have Graphviz installed.

The image above is the cloud it makes of Shakespeare's Hamlet - you can tell, since it contains "To be or not to be". There's also some delightful nonsense to be found:

It is, to You and I, the Ham of Not thatO lord have us, what now...

\$\endgroup\$
1
  • \$\begingroup\$ You may need to tweak the constant /5 in the second-to-last line depending on how large your text is. 5 works well for Hamlet-sized texts, 500 for Bible-length input and so on. \$\endgroup\$ Commented Mar 20, 2014 at 14:25
5
\$\begingroup\$

JAVASCRIPT 473

var wordCloud=function(e){var t=e.split(/[\s-.,;]+/);var n={},r;for(r in t){var i=t[r];n[i]=n[i]+1||1}var s=document;var o=s.createElement("canvas");o.width=600;o.height=400;o.style.display="none";s.body.appendChild(o);var u=o.getContext("2d");var a=0,f=50;for(var i in n){u.font=n[i]*50+"px monospace";u.fillText(i,a,f+n[i]*5);a+=i.length*n[i]*50;if(a>o.width*.6){a=0;f+=n[i]*5+100}}var l=o.toDataURL("image/png");var c=s.createElement("img");c.src=l;s.body.appendChild(c)}

Ungolfed demo

wordCloud("string;abc,test-omg shouldn't test omg lalala. s2 s2 s2")

enter image description here

\$\endgroup\$
8
  • \$\begingroup\$ Are you sure this produces a PNG file? \$\endgroup\$
    – manatwork
    Commented Mar 20, 2014 at 13:57
  • \$\begingroup\$ Now it does !!! \$\endgroup\$
    – user15260
    Commented Mar 21, 2014 at 12:07
  • 1
    \$\begingroup\$ Regarding the golfing, this shortened version seems to do it in 360 characters: pastebin.com/C4dpYLP8 \$\endgroup\$
    – manatwork
    Commented Mar 21, 2014 at 12:45
  • 3
    \$\begingroup\$ ...296 characters: pastebin.com/5BUPavYH \$\endgroup\$ Commented Mar 22, 2014 at 5:04
  • 1
    \$\begingroup\$ I'm also going to golf this even more into 405 bytes. Try it here! \$\endgroup\$ Commented Jul 30, 2016 at 3:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.