0
\$\begingroup\$

Problem

Spreadsheet cells are referenced by column and row identifiers. Columns are labeled with alphabetical characters, starting with "A", "B", "C", ...; rows are numbered from 1 in ascending order. Write a function that takes in a string identifying a range of cells in a spreadsheet and returns an ordered list of cells which compose that range.

Example:

"A3:D5" -> ["A3", "A4", "A5", "B3", "B4", "B5", "C3", "C4", "C5", "D3", "D4", "D5"]
"A3:D4" -> ["A3", "A4", "B3", "B4", "B5", "C3", "C4", "C5", "D3", "D4"]

Here is scala implementation of the same ,

import scala.language.postfixOps
object PrintSpreadSheet extends App {
 val validAlphabets = ('A' to 'Z').toSeq
 def cells(range: String): Seq[String] = {
 val corners = (range split ":") flatMap { corner =>
 Seq(corner.head, corner.last)
 }
 val rows = (corners filter (r => validAlphabets.contains(r))) sorted
 val cols = (corners filter (c => !validAlphabets.contains(c))) sorted
 (rows.head to rows.last) flatMap { r =>
 (cols.head to cols.last) map { c =>
 r.toString + ":" + c.toString
 }
 }
 }
 cells("A1:D5") foreach println
}
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jan 4, 2019 at 23:53
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

I couldn't get your code to compile until I took out the sorted. The output was still good so I don't know what purpose it was supposed to serve.

There's no point in casting validAlphabets to a Seq[Char]. As a Range[Char] the contains() method still works. Better still would be to cast it to a Set[Char]. Then the syntax is more concise and the lookup is faster.

val rows = corners filter validAlphabets
val cols = corners filter (!validAlphabets(_))

Due to the use of .head and .last, this solution won't handle rows past 9. There are also a number of input errors that it won't catch. These can be addressed if you use a Regex to parse the input.

def cells(range: String): Seq[String] = {
 val format = "([A-Z])(\\d+):([A-Z])(\\d+)".r
 val format(colStart, rowStart, colEnd, rowEnd) = range
 for {
 c <- colStart.head to colEnd.head //from String to Char
 r <- rowStart.toInt to rowEnd.toInt //from String to Int
 } yield s"$c:$r" //back to String
}

This will throw if the input string doesn't match the expected format. If you'd prefer it print the error and return nothing (an empty Seq[String]) then you can use a match statement instead, with a default case _ => for the format failure.

Notice that I use a for comprehension here. Whenever you see a map() inside a flatMap() that's a flag indicating that a for might do the same thing in a clearer/cleaner manner.

answered Jan 5, 2019 at 2:06
\$\endgroup\$
2
  • \$\begingroup\$ Code is compiling for me, here is same code in a online compiler scastie.scala-lang.org/eQxRuAvfR9qgCwNMiapGmg Also sorted is needed to handle input like "D5:A1" , else it will return empty seq. without sorted version - scastie.scala-lang.org/fD8FBWMDRRyzdvPvv4bazg I thought about using regex and agree it makes validation straightforward. But I am not very comfortable in writing regex (specially in an interview), learning it. How about working with Strings and using some thing like this - scala> ("A233" take 1, "A233" drop 1) res92: (String, String) = (A,233) \$\endgroup\$ Commented Jan 5, 2019 at 5:30
  • \$\begingroup\$ But I do agree regex is best and I should learn it. It makes it super simple. I accept it as a answer. \$\endgroup\$ Commented Jan 5, 2019 at 5:34
0
\$\begingroup\$

You're failing to handle columns beyond column Z (which should be AA) and rows beyond row 9. Your variable naming is also reversed: the columns are designated using letters and the rows are designated using numbers.

answered Jan 5, 2019 at 8:00
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.