Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created January 15, 2016 13:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sungkmi/a70d961e364506933f37 to your computer and use it in GitHub Desktop.
Save sungkmi/a70d961e364506933f37 to your computer and use it in GitHub Desktop.
object NewCalendar extends App {
def numberOfLines(totalMonths: Long, dayPerMonth: Int, dayPerWeek: Int): Long = {
@annotation.tailrec
def gcd(p: Int, q: Int): Int = if (q==0) p else gcd(q, p%q)
val lcm = dayPerMonth / gcd(dayPerMonth, dayPerWeek) * dayPerWeek
val (q, r) = (totalMonths / lcm, totalMonths % lcm)
//println(gcd(dayPerMonth, dayPerWeek), lcm, q, r)
val (rth, last, offset) = ((0, 0, 0) /: (1 to lcm)) {
case ((rth, last, offset), i) =>
//println(i, rth, last, offset)
val (q1, r1) = ((offset + dayPerMonth)/dayPerWeek, (offset + dayPerMonth)% dayPerWeek)
val ans = last + q1 + (if (r1==0) 0 else 1)
((if (i==r) ans else rth), ans, r1)
}
q * last + rth
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) =
for (i <- 1 to lineIn.next().toInt) {
val Array(totalMonths, dayPerMonth, dayPerWeek) = lineIn.next().split(' ').map(_.toLong)
lineOut(s"Case #$i: ${numberOfLines(totalMonths, dayPerMonth.toInt, dayPerWeek.toInt)}")
}
val filename = "A-large-practice"
val writer = new java.io.PrintWriter(filename + ".out")
try {
process(io.Source.fromFile(filename + ".in").getLines) { s =>
writer.println(s); writer.flush()
}
} finally {
writer.flush(); writer.close()
}
}
import org.scalatest._
import NewCalendar._
class NewCalendarTest extends FunSuite with Matchers {
test("sample #1") {
assert(numberOfLines(3, 11, 4) === 11)
}
test("sample #2") {
assert(numberOfLines(12, 28, 7) === 48)
}
test("small #17") {
assert(numberOfLines(17, 1, 8) === 17)
}
test("sample case") {
val input = """3
3 11 4
12 28 7
10 35 10""".lines
val expected = """Case #1: 11
Case #2: 48
Case #3: 40""".lines
lineComparison(input, expected)
}
test("full small case") {
val input = io.Source.fromFile("A-small-practice.in").getLines()
val expected = io.Source.fromFile("A-small-practice.out").getLines()
lineComparison(input, expected)
}
ignore("full large case") {
val input = io.Source.fromFile("B-large-practice.in").getLines()
val expected = io.Source.fromFile("B-large-practice.out").getLines()
lineComparison(input, expected)
}
def lineComparison(input: Iterator[String], expected: Iterator[String]) {
process(input) { s =>
for (line <- s.lines) assert(line.trim === expected.next().trim)
}
assert(expected.hasNext === false, "Finished too fast.")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment