Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I want to find similar letters

charList = CharacterRange["a", "l"];
ls = ImageData@Binarize@Rasterize@# & /@ charList;
Table[{i}~Join~Nearest[Complement[ls, {i}], i, 1], {i, ls}];
% /. Rule @@@ Table[{ImageData@Binarize@Rasterize@ii, ii}, {ii, charList}]
GraphPlot[Rule @@@ %, DirectedEdges -> True, VertexLabeling -> True]
Clear["`*"]

I think my code could be better. How can I refactor it?

share|improve this question
1  
Better in what way? Shorter? Easier for Mathematica novices to understand? –  Verbeia Jan 21 '13 at 9:01
    
I would like more Shorter. –  mathe Jan 21 '13 at 9:17
1  
Why? Trust me -- The main thing is that the code is readable (assuming performance is not a problem). –  Ajasja Jan 21 '13 at 12:46
add comment

1 Answer

up vote 6 down vote accepted

There isn't a lot wrong with your code, which I find quite sophisticated. The one thing I'd suggest is that the piece Table[{ImageData@Binarize@Rasterize@ii, ii}, {ii, charList}] isn't needed, since charList and ls already give you want you need with the simple use of Thread to put the Rule elements in.

The following gives the same result as your version:

charList = CharacterRange["a", "l"];
ls = ImageData@Binarize@Rasterize@# & /@ charList;
Table[{i}~Join~Nearest[Complement[ls, {i}], i, 1], {i, ls}] /. 
 Thread[ls -> charList]
GraphPlot[Rule @@@ %, DirectedEdges -> True, VertexLabeling -> True]

The one other thing I'd suggest, which is purely stylistic, is to avoid the use of % in code that you regularly use. It's ok if you are just experimenting, but there is always the risk that people will accidentally evaluate cells out of order, so that % isn't the thing you expect it to be. I would suggest naming the expression on the third line, like so:

charList = CharacterRange["a", "l"];
ls = ImageData@Binarize@Rasterize@# & /@ charList;
pairs = Table[{i}~Join~Nearest[Complement[ls, {i}], i, 1], {i, 
    ls}] /. Thread[ls -> charList]
GraphPlot[Rule @@@ pairs, DirectedEdges -> True,  VertexLabeling -> True]

Of course, this assumes that the expression now defined as pairs is giving the result you want. You could have different results depending on the font size and font family that Mathematica assumes when rasterizing text.

share|improve this answer
5  
A further tweak is to note that {i}~Join~Nearest[Complement[ls, {i}], i, 1] is the same as Nearest[ls, i, 2]. So you could define nf = Nearest[ls -> charList] and pairs = nf[#, 2] & /@ ls –  Simon Woods Jan 21 '13 at 9:29
    
Thanks. Dimensions /@ (ImageData@Binarize@Rasterize@# & /@ {l, m, n}) gives {{15, 7}, {15, 8}, {15, 7}}, it's not my expect. –  mathe Jan 21 '13 at 9:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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