1
$\begingroup$

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?

$\endgroup$
3
  • 1
    $\begingroup$ Better in what way? Shorter? Easier for Mathematica novices to understand? $\endgroup$
    – Verbeia
    Jan 21, 2013 at 9:01
  • $\begingroup$ I would like more Shorter. $\endgroup$
    – matrix42
    Jan 21, 2013 at 9:17
  • 1
    $\begingroup$ Why? Trust me -- The main thing is that the code is readable (assuming performance is not a problem). $\endgroup$
    – Ajasja
    Jan 21, 2013 at 12:46

1 Answer 1

6
$\begingroup$

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.

$\endgroup$
2
  • 5
    $\begingroup$ 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 $\endgroup$ Jan 21, 2013 at 9:29
  • $\begingroup$ Thanks. Dimensions /@ (ImageData@Binarize@Rasterize@# & /@ {l, m, n}) gives {{15, 7}, {15, 8}, {15, 7}}, it's not my expect. $\endgroup$
    – matrix42
    Jan 21, 2013 at 9:45

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.