プログラム脳を鍛える数学パズル on python3
追記: とりま gist に置いてみた (2017/06/27
プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問
- 作者: 増井敏克
- 出版社/メーカー: 翔泳社
- 発売日: 2015/10/16
- メディア: Kindle版
- この商品を含むブログ (7件) を見る
お題はこれで、目標は1日1個以上。
…ダレ無いといいけど…。
続きを読む超久々に Python 弄ってた
AI 関連が実質 Python 一択で、数学系ライブラリもその表示も Python だとかなり揃ってたので、久々にやってみようとしてどハマりした記録。
何をしようとしたかというと、下記を Python で実装すればいいかなーとかとか漠然と考えてどハマりした。
プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問
- 作者: 増井敏克
- 出版社/メーカー: 翔泳社
- 発売日: 2015/10/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (8件) を見る
どこにはまったかというと問題2。
問題内容は書籍を買うか、下記を見て欲しい。
- 「Python だし、eval あるよねー使い方調べるついでに使って見るかー」
→ 9009 に*
突っ込むとしても90*09
とかになるとダウンする。09 ってなんぞやー - 「諦めて、
*
が必要な箇所で文字列区切って掛け算するか」
→ 変数タイポで 1h どハマり(実行時評価だから実行するまでわからないので単純なミスが見つからない) - 「計算できたし正解を比較するか」
→ 久々にやってて問題文間違って覚えてて、「計算の前後で出た四桁数字が順不同で含まれてることじゃね?」と勘違いして実装。
→ 片方の文字列を1時づつ取り出して、もう片方に含まれるか?という判定をするが、122 - 124 でも true になる。
→ なら逆も比較したらええやんと思いきや、122 - 12 で結局OK判定になってしまう。
→ なので、片方の文字列を1時づつ取り出して、もう片方から1字づつ削除(immutable じゃなくて背中が痒く…)してみるも、 Java の String.replace 同様の replace メソッドを見つけたが、第3引数に指定がないと replaceAll 同等動作とか知らずにハマる。
→ 突破したら突破したで仕様違いに気づいて脱力…回文かよ…
で、色々やった挙句、こんな単純な問題に 3 時間も悩まされたという。
途中途中で Syntax error に悩まされたのもでかい。
TextMate2 を使っているが、やっぱ IDE なんかでリアルタイムに syntax チェックしてないとわからん。
加えて言えば、実行字型の為に、動かしてから死んでデバッグの後戻りがひどかった…
慣れの問題なのだろうか、例えば代入時に変数名が一時違った位でも、「新しい変数ができた」と認識されて平然と動いてしまう為、何が悪いか超追いかけづらかった…。
結局最後は全部関数にした…もう…関数型で…イイヨ。
たとえ…Python に… tail call recursive が実装されてなかったとしても…!
positions = [ [1], [2], [3], [2, 1], [3, 2], [3, 1], [3, 2, 1] ] def split(str, pos, stack): if len(pos) == 0: stack.append(str) return stack else: i = pos[0] stack.append(str[i:]) return split(str[:i], pos[1:], stack) from functools import reduce def multiple(list): return reduce(lambda a,b: a * b, list) def is_kaibun(left, right): return left == right[::-1] for cur in range(1000, 9999): strCur = str(cur) for pos in positions: splitted = split(strCur, pos, []) result = multiple(map(lambda v: int(v), splitted)) if is_kaibun(strCur, str(result)): print(str(splitted) + " = " + str(result)) print("success: " + strCur)
Java8 の Stream が物足りない人たちへ
JUnit をもう少し管理者にみやすくしてみた
今日紹介するのはこれ。
Scala でザクッと作ってみた。
制作時間は調べ物 6h 、実装 4h か…
まだまだ精進が足りない。
こいつは先日書いた、JavaDoc を XML で吐き出すメモ - 謎言語使いの徒然 と、JUnit の結果をマージして出力するツールだ。
サンプルこんな感じ。
$ java -jar ut_converter.jar javadoc/javadoc.xml ut > result.html SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
で出てくるのがこんな感じ。
JUnit は Spec じゃ無いから、表現力が低い。
そのため、メソッド名は目安になるけど、それ単品ではテストレポートとして出すのが難しい。
そこで、Javadoc で細かくテスト内容書いておいたら、まとめて表示してくれるツールがどっかで要るなと。
2週間位前にリポジトリは作ってたけど、やっぱ平日に手を出す余裕ないね(汗
引数パースライブラリの SCOPT(3.6.0) 使ってみた
紹介するのはこれ
依存はこれだけ
libraryDependencies ++= Seq( "com.github.scopt" %% "scopt" % "3.6.0" )
で、引数を格納するクラスをこんな風に用意して
import java.io.File case class Config(javaDocXml: File, junitResultDir: File)
パース設定とかを用意する。
import java.io.File import scopt.OptionParser object ArgParser { val parser = new OptionParser[Config]("UTXmlConverter") { head("ut_converter", "1.0-SNAPSHOT") arg[File]("[JavaDoc XML path]") .required() .text("Path for XML file that using MarkusBernhardt/xml-doclet.") .action((f, c) => c.copy(javaDocXml = f)) .validate(v => { if (!v.isFile) Left("Not a file.") else if (!v.getAbsolutePath.endsWith(".xml")) Left("Not a XML file.") else Right() }) arg[File]("[UT XML dir path]") .required() .text("Path for unit test results directory path.") .action((f, c) => c.copy(junitResultDir = f)) .validate(v => if (v.isDirectory) Right() else Left("Not directory.")) help("help").text("print this usage text.") note( "This program requires XMLs that generated by MarkusBernhardt/xml-doclet (var 1.0.5)\n" + " and Junit test results XML files." ) } def parse(args: Array[String]): Option[Config] = { parser .parse(args, Config(new File("docs.xml"), new File("ut_results"))) } }
そして、引数指定しないで実行すると…
Error: Missing argument [JavaDoc XML path] Error: Missing argument [UT XML dir path] Try --help for more information.
おーいいね。
help 読んでみても…
$ java -jar ut_converter.jar --help ut_converter 1.0-SNAPSHOT Usage: UTXmlConverter [options] [JavaDoc XML path] [UT XML dir path] [JavaDoc XML path] Path for XML file that using MarkusBernhardt/xml-doclet. [UT XML dir path] Path for unit test results directory path. --help print this usage text. This program requires XMLs that generated by MarkusBernhardt/xml-doclet (var 1.0.5) and Junit test results XML files.
オプション引数や、引数バリデーションも書けるし、なかなかいいですね。
sbt を jar にしてみた
つっても何の事は無い。
これ突っ込んだだけ。
project/plugins.sbt
に下記を追加して
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.4")
build.sbt
でざっくり指定するだけ。
name := "Example" version := "1.0-SNAPSHOT" scalaVersion := "2.11.8" mainClass in assembly := Some("net.white_azalea.Application") assemblyJarName in assembly := "example.jar"
これして sbt assembly
するだけで、target/scala-2.11/example.jar
が出来上がる。
以上。
JavaDoc を XML で吐き出すメモ
やりたい事が何かと言うと、外部プログラムにおいて、Java クラスのリスト取得と、そのドキュメントを引き抜きたいと考えた。
しかしながら、単純に javadoc のコマンドだけ実行すると、HTML ファイルが出てくる。
これは JavaDoc コマンドの仕様であり、基本動作となっていて、中間ファイルなども出てきていないようだ。
要するに javadoc コマンドの中でパースやら構築やら全部やってしまっていて、その間にあるだろう Javaクラス構成とそのドキュメント構造を引っこ抜く事がこのままだとできない。
でも当たり前だが、同じことをしたい人なんて絶対いるだろうと…むしろ居ない訳がなかろうと思ったのだ。
そして散々悩んだところ、どうも JavaDoc には Doclet なる機構が存在するらしい。
この Doclet とは、JavaDoc で読み取ったデータを出力する際のデータ整形に使われるようだ。
つまりこいつに XML 生成の Doclet 食わせてやれば、XML が吐き出されると思われた。
で、探して見たところ案の定。
そりゃそーだよなと、むしろない訳ないよなと。
って事でやってみた。
続きを読む