ひとりにしてくれが好きだ


z3pyを導入しましたよ、というだけの日記です。
相も変わらず、「ひとりにしてくれ」の数字埋めを扱います。

処置前サンプル。これを、

f:id:mainasuyon:20210218170522p:plain

こんなふうにしたい。

f:id:mainasuyon:20210218170602p:plain

pythonを触ったこともほぼないので、配列すら使わずにベタ書きしてしまいます。

# モジュールをインポートする
from z3 import *

# 変数を用意する
aaa_00_00 = Int('aaa_00_00')
aaa_01_00 = Int('aaa_01_00')
aaa_02_00 = Int('aaa_02_00')
aaa_03_00 = Int('aaa_03_00')
aaa_04_00 = Int('aaa_04_00')
aaa_05_00 = Int('aaa_05_00')
aaa_06_00 = Int('aaa_06_00')
aaa_07_00 = Int('aaa_07_00')
aaa_00_01 = Int('aaa_00_01')
aaa_01_01 = Int('aaa_01_01')
...(中略)...
aaa_07_07 = Int('aaa_07_07')

solver = Solver()

# 変数は1以上8以下
solver.add( aaa_00_00 > 0, aaa_00_00 < 9)
solver.add( aaa_01_00 > 0, aaa_01_00 < 9)
...(中略)...
solver.add( aaa_07_07 > 0, aaa_07_07 < 9)

# 各マスの関係の制約を記述
solver.add( aaa_00_00 == aaa_01_00 )
solver.add( aaa_00_00 == aaa_02_00 )
solver.add( aaa_00_00 != aaa_03_00 )
solver.add( aaa_00_00 != aaa_04_00 )
...(中略)...
solver.add( aaa_07_03 != aaa_07_07 )
solver.add( aaa_07_04 == aaa_07_05 )
solver.add( aaa_07_04 != aaa_07_06 )
solver.add( aaa_07_04 != aaa_07_07 )
solver.add( aaa_07_05 != aaa_07_06 )
solver.add( aaa_07_05 != aaa_07_07 )
solver.add( aaa_07_06 != aaa_07_07 )

# 解いておくれ
print(solver.check())
print(solver.model())

パッと見で把握しやすいように、雑に略しましたけどわかりますよね。
各マスの関係ですが、縦横に見て、2つのマスの組み合わせに関して、両方数字が入っていて等しいならイコール、そうでなければノットイコールで結ぶだけです。

結果はこんな感じ。

sat
[aaa_07_03 = 2,
aaa_01_01 = 2,
aaa_01_05 = 4,
aaa_01_02 = 5,
aaa_00_06 = 3,

... (中略) ...
aaa_01_00 = 7,
aaa_02_00 = 7]

結果を得てしまえば、あとは適切なスクリプトを書いてパズル盤面として成形するだけです。今回の場合はawkを使用してpenilboxの形式に変換しました。

重い腰を上げて使ってみたけど、導入は簡単だし、そりゃ使われるよねpythonってところ。
やりたいことは伝えられてるんじゃないかと思うので、どなたかもっと便利に洗練された形に仕上げてくれると幸いです。
ということでレッツエンジョイひとくれライフ!

以下ソースコードとかいろいろ。

続きを読む

ひとりにしてくれが好きだ

以前、こんな↓記事を書きました。

https://mainasuyon.hatenadiary.org/entries/2010/02/07


簡単に言うと、「ひとりにしてくれを作る時の数字を埋める作業が面倒なので、パソコンさんに任せるのはどうでしょう。Sugar制約ソルバーを利用すると簡単ですよ。数字は入れ替わっちゃいますけど」という話です。

PencilBox形式からSugar入力形式に変換するawkスクリプトも公開してたんですが、ジオシティーズのサービス終了に伴い見られなくなっています。

じゃあブログに直接書いちゃうか、というのが今回の記事。

Sugarが導入されている仮定なんで、Perlで書くのが筋かなと思い、そうしてみました。

#!/usr/bin/env perl
use strict;
use warnings;



my $file = shift; 

open(my $fh, "<", $file) or die("Error");

my @lines = <$fh>;

### 盤面の格納 ###
my $ymax = $lines[0];
my $xmax = $lines[1];

my @parr = ();

for(my $j=0;$j<$ymax;$j++){
 my @tmparr = split(" " , $lines[2+$j] );
 for(my $i=0;$i<$xmax;$i++){
  $parr[$j*$xmax+$i] = $tmparr[$i];
 }
}


### Sugar変数定義 ###
for(my $j=0;$j<$ymax;$j++){
 for(my $i=0;$i<$xmax;$i++){
  printf("( int a_%02d_%02d 1 %d )\n",$i,$j,$xmax);
 }
}


### ヨコ方向 ###

#  左からn番目の数字が、
#   他に重複したものがあり、しかもそのグループの中で左端ではない → tmparr[n]が1
#   それ以外                                                     → tmparr[n]が0

for(my $j=0;$j<$ymax;$j++){
 my @tmparr = (0) x $xmax;
 for(my $i=0;$i<$xmax;$i++){
  for(my $u=$i+1;$u<$xmax;$u++){
   if(($parr[$j*$xmax+$i]!=0)&&($parr[$j*$xmax+$i]==$parr[$j*$xmax+$u])){
    printf("( = a_%02d_%02d a_%02d_%02d )\n",$i,$j,$u,$j);
    $tmparr[$u] = 1;
   }
  }
 }

 printf("( alldifferent ");
 for(my $i=0;$i<$xmax;$i++){
  if($tmparr[$i] != 1){
   printf("a_%02d_%02d ",$i,$j);
  }
 }
 printf(")\n");
}


### タテ方向 ###

#  上からn番目の数字が、
#   他に重複したものがあり、しかもそのグループの中で上端ではない → tmparr[n]が1
#   それ以外                                                     → tmparr[n]が0

for(my $i=0;$i<$xmax;$i++){
 my @tmparr = (0) x $xmax;
 for(my $j=0;$j<$ymax;$j++){
  for(my $u=$j+1;$u<$ymax;$u++){
   if(($parr[$j*$xmax+$i]!=0)&&($parr[$j*$xmax+$i]==$parr[$u*$xmax+$i])){
    printf("( = a_%02d_%02d a_%02d_%02d )\n",$i,$j,$i,$u);
    $tmparr[$u] = 1;
   }
  }
 }

 printf("( alldifferent ");
 for(my $j=0;$j<$ymax;$j++){
  if($tmparr[$j] != 1){
   printf("a_%02d_%02d ",$i,$j);
  }
 }
 printf(")\n");
}

close($fh);

もうひとつ、めでたくSugarが成功の出力を返してくれた場合、それをPencilBox形式に変換するスクリプト
盤面サイズは自動検出に対応していないので、個別に my $size = 8; のところを適宜変更してください。

#!/usr/bin/env perl
use strict;
use warnings;

### 盤面サイズの指定 ###
my $size = 8;


my %parr = ();

while(<>){
 my @tarr = split(/\s+/,$_);
 if($#tarr+1==3){
  $parr{$tarr[1]} = $tarr[2];
 }
}

print $size . "\n";
print $size . "\n";
for(my $j=0;$j<$size;$j++){
 for(my $i=0;$i<$size;$i++){
  my $pos = sprintf("a_%02d_%02d",$i,$j);
  printf $parr{$pos} . " ";
 }
 printf "\n";
}


スクリプトに責任などもちろん持ちませんけど、普段この程度のスクリプトを書くならawkで書くので、perlのお作法的に変なことをしてるかもです。
適宜修正して使っていただければ。

Sugarの導入は大変なので、minisatさえ導入できれば使えるように、なんてことも考えるんですけれども。
希望がありましたら、まいなすよんの生活に余裕ができるように星に祈っておいてください。よろしくお願いします。

百人一首から平均的な一首を選択せよ! その1 法性寺入道前関白太政大臣

こんにちは。

先日、twitterで次のようなことをつぶやきました。

小倉百人一首から、もっとも平均的な一首を選出する」という命題を設定したとして、歌そのものの集合のみからでもちょっと考えれば十個くらいは実例つきで挙げられるだろう。こじつければもう十個くらいはなんとか。何人かでアイデア出せばどうか。意味的、歴史的なこじつけも許可してどうだろうか。

・百首全部のひらがな使用ヒストグラムと一首ずつのそれを比較して一番似てるのを選出。・歌の間に距離を定義して他の99首との距離を合計して最小値をとるものを選出。・隣接するひらがなの組み合わせの登場数で重みをつけて一首のなかで合計して最大値をとるものを選出。などなど。

特に反響は無かったのですが、まーとりあえずやってみる動作くらいはしようか、と思ってやってみました。
サンプルはwikipediaから持ってきました。データの正当性とか検証するのも虚しいので、漢字と()を除去したものをそのまま使用します。読み方とか清濁とか、考え始めるといろいろと難しいらしいですね。その辺はさっくり無視の方針で。

では今回は、百人一首全体のひらがな使用傾向と一番似た傾向を持つ一首を選出することを目指します。

まずは全体の文字数をカウントしましょう。こんな。

20180104170201

濁音は少なさそうですよね。
「の」が突出して多い。そりゃそうよねな感じ。
「丸みら時には賀茂氏なの」とかなんとなく意味ありげ。
どうでもいいですけど。



では次は、一首ごとのひらがなの使用傾向をそれぞれ算出し、単純に全体のそれとの二乗距離をとってみることにします。
いいの、そんな処理で?
知らねえよ、んなこと!

20180104170202



んー、突出したなにかがあるわけでもないですがー
とりあえず一列に並んだので今回の結論としましょう。
百人一首の中で一番平均的なのは!
76.法性寺入道前関白太政大臣
わたのはらこぎいでてみればひさかたのくもゐにまがふおきつしらなみ
百人一首の中で一番平均から外れているのは!
28.源宗于朝臣
やまざとはふゆぞさびしさまさりけるひとめもくさもかれぬとおもへば



最後に、この2首のひらがな出現傾向を、グラフとして全体と並べてみましょう

20180104170203



ねえこれ似てるっていうの?
ねえこれ似てないっていうの?
そもそもこの記事なにか面白いの?

まなみんが、じゃない、クロスワードが好きだ

田中真奈美さんが大好きだ僕。

おっと失礼しました。心の声があふれ出てしまいました。
ことほどさように贔屓の声優さんに気持ちが引きずられてしまうと、パズル作りにも影響が及んでしまうこともあるのです。愛とは難しいものですね。途中から思いが止まらなくなってしまい、発表する場所を失ってしまったクロスワードがありますので、ここでお披露目しようと思います。
ま、でも、あれですね。むしろ暴走しなかった前半部分の横方向に、かえって私の作家性が反映されているのではないかななどと思うのです。あーりふれた日々のー素晴らしさにー気づくまでにー二人はただー♪

ということでそんな感じよ。

20160817195421

タテのカギ
1 社会、国家はこの人々から成る
2 比較的やわらかなボール。野球、テニスなどで使われる方式がある
3 石川県南部の旧国名
4 他人の妻の敬称
6 海岸や湖岸にできた砂堤。サスがに辞書そのもののヒントでいいですよね……
7 ゴルフで、パー+2の打数、を略して
9 これが一番大切なこと
10 新潟県上越市名産の菓子。夏目漱石「坊ちゃん」にも登場する
13 学名ニッポニア・ニッポンの鳥
15 文字を素材とする芸術
17 たまにはこぼすのも仕方ない
18 7以上48以下、といわれます

ヨコのカギ
2 ぼくらは同じ目的を持って頑張っている関係だぜ
5 手首を飾る刺繍糸のお守り。切れるまで付けていると願いが叶うとか
7 高所のものを取る時などに乗る
8 気のゆるみ、油断。勝負の時には見せないように
9 ぶつけてあいたたた
11 声優の田中真奈美さんの楽しいおしゃべりを聞いていると、うきうきとこんな気分になりますね。また、田中真奈美さんが、ご友人の西明日香さんの、ご家族面白エピソードに対してこう評することが多いような気がします。仲の良さがとてもほほえまです。
12 声優の田中真奈美さんのプロフィールの「好きな食べ物」の欄にあげられています。他には、豆腐、お米など。おやおや、少しだけ独特な視点の共通項があるようですね。
14 声優の田中真奈美さんの数年前くらいのお話を聞いていると、柔和な外見に似合わないこれの強さを感じて意外に思ったりします。最近はずいぶんと柔らかくしなやかになった印象ですね。どちらも魅力的ですよね。
16 声優の田中真奈美さんの出身県、の旧国名田中真奈美さんもご故郷には当然ながら特別の思い入れがあるようで、ラジオでお好み焼きや牡蠣に対するアツい思いを語られたりしています。かわいい。ソウルフードは飽きがこないのでしょうね。
17 声優の田中真奈美さんの座右の銘。真面目で努力を怠らないイメージと、必ずしも良い意味ばかりではない言葉をチョイスするセンスが相まって、すこぶる彼女らしいと思います。
19 声優の田中真奈美さんのバースデーイベントを2回(2017/8現在)も開催してくれた宇都宮大学ハロー!!きんいろモザイクのお披露目イベントツアーの会場となったヒカリ座、セガ・ハードガールズのステージが開催されたとちてれアニメフェスタ等、田中真奈美さんに縁の深い県ですね。関係者のみなさま今後もよろしくお願いします!





答えはこちら

20160817195420


(言うまでもありませんが一ファンの記事です。公式とはなんら関連しません)

推理パズルとオモパが好きだ

ニコリ154号掲載の自作問題のコメントです。


推理パズル2
特集のテーマが「ウソ」ということで、比較的スタンダードな「正直村と嘘つき村のパズル」があるといいのではないかなと思って作ってみました。多少ひねってみて、私は前例を認識してはいませんが、ひねり方自体はオーソドックスなので、前例がどっかにはあるだろうなーとは思ってたりしてます。


ドッスンフワリ3
頑張って難しめに振ってタラちゃん採用なのでその点はわーいなわけですが、時間を置いて解きなおすとどの辺が意図だったかなと見失ったりもしてます。


とさらっと。

オモパが好きだ


今でこそこう、オモパコーナーの感想を書くのに差し障りが生じるなんてことはないわけですが、昔をよく知る人に聞いてみると、オモパコーナーの感想を書くなんてどういう料簡だって時代があったなんて話を聞いたり聞かなかったりしますな。そもそも当時の東京ではオモパなんて略し方をしなかったそうで。ではなんと呼んでたんですかと聞くと昔はオモ口パと呼んでいたとか。髪結いでも、芝居相撲オモ口パの話題についてこれないのでは江戸っ子と名乗る資格はないなんて風潮があったそうです。まーそこまで流行していたというのは結構な話に聞こえますけど、ひどいときには昇格退場をめぐって喧嘩沙汰になったというから穏やかでない。それもこれもすべてオモ口パに口だけを出す輩が多すぎるからだと、時のお上の一声で「口」が削られて現在のオモパになったと、まあここまでくるといくらなんでも嘘でしょうという話になるというか徹頭徹尾嘘なわけですが。
それはそれとしてニコリ153号オモパコーナーの感想です。


ドッスンフワリ

昇格めでたい。「ここで別解が生じないようにするには、このへんでこうするしかないよな……」てな状況が割と生じやすくて作成時にはもやもやしたりするのですが、誰かが作ったものを解くときにはそんなこと感じないんじゃないすかね。どんなもんでしょう。大人の余裕かあるいは子供の無垢さが必要ということかもしれません。(てきとう)


ノンダンゴ

好調でよいですね。ルールがシンプルな割に複雑なことができるのは魅力的です。「箱の中にひとつずつある黒丸と白丸の場所を確定する」ドッスンフワリと「箱の中に既にある丸の中からひとつだけある黒丸の場所を確定する」ノンダンゴでは字面で書くと目的はあまり変わらない気がするんですが、ずいぶん違って感じられるのはなぜでしょう。


オレサッカー

好評なんですか。それは失礼ですがちょっと意外。私は好きなので好評なのは嬉しいですが。前回も書きましたけど、直感重視で構成するにはルールが複雑だし、理詰め重視でいくにはパターンの広がり方が大きい(ちょっと言葉を省略してます)ので制御しにくいと思っていたのです。いや、オモパファンの許容力を侮っておりました。


ウソワン

ウソもの、ってジャンルがあるのか判らんですが、盤面系のウソものって、ウソであるかどうかを判定する局面とそれ以外の局面が乖離しがちだなーと考えるのです。ウソワンは比較的スムーズに繋がっているとは思います。そこが人気の秘密と主張したいわけでもありませんですが。


クロボウズ

1×nを配置するパズルはたまに解くと新鮮ですね。モチコロもそうだったのですが、別解を生じさせないような解答図の制約が案外と強固なので、局所的な調整が難しくてしかもそこが面白いところ。なんかオモパファンにしか伝わらない表現になってしまいましたしオモパファンに伝わるとも期待しずらいあれですが。数字が表現していることが独特なので要素の決まり方が意外で良いです。


トライアングループ

初見ではどう解いたらよいのか途方に暮れてしまいましたが、線が進めないところに丁寧に×印をつけると劇的に解きやすくなり、しかも思いもよらないつながり方の出現が楽しめました。作成時は、スリリン風のドットで一行おきに0.5マスずれたようなものを起用すると、準備の簡便さと作業のしやすさのバランスが良いと思います。長さが少し把握しずらくなるかもなので、出題時の盤面は現行のものの方が良いでしょうが。


クロクローン

黒マスがにょろにょろと伸びる感触が心地よいですね。矢印に指されない2マス以上の黒マスのカタマリは別解なしには存在できないので、そこははなから期待しないという心構えが良いかも。個人的には現状のルール3での制約は強すぎるものしか表現できないように感じますけど、他が新鮮で馴染みがないので仕方ないのかもしれません。


ということでこんなで。マクラを本文より長くしてみよっかなとちょっと思ったとかそんなこともありましたとさ。

明けてました。

明けましていろいろですね。

パソコンを買い替えて、いろいろしてたら、2015年の年賀状用パズルが出てきたので公開します。


以下の5人の名前を5×9に納まるスケルトン枠に組んでください
ALICE
SHINO
AYA
YOKO
KAREN


ここ最近、特定の範囲にしか年賀状を送ってないのが如実に表れていて趣深いですね。
SHINOBUにして盤面を大きくすると別解が出るんじゃなかったかなたしか。
2016年分の年賀状は特にパズルは入れなかったのですが、twitterで発表したものとしては、


みんな+みんな+まなみんに=応援声援な


いやあお正月のまなみんも麗しかった。
ということで今年もよろしくだったりまーいろいろ適切にです。