patternrubyMinor
Twisting words! (boustrophedon formatting)
Viewed 0 times
boustrophedonformattingwordstwisting
Problem
I decided to implement properly the Code Golf challenge about twisting strings. I report the assignement verbatim for convenience:
Twisting Words!
Given a string and a positive integer. You must twist the string, back
and forth.
Example Input / Output
Input
Output
Input
The input can be taken in through STDIN, or function argument. The
input will consist of a string and a positive integer, n. The
integer will determine the length of each twisted line.
The string is twisted back-and-forth. An input of
5 would look like:
Output
The output will be the twisted text. It may not any trailing
whitespace. If the input string length is not divisible be the line
length, add a space until the line is filled:
An example of this: Input
Output (Note the whitespace at the very end)
My implementation
Twisting Words!
Given a string and a positive integer. You must twist the string, back
and forth.
Example Input / Output
Input
Programming Puzzles & Code Golf
4
Output
Prog
mmar
ing
zzuP
les
oC &
de G
flo
Input
The input can be taken in through STDIN, or function argument. The
input will consist of a string and a positive integer, n. The
integer will determine the length of each twisted line.
The string is twisted back-and-forth. An input of
HELLO, WORLD! and5 would look like:
Output
The output will be the twisted text. It may not any trailing
whitespace. If the input string length is not divisible be the line
length, add a space until the line is filled:
An example of this: Input
Hello, World!
5
Output (Note the whitespace at the very end)
Hello
roW ,
ld!
My implementation
def twist(text, chunk_size)
text
.+(" " * ((text.length % chunk_size) - 1))
.chars
.each_slice(chunk_size)
.each_with_index
.map {|str, i| i.odd? ? str.reverse : str}
.map(&:join)
.join("\n")
end
puts twist("Hello, World!", 5)
puts
puts twist("foo bar baz", 7)
Solution
Looks fine to me. Only thing I'd change is the way the padding is done: You can use
You can also use the
Of course there are several approaches to this. For instance, you needn't necessarily use
I won't say it's a better solution, though. Fewer lines, sure, but the interpolated regex isn't pretty. But again, it's just to show an alternative approach.
You can also move the
It's obviously it's kinda brute-force, since we know that it'd only be the last chunk that could require padding. But again: Just an alternative.
ljust instead, which seems a little more appropriate to me. Something like:.ljust(text.length.fdiv(chunk_size).ceil * chunk_size, " ")You can also use the
with_index modifier on map instead of doing a separate each_with_index, i.e.:.map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }Of course there are several approaches to this. For instance, you needn't necessarily use
chars and then join. For instance:def twist(text, chunk_size)
text
.ljust(text.length.fdiv(chunk_size).ceil * chunk_size, " ")
.scan(%r/.{#{chunk_size}}/)
.map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }
.join("\n")
endI won't say it's a better solution, though. Fewer lines, sure, but the interpolated regex isn't pretty. But again, it's just to show an alternative approach.
You can also move the
ljust, to avoid the long'ish bit of arithmetic:def twist(text, chunk_size)
text
.scan(%r/.{1,#{chunk_size}}/)
.map { |chunk| chunk.ljust(chunk_size, " ") }
.map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }
.join("\n")
endIt's obviously it's kinda brute-force, since we know that it'd only be the last chunk that could require padding. But again: Just an alternative.
Code Snippets
.ljust(text.length.fdiv(chunk_size).ceil * chunk_size, " ").map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }def twist(text, chunk_size)
text
.ljust(text.length.fdiv(chunk_size).ceil * chunk_size, " ")
.scan(%r/.{#{chunk_size}}/)
.map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }
.join("\n")
enddef twist(text, chunk_size)
text
.scan(%r/.{1,#{chunk_size}}/)
.map { |chunk| chunk.ljust(chunk_size, " ") }
.map.with_index { |chunk, index| index.odd? ? chunk.reverse : chunk }
.join("\n")
endContext
StackExchange Code Review Q#101738, answer score: 3
Revisions (0)
No revisions yet.