テトロミノ認識やってみました

TL で面白そうな問題が流れてきたので解いてみました。

テトロミノ認識〜 横へな 2012.10.6

要するにテトリスですね。

どうやら 1 時間で解くという事らしかったので力技で解いてます。
考え方としては、10 * 10 のマスをすべて連続すると考えて入力された座標の位置関係を距離で判別しました。
この規模だと全パターン数も大したことないので定数として用意しておきました。

もうちょいスマートに解けると思いますが、とりあえず Groovy の練習として。

class Tetromino {
    private List patternL = [[1,1,10],[10,1,1],[10,10,1],[1,10,10],[10,9,1],[1,1,8],[1,9,10],[8,1,1]]
    private List patternI = [[1,1,1],[10,10,10]]
    private List patternT = [[9,1,10],[1,1,9],[10,1,9],[9,1,1]]
    private List patternO = [[1,9,1]]
    private List patternS = [[1,10,1],[1,8,1],[10,1,10],[9,1,9]]
    String judge(List coordinates) {
        if (isOverEdge(coordinates))
            return "-"
 
        List judgementPattern = extractJudgementPattern(coordinates)
 
        if (patternO.contains(judgementPattern))
            return "O"
        if (patternS.contains(judgementPattern))
            return "S"
        if (patternI.contains(judgementPattern))
            return "I"
        if (patternT.contains(judgementPattern))
            return "T"
        if (patternL.contains(judgementPattern))
            return "L"
 
        return "-"
    }
 
    private boolean isOverEdge(List coordinates) {
        def yList = coordinates.collect {it % 10}
        yList.max() == 9 && yList.min() == 0
    }
 
    private extractJudgementPattern(List coordinates) {
        coordinates.sort()
        List distanceList = []
        (1..3).each {
            distanceList << coordinates[it] - coordinates[it-1]
        }
        distanceList
    }
}
import spock.lang.Specification
import spock.lang.Unroll
 
class TetrominoSpec extends Specification {
    def "同じ座標を含む場合は-を出力"() {
        given:
        Tetromino t = new Tetromino()
 
        when:
        t.judge([55,55,55,55]) == "-"
 
        then:
        true
     }
 
    @Unroll
    def "座標 #input は #result を出力"() {
        when:
        Tetromino t = new Tetromino()
 
        then:
        t.judge(input) == result
 
        where:
        input           |result
        [07,17,06,05]   |"L"
        [21,41,31,40]   |"L"
        [62,74,73,72]   |"L"
        [84,94,74,75]   |"L"
        [48,49,57,47]   |"L"
        [69,89,79,68]   |"L"
        [90,82,91,92]   |"L"
        [13,23,03,24]   |"L"
        [24,22,25,23]	|"I"
        [51,41,21,31]	|"I"
        [64,63,62,65]	|"I"
        [49,69,59,79]	|"I"
        [12,10,21,11]	|"T"
        [89,99,79,88]	|"T"
        [32,41,43,42]	|"T"
        [27,16,36,26]	|"T"
        [68,57,58,67]	|"O"
        [72,62,61,71]	|"O"
        [25,24,15,14]	|"O"
        [43,54,53,42]	|"S"
        [95,86,76,85]	|"S"
        [72,73,84,83]	|"S"
        [42,33,32,23]	|"S"
        [66,57,67,58]	|"S"
        [63,73,52,62]	|"S"
        [76,68,77,67]	|"S"
        [12,11,22,01]	|"S"
        [05,26,06,25]	|"-"
        [03,11,13,01]	|"-"
        [11,20,00,21]   |"-"
        [84,95,94,86]	|"-"
        [36,56,45,35]   |"-"
        [41,33,32,43]	|"-"
        [75,94,84,95]	|"-"
        [27,39,28,37]	|"-"
        [45,34,54,35]	|"-"
        [24,36,35,26]	|"-"
        [27,27,27,27]	|"-"
        [55,44,44,45]	|"-"
        [70,73,71,71]	|"-"
        [67,37,47,47]	|"-"
        [43,45,41,42]	|"-"
        [87,57,97,67]	|"-"
        [49,45,46,48]	|"-"
        [63,63,52,72]	|"-"
        [84,86,84,95]	|"-"
        [61,60,62,73]	|"-"
        [59,79,69,48]	|"-"
        [55,57,77,75]	|"-"
        [10,19,9,20]	|"-"
        [29,31,41,30]	|"-"
        [39,41,40,50]	|"-"
    }
 }