最新の数独解析プログラムで何問か難易度★5の問題を解いてみたのですが。

順調に問題解けてます。
ロジック周りはほぼ完成と言ったところでしょうか。
あとはもうちょっと使い勝手が良くなるようにカスタマイズしていこうと思います。
前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/sudoku
前回のソースでは、以下のような問題で解析が途中で失敗していました。

この原因を探るため、ログ出力を強化します。
まず、マスに値を入れるタイミングでログを出します。
次に、仮置きロジックを適用する時と、仮置き前に巻き戻しをする時に、それが分かるようにログを出します。
さらに、仮置きロジックを適用する場所をログに出力するようにします。
ここまでやって、 仮置きロジックを適用する場所を探す処理に不具合がある事が分かりました。
/**
* 仮置き対象のマスを抽出する
*
* squares マス
*/
private List<Square> searchKariokiSquare(Square[,] squares)
{
List<Square> ret = null;
for (int row = 0; row < 9; row += 3)
{
for (int col = 0; col < 9; col += 3)
{
List<Square> temp = new List<Square>();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (squares[row + i, col + j].isConfirmed() == false)
{
temp.Add(_square[row + i, col + j]);
}
}
}
if (ret != null) //←★ここ
{
if (ret.Count > temp.Count && temp.Count != 0)
{
ret = temp;
}
}
else
{
ret = temp;
}
}
}
return ret;
}
★の箇所で、ret=nullで、temp.Count = 0の時に、仮置きロジックを適用する箇所がない(ret.Count=0)となり、解析が終了していることが分かりました。
なので、★の箇所を修正します。
if (ret != null)
{
if (ret.Count > temp.Count && temp.Count != 0)
{
ret = temp;
}
}
else if(temp.Count != 0)
{
ret = temp;
}

解けました。
難易度★5の問題も解けるようになったので、大抵の問題は解けるようになりました。
もう少し動かしてみます。
前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/hotel-mng
さて、前回からだいぶ期間が空いてしまいましたが、
続きやります。(思い出すのに時間かかった)
今回は、前回メールに添付したQRコードに書かれた解錠コードを使って解錠する処理を実装するのですが、
実際に解錠を行うのは、外部のデバイスを使用する、という前提として考え、ここではデバイスに入力した解錠コードをサーバに送信し、照合結果を返すAPIを実装します。
このAPIのレスポンスをデバイスが受信して、デバイスが実際に解錠を行います。そういう想定で実装します。
まず、APIのルーティングを作成します。
routes配下のapi.phpに以下を追加します。
Route::group(['middleware' => ['api']], function(){
Route::post('/unlock', 'Api2Controller@unlock');
});
なぜ、今までのようにweb.phpではないかというと、web.phpには
Auth::routes();
がかかれてあり、ログイン状態でアクセスしなければAPIは受け付けられません。
デバイス側にログイン状態というのは意識できないので、この制約が入らないルートに設定しなければなりません。
では、コントローラーを作成します。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Repository\RegisterManagementRepository;
use App\Repository\RoomRepository;
use App\Repository\UserRepository;
class Api2Controller extends Controller
{
public function __construct()
{
$this->registerManagement = new RegisterManagementRepository();
$this->room = new RoomRepository();
$this->user = new UserRepository();
}
public function unlock(Request $request)
{
\Log::debug(print_r($request->input('number'), true));
\Log::debug(print_r($request->input('room'), true));
$registers = $this->registerManagement->getItemsByDate(date('Y-m-d'));
if(is_null($registers) == false)
{
foreach ($registers as $register)
{
$room = $register->rooms()->first();
if(is_null($room) == false)
{
if($room->id == $request->input('room') &&
strcmp($register->lock_number, $request->input('number')) == 0)
{
return response()->json(['result' => true]);
}
}
}
}
return response()->json(['result' => false]);
}
}
Api2Controller.phpを追加しました。
ApiController.phpでは、コンストラクタに
$this->middleware('auth');
と記述しているため、これも上記と同じ理由で使用できません。
入力は部屋番号と解錠コードをjsonで入力します。
現在の日付から予約情報を取得し、部屋番号を解錠コードの比較を行い、一致したときにtrue、一致しない場合はfalseを返します。


思ったように動いているようです。
ただし、このままだと誰でもアクセスできてしまうので、セキュリティ的にガバガバ状態です。
デバイス情報を登録して、それも入力情報に含めるようにしましょうか。
次回やります。
元ネタはこちら
https://k-tai.watch.impress.co.jp/docs/news/1241563.html
ドコモの公式発表によると、全国の特定スポットにて5Gサービスが提供されます。
https://www.nttdocomo.co.jp/area/5g/?icid=CRP_menu_to_CRP_AREA_5g
その中には北海道も含まれています。
しかし、本当にとあるポイント周辺に限られているので、いつでも5Gが使えるわけではありません。
では、北海道ではどこで5Gが使えるのか。
PDFファイルにも書いてあるのですが、
本当に特定ポイントやね。
5Gを利用するためには、対応端末が必要です。(知ってると思うけど)
全国で使用できるには、少なくとも1年は待つ必要はあります。
なので、今焦って買う必要は無いと思います。
5G試せる人は一部のガジェットマニアぐらいか・・・
この記事、定期的にアップデートしていこう。
MySQLのセットアップ
composerのインストール
$ sudo apt-get install composer
phpの足りないモジュールをインストール
$ sudo apt-get install php7.2-mbstring
$ sudo apt-get install php7.2-xml
$ sudo apt-get install php7.2-zip
$ sudo apt-get install php7.2-gd
$ sudo apt-get install php7.2-mysql
nginxのインストール
Laravelの設定
$ composer global require "laravel/installer"
$ cd /var/www
$ sudo chmod 777 html
$ cd html
リポジトリからLaravelのソースをclone
$ git clone リポジトリのURL
$ chmod 777 storage/
$ chmod 777 bootstrap/cache/
.envを作成して、設定を記入
$ composer install
$ php artisan key:generate
node.jsのセットアップ
$ sudo apt-get install npm
$ sudo apt-get install libpng-dev
$ npm install
$ npm run dev
データベースを設定
$ php artisan migrate
$ php artisan db:seed --class=実行するseederクラス
忘れないようにメモしておく。
MySQLのインストール
$ sudo apt-get install mysql-server
rootパスワード設定
$ sudo mysql_secure_installation
問い合わせはすべてyを入力。
rootでログインを確認
$ sudo mysql -u root -p
MySQLにユーザーを追加
mysql> CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'
ユーザーに権限を設定
mysql> GRANT all ON *.* TO 'user'@'localhost'
そういえば、今使っているPCのWindows10がProなので、デフォで仮想環境が使える、と言うことに気がついたので。

これを使えば、VMwareとか、Virtual Boxとか使わなくても仮想環境を構築することができる。
参考にしたサイトはこちら。(Microsoftのヘルプページ)
https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v
Hyper-Vを有効にして、Hyper-Vマネージャーから仮想マシンを作成すると、すでにUbuntu18.04のテンプレートが用意されているので、これを選択すると、自動的にisoイメージのダウンロード、インストールまで完了します。
注意するところは、リモートデスクトップで接続しないこと。
そりゃそうだ。インストール直後のUbuntuはリモートデスクトップを許可していないので。接続できるはずがありません。
リモートデスクトップ接続をキャンセルすれば、仮想マシンのデスクトップを直で表示されます。
ただ、このままだと、画面解像度的に使いづらいので、解像度の設定を書き換えます。
参考にしたサイトはこちら。(Qiita)
https://qiita.com/mizutoki79/items/6122455bfa2755942488
$ sudo vi /etc/default/grub
で設定ファイルを開いて、以下のように書き換えます。

GRUB_CMDLINE_LINUX_DEFAULTの行にvideo=hyperv_fb:[変更したい解像度]を書き足します。
1920×930程度にしておけば、フルHDのデスクトップにちょうど収まります。
そして以下のコマンドで設定を反映。
$ sudo update-grub
間違えてFedoraのコマンドを使用すると起動不能になる。(やらかした)

使ってみた感じでは、非常に快適です。
これなら本当にVMwareとかいらないかも。
メモリも32GBと余るほどあるので、半分の16GBをHyper-Vに割り当てても余裕。
まずい、これは本当にLinux PCいらないぞ。
とりあえず、開発環境をセットアップして見ようか。
プログラマーが一番頭悩ませるのがエラー処理なのよ
— 多岐川ノリ@ぼっちのバンドリーマー (@n2_taki) March 11, 2020
プログラムというのは、目的通りに動いていればいい、という訳ではありません。
目的通りに動かすのは「当たり前」で、それ以上に頭を悩ませるのがエラー処理なんです。
具体的には、なんらかの要因で正しい処理が行えなくなった場合でも、正しい状態を保つ、ということをプログラミングしなければなりません。
前者が「正常系」と呼ぶのに対し、後者は「準正常系」と呼んでいました。
ちなみに、それ以外の深刻な問題が発生したときは「異常系」と呼んで、オペレーターに異常を知らせる処理を実行します。主にハードウェアの故障などがこれに該当します。
準正常系は、入力データの異常や割り込み処理などが該当します。
ソフトウェア設計者は、こういった準正常系の処理を全て網羅して、あらかじめエラーを検出し、本来の正常な動作を保つように設計しなければなりません。
設計者が頭を悩ませるのが、「準正常系に漏れが無いよね?」ということなんです。
我々がニュースなどで耳にする「ソフトウェアの異常」というのは、大抵、準正常系の考慮が漏れていたことに起因します。
そして、本番でこういうことが起きないように、出荷前に様々なテストデータを用意して、徹底的にいじめます。
特に組み込み系のファームウェアは、簡単にアップデートできないので、出荷から当分の間はヒヤヒヤします。
トラブルがあったら現場大炎上なので。
では、どうすれば良いかというと、これも難しい話で、経験を積み重ねるしか無いんですよ。
ベテラン技術者にレビューして貰うのも一つの手です。
まぁ、ソフトウェア製品の開発にはこんな事があるんですよ、ということで理解して貰えれば。
前回までの状況はこちら。
最新ソースはこちら(gitHub)
https://github.com/takishita2nd/sudoku
修正を戻したのは、重大な欠陥に気がついたためです。
仮置きロジックを再起実行させたときに矛盾を検出した場合、正しく処理されない、という動きが発生していました。
やはり、面倒でも、仮置きロジックを再起処理から全てリターンして、値を一つずつ確定していくのが一番良い方法だと思います。
このコードでもう少し問題を解いてみます。
そして、最高難度の問題でも解けるかを確認していきたいと思います。