Tom is a boy whose dream is to become a scientist, he invented a lot in his spare time. He came up with a great idea several days ago: to make a stopwatch by himself! So he bought a seven-segment display immediately.app
The seven elements of the display are all light-emitting diodes (LEDs) and can be lit in different combinations to represent the arabic numerals like:ide
However, just when he finished the programs and tried to test the stopwatch, some of the LEDs turned out to be broken! Some of the segments can never be lit while others worked fine. So the display kept on producing some ambiguous states all the time...this
Tom has recorded a continuous sequence of states which were produced by the display and is curious about whether it is possible to understand what this display was doing. He thinks the first step is to determine the state which the display will show next, could you help him?idea
Please note that the display works well despite those broken segments, which means that the display will keep on counting down cyclically starting from a certain number (can be any one of 0-9 since we don't know where this record starts from). 'Cyclically' here means that each time when the display reaches 0, it will keep on counting down starting from 9 again.spa
For convenience, we refer the seven segments of the display by the letters A to G as the picture below:pwa
基本的想法是:scala
先假設全部的節點,都處於不肯定的狀態(2),根據後續的匹配驗證,更新節點的狀態,該節點正常爲1,不正常爲0;code
從9到0(或者從0到9)開始的倒序數列與輸入的數列進行匹配驗證;orm
驗證到某個輸入時,檢查是否出現矛盾;若是出現,那麼廢棄此次嘗試,更新起點,從新驗證;若是沒有矛盾,更新節點的狀態,並繼續;ci
9 ~ 0,驗證完畢後,只產生了一個輸出,那麼該輸出即爲結果; 若是出現多於一個的結果,或者,在驗證某個序列的時候,最終的節點狀態,某個節點仍未知,且該節點要輸出1,也代表沒法肯定結果;
代碼以下:
import codejam.FileOp /** * Created by senyuanwang on 15/5/1. */ object A1 extends App with FileOp { override val filePrefix = "src/main/scala/codejam/year2015/apactest/A-large-practice" type LED = List[Int] object LED { def apply(str: String): LED = (str.toCharArray().map(_ - '0')).toList } def markMask(a: LED, b: LED, mask: LED): Option[LED] = { (a, b, mask) match { case (1 :: at, 1 :: bt, 2 :: mt) => markMask(at, bt, mt).map(mask => 1 :: mask) //確認該節點是正常的 case (1 :: at, 1 :: bt, 1 :: mt) => markMask(at, bt, mt).map(mask => 1 :: mask) //正常case case (1 :: at, 1 :: bt, 0 :: mt) => None //已確認損壞的節點被點亮了,和前面的case矛盾 case (1 :: at, 0 :: bt, _) => None //不應點亮的節點被點亮了 case (0 :: at, 1 :: bt, 1 :: mt) => None //已確認該節點work的狀況下,該節點未點亮 case (0 :: at, 1 :: bt, _ :: mt) => markMask(at, bt, mt).map(mask => 0 :: mask) //確認該節點是損壞的 case (0 :: at, 0 :: bt, m :: mt) => markMask(at, bt, mt).map(mask => m :: mask) //沒法確認該節點是否損壞 case (Nil, Nil, Nil) => Some(Nil) } } def light(led: LED, mask: LED): LED = (led, mask) match { case (1 :: at, 2 :: bt) => throw new Exception("ERROR") case (a :: at, b :: bt) => (a & b) :: light(at, bt) case _ => Nil } def solve(input: List[LED], path: List[LED], mask: LED): Option[LED] = (input, path) match { case (Nil, head :: tail) => Some(light(head, mask)) case (a :: at, b :: bt) => markMask(a, b, mask).flatMap(solve(at, bt ++ List(b), _)) } val ZERO = LED("1111110") val ONE = LED("0110000") val TWO = LED("1101101") val THREE = LED("1111001") val FOUR = LED("0110011") val FIVE = LED("1011011") val SIX = LED("1011111") val SEVEN = LED("1110000") val EIGHT = LED("1111111") val NINE = LED("1111011") val cycle = NINE :: EIGHT :: SEVEN :: SIX :: FIVE :: FOUR :: THREE :: TWO :: ONE :: ZERO :: Nil def startCycle(x: Int): List[LED] = { val (a, b) = cycle.splitAt(9 - x) b ++ a } def substract(leds: List[LED], list: List[LED], index: Int, result: List[LED]): Option[List[LED]] = { (leds, list) match { case (Nil, _) => Some(result.reverse) case (a :: at, b :: bt) if (index < 10) => substract(at, list, index + 1, a :: result) case (a :: at, b :: bt) if a != b => None case (a :: at, b :: bt) => substract(at, bt, index + 1, a :: result) } } def process(t: Int): Option[LED] = { val line = file.next().split("\\s+") val n = line(0).toInt val leds = (for { i <- 1 to n led = LED(line(i)) } yield led).toList substract(leds, leds, 0, Nil).flatMap { leds => val m = -1 val mask = LED("2222222") try { val result = (for { i <- 9 to 0 by -1 led <- solve(leds, startCycle(i), mask) } yield led).toSet if (result.size != 1) { None } else { Some(result.head) } } catch { case error: Exception => None } } } val T = file.next().toInt for { t <- 1 to T } { process(t) match { case Some(res) => println(s"Case #$t: ${res.mkString}") case None => println(s"Case #$t: ERROR!") } } }