CodeIQ 「進捗まあまあマーク」問題の僕の回答(闇落ち版)

CodeIQ 「進捗ないですマーク」問題、僕の回答(闇落ち版)です。

　#sinchokumiq

## 実行結果

こんな感じです。おまけのメソッドがあります。

```
>>> import CodeIQTBX as IQ
>>> IQ.main()
5
m...m
mm.mm
m.m.m
m...m
m...m
>>> IQ.MerryChristmas(5)
m...m eeeee rrrrr rrrrr y...y
mm.mm e.... r...r r...r .y.y.
m.m.m eeeee rrrrr rrrrr ..y..
m...m e.... r..r. r..r. ..y..
m...m eeeee r...r r...r ..y..
ccccc h...h rrrrr ..i.. sssss ttttt m...m aaaaa sssss
c.... h...h r...r ..i.. s.... ..t.. mm.mm a...a s....
c.... hhhhh rrrrr ..i.. sssss ..t.. m.m.m aaaaa sssss
c.... h...h r..r. ..i.. ....s ..t.. m...m a...a ....s
ccccc h...h r...r ..i.. sssss ..t.. m...m a...a sssss
>>> IQ.HappyNewYear(5)
h...h aaaaa ppppp ppppp y...y
h...h a...a p...p p...p .y.y.
hhhhh aaaaa ppppp ppppp ..y..
h...h a...a p.... p.... ..y..
h...h a...a p.... p.... ..y..
n...n eeeee w...w ..... y...y eeeee aaaaa rrrrr
nn..n e.... w...w ..... .y.y. e.... a...a r...r
n.n.n eeeee w.w.w ..... ..y.. eeeee aaaaa rrrrr
n..nn e.... ww.ww ..... ..y.. e.... a...a r..r.
n...n eeeee w...w ..... ..y.. eeeee a...a r...r
>>> IQ.HappyNewYear(3)
h.h aaa ppp ppp y.y
hhh aaa ppp ppp .y.
h.h a.a p.. p.. .y.
n.n eee w.w ... y.y eee aaa rrr
nnn eee www ... .y. eee aaa rrr
n.n eee w.w ... .y. eee a.a r.r
>>> IQ.MerryChristmas(1)
m e r r y
c h r i s t m a s
>>>
```
## コード
コードはこんな感じ。
CodeIQ で回答した後に HappyNewYear を追加。

```CodeIQTBX.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sqlite3


strSQLMain = '''
SELECT
        'invalid'
    WHERE
        :1 & 1 = 0
UNION ALL
SELECT
    group_concat(l,' ')
FROM
    (
WITH P(x,y) AS (
        WITH X(x) AS (
                SELECT 1 WHERE :1 & 1 = 1
                UNION ALL SELECT x + 1 FROM X WHERE x < :1)
        SELECT X,1 FROM X
        UNION ALL SELECT P.x,P.y + 1 FROM P WHERE y < :1)
    SELECT
        cx,cy,y,
        group_concat(
            CASE
                WHEN
                    (
                        (ch = 'a')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (y = 1)
                            OR (y * 2 = :1 + 1)))
                    OR (
                        (ch = 'b')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (y = 1)
                            OR (y = :1)
                            OR (y * 2 = :1 + 1)))
                    OR (
                        (ch = 'c')
                        AND ((x = 1)
                            OR (y = 1)
                            OR (y = :1)))
                    OR (
                        (ch = 'e')
                        AND ((x = 1)
                            OR (y = 1)
                            OR (y = :1)
                            OR (y * 2 = :1 + 1)))
                    OR (
                        (ch = 'h')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (y * 2 = :1 + 1)))
                    --OR (
                        --(ch = 'i')
                        -- ここのコードは光速を超えれば閲覧可能
                    OR (
                        (ch = 'm')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (x = y and (y * 2 <= :1 + 1))
                            OR ((x + y = :1 + 1) and (y * 2 <= :1 + 1))))
                    OR (
                        (ch = 'n')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (x = y)))
                    OR (
                        (ch = 'o')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (y = 1)
                            OR (y = :1)))
                    OR (
                        (ch = 'p')
                        AND ((x = 1)
                            OR (y = 1)
                            OR ((x = :1) AND (y <= (:1 + 1) / 2))
                            OR (y = (:1 + 1) / 2)))
                    OR (
                        (ch = 'r')
                        AND ((x = 1)
                            OR (y = 1)
                            OR ((x = :1) AND (y <= (:1 + 1) / 2))
                            OR (y = (:1 + 1) / 2)
                            OR ((y * 2 >= :1 + 1) AND (x = y))))
                    OR (
                        (ch = 's')
                        AND ((y = 1)
                            OR (y = :1)
                            OR ((x = 1) AND (y * 2 <= :1 + 1))
                            OR ((x = :1) AND (y * 2 >= :1 + 1))
                            OR (y * 2 = :1 + 1)))
                    OR (
                        (ch = 't')
                        AND ((y = 1)
                            OR (x * 2 = :1 + 1)))
                    OR (
                        (ch = 'w')
                        AND ((x = 1)
                            OR (x = :1)
                            OR (y * 2 >= (:1 + 1)
                                AND (
                                    (x = y)
                                    OR (x + y = :1 + 1)))))
                    OR (
                        (ch = 'y')
                        AND ((y * 2 >= :1 + 1 AND x * 2 = :1 + 1)
                            OR (y < (:1 + 1) / 2
                                AND (
                                    (x = y)
                                    OR (x + y = :1 + 1)))))
                    OR (
                        (ch = 'x')
                        AND ((x = y)
                            OR (x + y = :1 + 1)))
                    OR (
                        (ch = 'z')
                        AND ((y = 1)
                            OR (y = :1)
                            OR (x + y = :1 + 1)))
                    THEN ch
                ELSE '.'
            END,'') as l
    FROM P, CH
    GROUP BY cx,cy,y
    ) L
GROUP BY cy,y
;
'''
strSQLPrepare = '''
CREATE TABLE CH (
    cx INTEGER
    , cy INTEGER
    , ch TEXT
    , PRIMARY KEY (cx, cy));
'''
strSQLRegisterCh = '''
INSERT INTO CH
    SELECT
        X,
        :1 AS Y,
        ch
    FROM
        (
            WITH X(n) AS (
                    SELECT 1
                    UNION ALL SELECT n + 1 FROM X WHERE n < LENGTH(:2))
                SELECT
                    n AS X
                    , SUBSTR(LOWER(:2),n,1) AS ch
                FROM
                    X) S;
'''


def prepareCh(conn, l):
    conn.executescript(strSQLPrepare)
    for (y, s) in enumerate(l):
        conn.execute(strSQLRegisterCh, (y + 1, s))


def printChars(n, l):
    try:
        conn = sqlite3.connect(':memory:')
        prepareCh(conn, l)
        lines = conn.execute(strSQLMain, (n, )).fetchall()
        for line in lines:
            print(line[0])
    finally:
        conn.close()


def MerryChristmas(n):
    printChars(n, ['merry', 'christmas'])


def HappyNewYear(n):
    printChars(n, ['happy', 'new year'])


def main():
    n = int(input())
    printChars(n, ['m'])


if __name__ == '__main__':
    main()
```

## なぜ闇落ち?

まぁ、当初 Python で Linewise のコード書いていた時はまぁ、普通の問題だった。
が、sqlite3 でやるようになり、Dotwise のコードを書くようにしたら問題が簡単すぎた。
sqlだからというわけではなく、Dotwise にすると他の言語でも簡単になるだろう。

あまりにも簡単すぎ、にも関わらず同じような問題が繰り返し出る。
それは狂気を呼び起こし、作るべきプログラムは何だと考え、
そしてプレッシャーにより作らずにいられなくなった。

・・・という感じです。