The Bible is divided up into books, each of which is divided into chapters, and the chapters are furthermore divided into verses. The number of verses in each chapter, and the number of chapters in each book, is a constant.
I’m given a book, chapter, and verse as an input. The result should be the position of this specific verse relative to the very first verse in the Bible.
So, for example the specific verse is at book 2, chapter 2, verse 2. Assuming there are 1,559 verses in the entire book 1, and 22 verses in chapter 2 of book 2, the result would be the total of all preceding verses in all preceding chapters and books, plus the number of verses preceding in the current book and chapter:
1,559 + 22 + 2
The relative verse number of the specific verse at book 2, chapter 2, verse 2 is thus 1,583. Or, put another way, the verse at book 2, chapter 2, verse 2 is the 1,583rd verse from the beginning of the bible.
One way to go about solving for this would be to drill down into all preceding chapters of all preceding books, summing the verses all the while. At the end, the verse number of the input would be added to account for verses in the current book in chapter. A quick throw-together in Ruby would look like this. Note this is not intended to be a Ruby-specific question, but a question about general algorithm design.
class Chapter attr_accessor(:verses) end class Book attr_accessor(:chapters) end class Volume attr_accessor(:books) end def get_relative_verse(book, chapter, verse) # assuming returns type Volume, with all books, chapters, and verses filled in vol = entire_bible verse_sum = 0 # track how many verses from beginning # loop through preceding books book_index = 0 while book_index < book # apply summing function to all verses of all chapters of this book verse_sum += vol.books[book_index].chapters.sum{|c| c.verses} book_index += 1 end # loop through preceding chapters of current book chapter_index = 0 while chapter_index < chapter verse_sum += vol.books[book_index].chapters[chapter_index].verses chapter_index += 1 end # finally, add verses of current chapter of current book verse_sum += verse return verse_sum end
In the final analysis, this is a function that deals with nested collections as an input, and ‘flattens’ the collections to give an output… surely a computing problem that has been addressed before. Ignoring syntatic sugar and built-in language or library features, and focusing on the general design principles, are there more elegant ways to accomplish this functionality?