Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created June 12, 2015 13:26
Show Gist options
  • Save sungkmi/427feeea078dde5a4f7d to your computer and use it in GitHub Desktop.
Save sungkmi/427feeea078dde5a4f7d to your computer and use it in GitHub Desktop.
object NoisyNeighbors extends App {
def unhappyness(r: Int, c: Int, n: Int): Int = {
if ((r * c + 1) / 2 >= n) 0
else {
case class Sites(val happy: Int, val one: Int, val two: Int, val three: Int, val four: Int) {
def +(that: Sites) = Sites(this.happy + that.happy, this.one + that.one, this.two + that.two, this.three + that.three, this.four + that.four)
}
def edgeRow(firstOccufied: Boolean): Sites = {
if (c == 1) {
if (firstOccufied) Sites(1, 0, 0, 0, 0) else Sites(0, 1, 0, 0, 0)
} else if (firstOccufied) Sites((c - 2 + 1) / 2, 0, 2, (c - 2) / 2, 0) else Sites((c + 1) / 2, 0, 0, c / 2, 0)
}
def unhappySites() = Set(
(Seq(false, true) map edgeRow).reduce(_ + _),
(Seq(true, false) map edgeRow).reduce(_ + _))
def getUnhappy(sites: collection.SortedMap[Int, Int], numberOfUnhappy: Int, acc: Int = 0): Int = {
println(sites, numberOfUnhappy, acc)
if (numberOfUnhappy <= 0) acc
else {
val (k, v) = sites.head
if (v == 0) getUnhappy(sites.tail, numberOfUnhappy, acc)
else if (v == 1) getUnhappy(sites.tail, numberOfUnhappy - 1, acc + k)
else getUnhappy(sites.tail + (k -> (v - 1)), numberOfUnhappy - 1, acc + k)
}
}
{
for {
Sites(happy, one, two, three, four) <- unhappySites()
} yield {
println(happy, one, two, three, four)
getUnhappy(collection.SortedMap(1 -> one, 2 -> two, 3 -> three, 4 -> four), n - happy)
}
}.min
}
}
def process(lineIn: Iterator[String])(lineOut: String => Unit) =
for (i <- 1 to lineIn.next().toInt) {
// lineOut(s"Case #$i: ${minCount(lineIn.next())}")
}
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 NoisyNeighbors._
class NoisyNeighborsTest extends FunSuite {
test("sample #1") {
assert(unhappyness(2, 3, 6) === 7)
}
test("sample #2") {
assert(unhappyness(4, 1, 2) === 0)
}
ignore("sample case") {
val input = """3
1
19
23""".lines
val expected = """Case #1: 1
Case #2: 19
Case #3: 15""".lines
lineComparison(input, expected)
}
ignore("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("A-large-practice.in").getLines()
val expected = io.Source.fromFile("A-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