yumetodoの旅とプログラミングとかの記録

旅や登山の記録やプログラミング関連の話とかフリーソフト紹介とか

はてなブログのあんたがたにあけおめ難易度高い数独

あけおめ

あけましておめでとうございます。今年もよろしくおねがいします。

問題

iOS数独アプリを解いていたらとんでもない難問に遭遇したので。

局面は

img

黒字が初期配置で青字が埋めたところ。

解いてみるとわかるが、左側が結構すんなり埋まる一方右側がさっぱり埋まらない。

此処から先、さっぱり埋まらず唸っていた。

ちょうど年末年始なのでいた、数独が自分よりできる父親に紙に書きうつして投げたところ、やっぱり唸っていた。

6時間ほどに渡る熟考の末、打開に成功した。

注目した箇所

右中段に注目する。まずは抜き出してみよう

img

ここで一旦15を取り除いてみる。

img

さて、8を見てみる。8は上と下に分かれている。これが上のときと下のときで場合分けしてみよう。

case1: 8が下

img

この様になる。下段が1,2,4,6,8が可能性があるが、1,6が入る余地が無いので6が右中で確定する。すると9が左中に確定し中央の3が確定する。

case2: 8が上

img

この様になる。上段が1,5,7,8の可能性があるが、1が入る余地が無い。

すると下段は1,2,4,6が可能性があるが、6が入る余地が無いので6が右中で確定する。すると9が左中に確定し中央の3が確定する。

場合分けまとめ
確定 未確定
上段 5,7
1,8
下段 2,4 8,1

1,8はX字依存。

中段はいずれにせよ9,3,6の順で確定する。

その後

9,3,6の順で確定したのを利用すると特に悩む余地なく素直に解ける。

img

このアプリは全部埋まると盤面が見れなくなるので一手前の画像。

筆ぐるめ23のグループの仕様に迫る

動機

年賀状作成シーズンがやってきた。我が家では長らく筆ぐるめ14を利用してきたのだが、流石に古いので3年くらい前に筆ぐるめ23に買い替えた。

過去に作成した年賀状データを見つつ毎年新しく作ったり部品をコピペしたりしているのだが、過去のデータが見えなくなってしまった。データ自体はファイルシステム上に存在しているにもかかわらずだ。

この記事は筆ぐるめがどのようにディレクトリとファイルを認識しているかをたどる過程でわかったことを未来の自分のために書き残す備忘録である。

多分他のバージョンの筆ぐるめについてもこの記事の内容が適用できるものと思っているが、保証はしない。

なおOSはWindows10 Home 1803を利用している。Windows7とかだと微妙に違っている可能性はある。

グループとは

筆ぐるめ23を起動して表面でも裏面でもいいが左にあるメニューを右クリックすると

img

新規グループ作成

新規サブグループ作成

という選択肢が出てくる。このグループのことだ。

左側のメニューは並び替えられる

どういうことかというと、上の図で言えば例えばみんなのレイアウト→マイレイアウトという順番で並んでいるのを逆にしたりできるということだ。マウスのドラッグで変えられる。

メニューの内容が記述されたファイルはどこか

メニューの中身を入れ替えたり追加/削除できるということはどこかでその情報を管理しているはずである。一体どこにあるというのか。

ソフトウェアの起動に管理者権限を要求されないことから、一般的な作法に従えば%USERPROFILE%\AppDataとかC:\ProgramDataを使っているだろう。

案の定探してみると

  • %USERPROFILE%\AppData\Local\Fujisoft\Fgw\23
  • C:\ProgramData\Fujisoft\Fgw\23

にあった。

img

img

さて、まあ画像の更新日時からも自明だが、C:\ProgramData\Fujisoft\Fgw\23のほうはただのカカシだ。つまり我々が見るべきは%USERPROFILE%\AppData\Local\Fujisoft\Fgw\23だということだ。

さていくつかファイルがある。拡張子が.ginfoとなっている。しかし恐れることはない。ただのテキストファイルだった。

次に拡張子が.ginfoのファイルだが、Sから始まるものとUから始まるものがある。Sから始まるものが何なのか、さっぱり分からないが、やはり更新日時から自明なように関係がない。つまり我々が見るべきはUから始まるものだということだ。

UAddres.ginfo
UAlbum.ginfo
UBackgr.ginfo
UExampl.ginfo
UExampl2.ginfo
UIllust.ginfo
ULayout.ginfo

まあ大体名前で何に対応しているかわかる。

.ginfoファイルのフォーマット

これ自体は.iniファイルみたいなものだが、なぜか値がcsvになっている。素直にjson使うべきでは?

[GroupAttributesBackgr]
Count=11
Group1="みんなの背景","%COMMON_BACKGROUNDS%",5021,1,"","C",,"0"
Group2="オンラインダウンロード","%SYSTEM_BACKGROUNDS%\\ContentDownload",5042, 1,"", "C",,"0"
Group3="年賀状","%SYSTEM_BACKGROUNDS%\\SGroup00",5001,1,"","C",,"1"
Group4="はがき縦","%SYSTEM_BACKGROUNDS%\\SGroup00\\00_01",5103,1,"%SYSTEM_BACKGROUNDS%\\SGroup00","C",,"1"
Group5="はがき横","%SYSTEM_BACKGROUNDS%\\SGroup00\\00_02",5103,1,"%SYSTEM_BACKGROUNDS%\\SGroup00","C",,"1"
Group6="シンプル","%SYSTEM_BACKGROUNDS%\\SGroup00\\00_03",5103,1,"%SYSTEM_BACKGROUNDS%\\SGroup00","C",,"1"
Group7="和風","%SYSTEM_BACKGROUNDS%\\SGroup01",5003,1,"","C",,"1"
Group8="はがき縦","%SYSTEM_BACKGROUNDS%\\SGroup01\\01_01",5103,1,"%SYSTEM_BACKGROUNDS%\\SGroup01","C",,"1"
Group9="はがき横","%SYSTEM_BACKGROUNDS%\\SGroup01\\01_02",5103,1,"%SYSTEM_BACKGROUNDS%\\SGroup01","C",,"1"
Group10="喪中欠礼","%SYSTEM_BACKGROUNDS%\\SGroup03",5037,1,"","C",,"1"
Group11="寒中見舞い","%SYSTEM_BACKGROUNDS%\\SGroup04",5034,1,"","C",,"1"

名前はCountというのとGroupNというのがある。ただしNは1から始まる連番だ。

このNの番号こそ、左のメニューの並び順の正体である。

で、GroupNの値を見ていく。これは明らかにcsvなのでそれぞれの意味を探ってみた。そのためにわかりやすい値をいくつか拾ってきた。

"みんなの\nレイアウト","%COMMON_LAYOUTS%",5021,1,"","C",,"0"
"マイ レイアウト","%USER_LAYOUTS%\\Group000",5022,1,"","D",,"0"
"test1","%USER_LAYOUTS%\\Group000\\Group009",5103,0,"%USER_LAYOUTS%\\Group000","D",,""
"リムーバブル\n(I:)","\\",8422,4,"","I",4,""
"CD-DVD\n(M:)","\\",8421,1,"","M",3,""

とはいえcsvっていうのは読みにくいのでそれぞれの意味を解説がてらjsonっぽく書き換えてみよう。

[
    {
        "type": "string",
        "note": "項目の名前、改行は\nを使用",
        "isOptional": false,
        "example": [
            "みんなの\nレイアウト",
            "マイ レイアウト"
        ]
    },
    {
        "type": "string",
        "note": "項目内のデータが存在しているパス。ただしプログラム内で定義されている謎の変数を含む。ドライブレターを含まない",
        "isOptional": false,
        "example": [
            "%COMMON_LAYOUTS%",
            "%USER_LAYOUTS%\\Group000",
            "\\"
        ]
    },
    {
        "type": "integer",
        "note": "グループの種類番号。おそらくシングルクリックしたときの挙動に関わる",
        "knownValue": [
            {
                "value": 5103,
                "note": "何らダイアログを必要とせず保存されているレイアウトファイル(.fglと.fgl.fgt)を呼び出すもの"
            },
            {
                "value": 5042,
                "note": "クラウドサービスに接続するもの"
            }
        ]
        "isOptional": false,
        "example": [
            5001,
            5019,
            5021,
            5022,
            5023,
            5034,
            5036,
            5037,
            5042,
            5044,
            5103,
            8421,
            8422
        ]
    },
    {
        "type": "integer",
        "note": "グループ設定変更禁止フラグ",
        "knownValue": [
            {"value": 0, "note": "変更可能"},
            {"value": 1, "note": "変更不能"}
        ],
        "isOptional": false
    },
    {
        "type": "string",
        "note": "親カテゴリのデータが存在しているpath",
        "isOptional": true,
        "example": "%USER_LAYOUTS%\\Group000"
    },
    {
        "type": "string",
        "note": "項目内のデータが存在しているパスのドライブレター",
        "isOptional": false,
        "example": [
            "C",
            "D",
            "M"
        ]
    },
    {
        "type": "integer",
        "note": "device type",
        "knownValue": [
            {"value": 3, "note": "CD/DVD/BD"},
            {"value": 4, "note": "removable media"}
        ],
        "isOptional": true
    },
    {
        "type": "string",
        "note": "サブグループ作成禁止フラグ",
        "knownValue": [
            {"value": "0", "note": "作成可能"},
            {"value": "1", "note": "作成不能"},
            {"value": "", "note": "自身がサブグループ"},
        ],
        "isOptional": false
    }
]

推測だがこんな感じだろうか。グループの種類番号ってのはほんとによくわかんないが、とりあえず5103だけが大事な感じ。

プログラム内で定義されている謎の変数

先程

項目内のデータが存在しているパス。ただしプログラム内で定義されている謎の変数を含む。

と解説した謎の変数について見ていく。

Process Explorerで筆ぐるめ23(Fgw.exe)を覗くと

img

それらしい文字列が見えてくる。USER_LAYOUTSってさっきあったよな。多分このへん全部有効な変数名なんじゃなかろうか。

ちなみにUSER_LAYOUTSは多分ライブラリのドキュメントの中の筆ぐるめ\ULayoutを指していると思う。

ライブラリのドキュメントのパスはGUI以外にも

reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Personal"

で分かる。

このブログにもKatexが来た

$$S _ {\text{chunk}}(n)=\Bigl( \frac{2n+2}{4} \Bigr) ^ 2$$

$$D _ {\text{ore}}(n)=\Bigl( \frac{16 \cdot 4 \cdot 8}{16 \cdot 16 \cdot 12} \Bigr) \times d \times c \times S _ {\text{chunk}}(n)$$

$$D _ { \text{get}}(n)=l \times D _ {\text{ore}}(n)$$

$\mathrm{Mg}^{2+}$/$\mathrm{Ca}^ {2+}$依存の DNase I family

みたいな数式が書けるようになった。

<link rel="prefetch" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Math-Italic.woff2">
<link rel="prefetch" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Main-Regular.woff2">
<link rel="prefetch" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/fonts/KaTeX_Size2-Regular.woff2">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/katex.min.css" integrity="sha384-9eLZqc9ds8eNjO3TmqPeYcDj8n+Qfa4nuSiGYa6DjLNcv9BtN69ZIulL9+8CqC9Y" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/katex.min.js" integrity="sha384-K3vbOmF2BtaVai+Qk37uypf7VrgBubhQreNQe9aGsz9lB63dIFiQVlJbr92dw2Lx" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/contrib/auto-render.min.js" integrity="sha384-kmZOZB5ObwgQnS/DuDg6TScgOiWWBiVt0plIRkZCmE6rDZGrEOQeHM5PcHi+nyqe" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://unpkg.com/microtip/microtip.css">
<script defer src="https://cdn.jsdelivr.net/gh/john-doherty/long-press@1.0.2/dist/long-press.min.js" integrity="sha384-KStdKoqyzrHMWSdq2HkajgYuueBIz000UjPzkOWvLVSc8fYJLKPp2aph8l2onLMO" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.0/themes/smoothness/jquery-ui.css">

を追記してさらに

use jquery-ui when touch device

を追記することで実現した。katexを適用するためのScriptは基本的には

7shi.hateblo.jp

7shi.hateblo.jp

からお借りしたが、今どきforをindex baseで回すコードが嫌という宗教上の理由で若干書き換えている。

またtextareaを追加するのもだるいなぁと思ったので古き良きalertを利用することに。最初はクリップボードに直接書き込んでやりたかったけどpermission APIがなくて断念。スマートフォンなどのタッチデバイスでは、古き良きalertだとテキストが選択できないのでjquer-uiのを利用。jquery-uiについては

developer.hateblo.jp

数式にツールチップつけるのにmicrotipというやつを利用することにした。CSSだけでできるのか・・・。

github.com

あとlong-press eventが欲しかったので

github.com

も使っている。ただしスマートフォンなどのタッチデバイスでは、これはうまくいかないので二回タップしたら発火するようにしている。