Created
December 2, 2010 14:22
-
-
Save rklemme/725368 to your computer and use it in GitHub Desktop.
Change order of elements so labels precede their values
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test whether the given element is a month label | |
def is_label(o) | |
String === o | |
end | |
# exchange values at positions | |
def swap(arr, i, j) | |
# not using parrallel assignment since | |
# we want to avoid all the fancy stuff | |
x = arr[i] | |
arr[i] = arr[j] | |
arr[j] = x | |
end | |
# Input: array with Events followed by month | |
# Output: number of events without month at end | |
# Side effect: months precede their Events | |
def realign_months(arr) | |
start = 0 | |
i = 0 | |
while i < arr.length | |
if is_label(arr[i]) | |
# swap label and first | |
swap(arr, i, start) | |
# remember begin of next section | |
start = i + 1 | |
end | |
i += 1 | |
end | |
# remaining elements without month | |
return arr.length - start | |
end | |
# we add a field only for easier reading of output | |
Event = Struct.new :no | |
arr = [ | |
Event.new(1), | |
Event.new(2), | |
Event.new(3), | |
"January", | |
Event.new(4), | |
"February", | |
Event.new(5), | |
Event.new(6), | |
Event.new(7), | |
"March", | |
Event.new(8), | |
Event.new(9), | |
"April", | |
] | |
p arr | |
remainder = realign_months(arr) | |
p arr | |
if remainder > 0 | |
$stderr.puts "Last #{remainder} events are misaligned" | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# test whether the given element is a month label | |
def is_label(o) | |
String === o | |
end | |
# rotate the given sub section of the array | |
# by one to the right, inserting the last | |
# element at the beginning | |
def rotate_right(arr, first, last) | |
if first > last | |
# fix order, alternatively signal error | |
x = first | |
first = last | |
last = x | |
end | |
x = arr[last] | |
i = last | |
while i > first | |
arr[i] = arr[i - 1] | |
i -= 1 | |
end | |
arr[first] = x | |
end | |
# Input: array with Events followed by month | |
# Output: number of events without month at end | |
# Side effect: months precede their Events | |
def realign_months(arr) | |
start = 0 | |
i = 0 | |
while i < arr.length | |
if is_label(arr[i]) | |
rotate_right(arr, start, i) | |
# remember begin of next section | |
start = i + 1 | |
end | |
i += 1 | |
end | |
# remaining elements without month | |
return arr.length - start | |
end | |
# we add a field only for easier reading of output | |
Event = Struct.new :no | |
arr = [ | |
Event.new(1), | |
Event.new(2), | |
Event.new(3), | |
"January", | |
Event.new(4), | |
"February", | |
Event.new(5), | |
Event.new(6), | |
Event.new(7), | |
"March", | |
Event.new(8), | |
Event.new(9), | |
"April", | |
] | |
p arr | |
remainder = realign_months(arr) | |
p arr | |
if remainder > 0 | |
$stderr.puts "Last #{remainder} events are misaligned" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment