Skip to content

Instantly share code, notes, and snippets.

@danielfone
Last active August 29, 2015 14:26
Show Gist options
  • Save danielfone/33558a021f29956afee0 to your computer and use it in GitHub Desktop.
Save danielfone/33558a021f29956afee0 to your computer and use it in GitHub Desktop.
a=n.gsub(?|,' ').split$/
i=!p;t=a.map(&:chars).transpose.map(&:join).select{i^=a}.sort_by{|s|s[/[A-Z]/][0]}
x=0;t.map{|t|y=0;u=p;t.chars{|c|u&&a[y][x,3]=?|*3;a[y][x+1]=c;y+=1;u|=c=='_'};x+=2}
a.join$/
def sort_books(n)
a = n.gsub(?|,' ') # pre-emptively remove all the '|'.
.split $/ # and split into an array of lines
# ($/ is the INPUT_RECORD_SEPARATOR, typically "\n")
# we're going to write our answer into `a` later
i = !p # i = true; we'll use this as a flip-flop variable
# Kernel#p returns nil with no args
# we're now going to get a sorted array of book titles (t)
t = a.map(&:chars) # break array into nested array of every character
.transpose # and transpose the entire array
.map(&:join) # this gives us an array of "horizontal" book titles with dividers
.select { i ^= a } # select every second line
# (i.e. just titles without dividers)
# `i` starts off true
# `a` is truish (it's our original array)
# `^=` is the bitwise xor assignment,
# it will alternate true/false on each execution
.sort_by { |s| s[/[A-Z]/][0] } # sort by the first alphabetical char
# use counters for less chars than `each_with_index`
# x and y are cartesian coordinates in the final array
x = 0 # start in the left-hand column
# go through each title
t.map { |t|
y = 0 # each book title starts on the top row
u = p # `u` is "have we reached the book's spine yet?" (or are we above it?)
# `u` starts off false and we'll set it true when we see the first '_'
# after which we'll start writing the book's edges
# go through each character of each title, including leading spaces and '_'s
# this will "descend" down the array writing each letter of the title
# along with the "edges"
t.chars { |c|
u && # if we're on the spine
a[y][x,3] = ?|*3; # write ||| in the next 3 columns
# the middle | will be overwriten by the title char
a[y][x+1] = c; # write the current title char into the second (x+1) column
y+=1; # descend to the next row
u |= c == '_' # Since '_' is the top and bottom of the book,
# this toggles whether we're on the spine
}
x += 2 # jump to the right 2 columns and start on the next title
}
a.join $/ # hopefully this is obvious
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment