Sort characters by darkness

Bash + ImageMagick: 164 147 148 characters

while read -n1 c
do
o=`convert -size 20x15 xc: +antialias -font cour.ttf -draw "text 0,10 '$c'" xpm:-`
o=${o//[^ ]}
a[${#o}]+=$c
done
echo "${a[@]}"

Sample run:

bash-4.1$ echo -n '@+.0' | bash graysort.sh
. + 0 @

Separators are inserted between grayness groups. Characters with identical grayness level are not separated:

bash-4.1$ echo -n 'abcdefghijklmnopqrstuvwxyz' | bash graysort.sh
i cl jortz esv ax u df bgnpq y hk w m

Mathematica, 112 110 108 bytes

This can still likely be golfed further. Assumes the string is in variable s.

And now uses a correct syntax to sort one list by another list.
Lucky test cases -> "Oh yeah, that works" -> Facepalm
Thanks for the sharp eyes, David Carraher.

Update: Replaced OCR A with Menlo because I realized that on OSX the OCR A font family name is actually OCR A Std. So I was sorting a default font instead of the real deal. Menlo is also monospaced with the same byte count, so no net gain or loss.

I've put up a hosted CDF export of the notebook, so you can see the code in action if you wish. I'm still figuring out how to add some interactivity to web-hosted CDFs, so for now it's just static.

c=Characters@s;Last/@Sort[Transpose@{Total[1-#&/@ImageData@Rasterize@Style[#,FontFamily->"Menlo"],3]&/@c,c}]

Output for s = FromCharacterCode /@ Range[33, 135]; with "Courier"

enter image description here

Output for same, but with FontFamily "Monospace":

enter image description here

Note that the final results are shown in MM's internal font, not in the font being sorted. Hence, you see the differences in the font chosen reflected in the sort. The CDF link shows both, though, for the completists.

Ungolfed code:

s = FromCharacterCode /@ Range[33, 135];
c = Characters@s;
Last /@ Sort[
    Transpose@{Total[1 - # & /@ 
        ImageData@Rasterize@Style[#, FontFamily -> "Menlo"], 3] & /@ c, c}]

QBasic, 259 bytes

SCREEN 1
DIM a(255)
FOR i = 32 TO 255
    CLS
    PRINT CHR$(i);
    FOR p = 0 TO 64
        a(i) = a(i) + POINT(p MOD 8, p \ 8)
    NEXT p
NEXT i
FOR p = 0 TO 96
    FOR i = 32 TO 255
        IF a(i) = p THEN PRINT CHR$(i);
    NEXT i
NEXT p

I did this for fun, so it's technically non-compliant to the rules in one way. It doesn't take a list of characters, but instead prints all characters from 32-255 and uses that instead. If you really want to see a version which complies with this rule, please tell me.

It also fails another technicality: "Furthermore, your program should be able to switch fonts by simply changing a variable or value or string in the code." There is no easy way to do this from within QBasic. However, the program will of course work fine with any codepage of your choosing.

Lastly, I could squeeze away a few characters (mostly whitespace that the QBasic IDE helpfully inserts,) but it's probably not worth it since this answer stands no chance of winning anyway.

QBasic sort characters by darkness

Tags:

Code Golf