プログラミングとかブログ

Unity/C#/SRPGStudio/RPGツクールMVの情報とかその他気になったことを調べて書きます。

ファイル置き場を移動しました

info-geocities.yahoo.co.jp

ジオシティーズが死ぬらしいので、昔アカウントだけ取っといて放置していたfc2ホームページに移行しました。

・やり方
ファイル全DL→fc2に全部突っ込む→index.htmlのリンクURLを書き換え
終わり


しかしブログ記事にリンクURLを貼ってたので全部変えるハメになったのだった。

【Windows10】無線がアクセスポイントごと消えて通信が切断する問題への対処

無線が切れ、俺はデュエルに敗北した――*1
f:id:shirakamisauto:20180808154847j:plain

唐突に無線が切れ、アクセスポイントすらなくなって再接続できないことが度々発生している。
どうもWindows10の大型アプデ以降無線がおかしくなったような気がしてならない。
有線とタブレットはふつうにつながるので、Wifiルーターの問題ではないらしい。
無線デバイスドライバのアプデを試すも効果なし。

結局、通信が切れるたびに無線デバイスを再起動することにした。
以下手順。

無線マークをクリックするとアクセスポイント一覧が出る。
f:id:shirakamisauto:20180808164008j:plain
接続中のアクセスポイントのプロパティを開くと、下の方にプロパティ欄がある。
説明の欄にあるデバイス(今回はIntel(R) Dual Band Wireless-AC 7260)を確認。
f:id:shirakamisauto:20180808152012j:plain
Windowsマークを右クリックしてデバイスマネージャーを開く。
f:id:shirakamisauto:20180808152034p:plain
ネットワークアダプターをクリックして、さっき確認した無線デバイスを右クリック。
「デバイスを無効にする」を実行、再度右クリックして「デバイスを有効にする」を実行。

これで接続処理が実行されて自動的に再接続される。



タイトルにある通り、これは対処に過ぎない。
根本的な原因が分からないので、一度パソコンを初期化しようと思っている。

*1:デュエルリンクスでランクマ中に無線が切れて切断負けになった

【C言語】ポインタまとめ

ポインタとは

プログラムはメモリ上で動きます。
変数や関数は全部メモリ上の適当な位置(アドレス)に置かれます。
そのアドレスに対してアレコレ操作するのがポインタです。
もっとざっくり言うと、メモリ上のデータにアクセスする仕組みがポインタです。

文法

宣言

ポインタ変数の宣言でよくある記法は基本的に下記のどっちかですが、後述のアクセス操作を考えると前者のほうがいいです。

	int* pointer1;
	int *pointer2;

実は変数型と変数名の間に「*」を入れればポインタ変数になります。
半角スペースを入れようが入れまいが同じです。
つまりこれもOKです。(見たことないですが)

	int*pointer3;
	int    *    pointer4;
使い方

ポインタ変数にはアドレスが格納されます。
下記では変数aのアドレスをポインタ変数に入れています。
「&変数名」で変数のアドレスになります。

	int a = 1;
	int* pointer = &a;

ポインタが指すアドレスに入っているデータ(つまりaのデータ)にアクセスするには下記のように「*」を変数名の前につけます。

	int b = *pointer;

で、これが宣言時のint *pointer2;と紛らわしいので、宣言時はint* pointerのほうが誤解がないと思います。

配列

ポインタの配列と、配列へのポインタがあります。
紛らわしいです。
前者はポインタがいっぱい、後者はポインタが一個だけです。

ポインタの配列がこう。

	int* p[5];//int型ポインタ変数の配列p

	p[0] = 0x00000001;
	p[1] = 0x00000002;
	p[2] = 0x00000003;
	p[3] = 0x00000004;
	p[4] = 0x00000005;

デバッグするとこんな感じになります。
f:id:shirakamisauto:20180208194642j:plain

配列へのポインタがこう。

	int(*po)[5];//要素数5の配列用のポインタ変数po
	int arr[5] = {1,2,3,4,5};
	po = &arr;

デバッグするとこんな感じになります。
f:id:shirakamisauto:20180208194632j:plain

構造体

通常、構造体のメンバーにアクセスする際は「.」を使います。

	struct MyStruct
	{
		int i;
	};

	struct MyStruct s;
	s.i = 2;

しかし構造体のポインタ変数では代わりに「->」を使います。
違うものなので仕方ないですが、紛らわしいですね。

	struct MyStruct
	{
		int i;
	};

	struct MyStruct stru;
	stru.i = 2;

	struct MyStruct* structp;
	structp = &stru;

	structp->i = 6;

f:id:shirakamisauto:20180209191851j:plain

応用

リスト

多分課題でよく出てくる単純なリスト構造です。
構造体の中に、(主に自身と同じ)構造体のポインタ変数を仕込みます。
下記では構造体n1の次(next変数)に構造体n2を突っ込むことで、n1とn2を続きにしています。

	struct node {
		int data;
		struct node* next;
	};

	struct node n1;
	n1.data = 1;

	struct node n2;
	n2.data = 2;
	n2.next = NULL;

	n1.next = &n2;

デバッグで見るとこんな感じです。
f:id:shirakamisauto:20180208191131j:plain
今はNULLにしていますが、n2.nextに別のを突っ込めば、リストを無限につなげられます。

数独スコアラー説明書

windowsストアで販売中の数独採点アプリ「数独スコアラー」の説明です。
www.microsoft.com

使い方

f:id:shirakamisauto:20180127190136p:plain
①テキストボックスに数独の問題を入力します。半角数字のみで、空白を0として入力します。
正しく入力できた場合、解くボタンが押せるようになります。
②解くボタンを押すことで問題を解きます。解けた場合はスコアが算出され、スコアがびよーんと動きます。
③リセットボタンを押すと問題と盤面とログをリセットします。
④入力した問題を表示する盤面です。
⑤どんな解法ロジックを使用したかなどを表示します。
⑥ここにチェックを入れると問題が解けなかったときに総当たり法で解きます。
スコアが跳ね上がるので注意です。
⑦ここにチェックを入れるとどの解法ロジックを使用して解いたかをログに表示します。

解くとこんな感じになります。
f:id:shirakamisauto:20180127185600p:plain

※問題は「超難問ナンプレAクラス2」より引用

処理解説

CRBE法→単一候補法→単一マス法の順で適用した後、
共有候補法→双子法→対角線法→三つ子法の順番で解放ロジックを適用していきます。
適用できた場合は単一候補法と単一マス法をやれるだけやって、再び共有候補法から適用します。
これを解けるか解けなくなるまでループします。
終了するまでの探索量を難易度スコアとしています。
具体的なロジックの説明は次項でします。


※盤面図や解法名https://www.oit.ac.jp/japanese/toshokan/tosho/kiyou/rikouhen/56-1/01r.pdfから引用

解説の前に

数独の盤面をi行j列の行列(i,j)として扱います。
f:id:shirakamisauto:20180127190335p:plain
ブロックも行列[i,j]扱いにします。
f:id:shirakamisauto:20180127190326p:plain

CRBE法

ある数字が入り得るマスを周辺の列(column)、行(row)、ブロック(block)から絞り込む(elimination)方法です。
下図では一番数の多い8を対象にします。
f:id:shirakamisauto:20180127190346p:plain
ブロック[1,3]を見ると、空きマスは(1,7)、(2,7)、(2,8)、(2,9)、(3,7)にあります。
すると、(1,5)に8があるため、1行目には8は入りません。
また、(2,1)にも8があるため、2行目にも8は入りません。
よって、下図のように(3,7)にしか8が入らないことが分かります。
f:id:shirakamisauto:20180127190406p:plain
こんな感じでほかのにも適用していきます。

単一候補法

あるマスに候補数字が一つしかなければそのマスはその候補数字で確定するというロジックです。
下図で○のついた候補数字4のあるマスは4以外の候補数字がないため、このマスは4で確定します。
f:id:shirakamisauto:20180127190424p:plain

単一マス法

ある候補数字がマス(i,j)にしか入らないことが分かっているとき、
その候補数字以外の候補数字はマス(i,j)から消去されるというロジックです。
下図で○のついた候補数字2はこのブロック内で1つしかないため、このマスは2で確定します。
f:id:shirakamisauto:20180127190443p:plain

双子法

独立双子法

独立双子法は同じ行、または同じ列、または同じブロックの中で候補数字が2つしかなく、
かつ候補数字が同一である2つのマスがあったとき、
その2マスを含む行、列、ブロックのその2マス以外のマスにその2つの候補数字は入り得ず、
候補から消去されるロジックです。
下図の(2,5)、(2,6)を見ると候補数字が2と3しかありません。
したがって、この2マスを含む行、列、ブロックには2と3は入らないため、
下図のように(2,1)と(2,3)の候補数字から2が消去され、
(1,4)と(1,5)の候補数字から2と3が消去されます。
f:id:shirakamisauto:20180127190455p:plain

居候双子法

同じ行、または同じ列、または同じブロックの中の2マスに共通の候補数字が2種類あったとき、
かつその候補数字がその2マスにしか入らないとき、
その2マスの候補数字から共通の候補数字以外の候補数字は消去されます。
下図の1行目を見ると、この行内で候補数字8、9はマス(1,4)、(1,5)にしかないことが分かります。
よってマス(1,4)、(1,5)のどちらか一方に8が、もう一方に9が入るので、
下図のように、マス(1,4)、(1,5)の8、9以外の候補数字は消去されます。
f:id:shirakamisauto:20180127190506p:plain

三つ子法

基本的に双子法の拡張です。

独立三つ子法

独立三つ子法は同じ行、同じ列、同じブロックの中で候補数字が3つしかなく、
かつ候補数字が同一である3つのマスがあったとき、
その3マスを含む行、列、ブロックのその3マス以外のマスから
その3つの候補数字は消去されるという解法ロジックである。
以下の図に独立三つ子法の例を示します。
f:id:shirakamisauto:20180127190517p:plain
マス(1,1)、(2,1)、(3,1)に着目すると、この3マスには候補数字が2、4、6のどれかしか入りません。
よって、このブロック内の他のマスの候補数字から2、4、6 は消去されます。
ここまでなら独立双子法の単純な拡張ですが、三つ子法の適用条件はこれ以外にもあります。
3つの数字から2つを選ぶ組合せは3C2=3通り存在します。
独立三つ子法は少なくともその3通りが揃っていれば適用できます。
3つの候補数字がn1、n2、n3だとしたとき、(n1,n2)、(n2,n3)、(n1,n3)の組が揃っていれば、独立三つ子法が適用できます。
下図を見てください。
f:id:shirakamisauto:20180127190524p:plain
n1=2、n2=4、n3=6とすると、どの例でも(2,4)、(4,6)、(2,6)の組が
○をつけた候補数字のあるマスに存在しているため、 独立三つ子法が適用できます。

居候三つ子法

居候三つ子法は同じ行、または同じ列、または同じブロックの中の3マスに共通の候補数字が3種類あったとき、
かつ、その候補数字がその3マスにしか入らないとき、
その3マスにある候補数字から3 種類の候補数字以外の候補数字は消去されるという解法ロジックです。
下図のマス(1,3)、(2,3)、(3,3)に着目すると、この3マスにしか候補数字7、8、9は入らないことが確定しています。
f:id:shirakamisauto:20180127190535p:plain
よって、マス(1,3)、(2,3)、(3,3)から7、8、9 以外の候補数字は消去される。
居候三つ子法の場合も独立三つ子法と同様に、3種の数字のうち少なくとも2種が揃っていれば適用できます。
f:id:shirakamisauto:20180127190543p:plain

共有候補法

共有候補法は、あるブロックとある行(または列) で共有するマスの情報を用いる解法ロジックです。
ブロックの情報から行(または列) の候補を消去する方法①と
行(または列) の情報からブロックの候補を消去する方法②がある。
①を下図で説明します。
f:id:shirakamisauto:20180127190553p:plain
ブロック[1,2]ではマス(1,4) か(1,6)にしか6が入りません。
よってこの2マスを共有する1行目のマス(1,1)、(1,2)から6は消去されます。
次に②を下図で説明します。
f:id:shirakamisauto:20180127190602p:plain
1行目ではマス(1,4)か(1,6)にしか8が入りません。
よってこの2マスを共有するブロック[1,2]のマス(3,4)、(3,5)、(3,6)から8は消去されます。

対角線法

下図に対角線法の例を示します。
f:id:shirakamisauto:20180127190611p:plain
○をつけた候補数字5は(2,5)、(2,9)、(6,5)、(6,9)に存在しています。
このとき、(2,5)に5が入ると、2行目と5列目の(2,9)、(6,5)に5は入りません。
よって(6,9)に5が入ることが確定します。
逆に、(2,9)に5が入ると、2行目と9列目、すなわち(2,5)、(6,9)に5は入りません。
よって(6,5)に5が入ることが確定します。
つまり、左上に入れば右下に、右上に入れば左下にと、この2パターンしか候補5の入る組合せはありません。
したがって、候補5がどちらのパターンで入ったとしても、
(2,5)、(2,9)、(6,5)、(6,9)以外の2行目、6行目、5列目、9列目のマスの候補数字から候補数字5は消去されます。
対角線法は下図のようにマスに入った数字を用いても適用できます。
f:id:shirakamisauto:20180127190619p:plain
数字9は3列目でマス(3,3)、(6,3)のどちらかに入り、7列目では、マス(3,7)、(6,7)のどちらかに入ります。
この場合でも数字は対角線上に配置されることになり、
マス(3,3)、(6,3)、(3,7)、(6,7)を除いた3行目と6行目のマスに9が入らないことが分かります。