Last night, I had a great time collaborating with Michael and Andres as we shared ideas back and forth on how to rewrite the following method:
paddedBinaryPrintString
"Answer the base two representation of the receiver, with the output
being split into groups of 8 bits each"
| binaryDigits paddedSize paddedString binaryStream |
binaryDigits := self abs printStringRadix: 2.
paddedSize := binaryDigits size.
binaryDigits size \\ 8 > 0 ifTrue: [paddedSize := paddedSize + 8 - (binaryDigits size \\ 8)].
paddedString := String new: paddedSize withAll: $0.
paddedString replaceFrom: paddedSize - binaryDigits size + 1 to: paddedSize with: binaryDigits.
binaryStream := String new writeStream.
self < 0 ifTrue: [binaryStream nextPutAll: '-'].
(1 to: binaryDigits size by: 8)
do:
[:base |
binaryStream nextPutAll:
(paddedString copyFrom: base to: base + 7)
]
separatedBy: [binaryStream space].
^binaryStream contents
This is a slightly fixed version of what you'll find in VisualWorks 7.6. The goal of this method is to print integers in binary format, where they're shown as chunks of 8 0/1's separated by space. E.g:
00001010 11001101 11100010
01001010 00100010 10000011
It was a fun discussion on whether one solution was more mathematical (relying more on integer behaviors to get the right output) versus those that were more stringy (print it up front a
Some were more serious than others; I did one where I actually formed the string backwards, and then reversed the contents on the final return. Two gems that I thought I'd put here. I did a recursive version:
paddedBinaryPrintString
"Answer the base two representation of the receiver, with the output
being split into groups of 8 bits each."
"Use recursion to break the problem down into chunks of 8 nicely."
| ws |
self < 0 ifTrue: [^'-' , self abs paddedBinaryPrintString].
ws := (String new: 8) writeStream.
self \\ 256 printOn: ws paddedWith: $0 to: 8 base: 2.
^self > 256
ifTrue: [(self // 256) paddedBinaryPrintString , ' ' , ws contents]
ifFalse: [ws contents]
This inspired Andres to exploit an API I've rarely really used or been aware of:
paddedBinaryPrintString
"Answer the base two representation of the receiver, with the output
being split into groups of 8 bits each. Each digit is a byte of the receiver"
| result |
self < 0 ifTrue: [^'-', self negated paddedBinaryPrintString].
result := String new writeStream.
(self digitLength to: 1 by: -1)
do:
[:eachDigitIndex |
(self digitAt: eachDigitIndex)
printOn: result
paddedWith: $0
to: 8
base: 2
]
separatedBy: [result space].
^result contents
Michael had some nice ones too (I just don't have them sitting here digitally to share, well I would if I wasn't too lazy to dig through Skype Logs). I thought it'd be fun to through it out there, and see if others had another way to write the method. Go for funny. Go for fast. Go for creative. Go for elegant. Go for readable. Whatever. Put your version in the comments.
I'll try to do one of these a week.