「中学入試から:数字の個数」の実装例リンク集
毎度恒例実装例リンク集です。
今回はツイートをそのまま置く感じで。
答案 http://t.co/BuEAPazpj4 挑戦者求む!中学入試から:数字の個数 by @Nabetani http://t.co/uNO1GGq51x @codeiqさんから
— しえる(かめんにーと) (@cielavenir) November 18, 2014
数字の個数の提出解答 @Nabetani #CodeIQ http://t.co/ExUyATYqm6
— カニ戯(ry (@bananawani_mc) November 18, 2014
#CodeIQ 「中学入試から:数字の個数」解答コード公開しました。 @Nabetani https://t.co/ED0NLpGqTu
— みけCAT (@mikecat_mixc) November 18, 2014
「中学入試から:数字の個数」 @Nabetani FBありがとうございました。実装前のアルゴリズムの整理がもっと必要でした。私にとってはかなり手こずった問題でした。難解なコードになってしまいましたが、解答を公開します。 http://t.co/WJm4w1q65u #CodeIQ
— suppy(すっぴー) (@suppy193) November 18, 2014
ちゃっかりLA http://t.co/MQzYyDUk0s #codeiq > 挑戦者求む!中学入試から:数字の個数 by @Nabetani http://t.co/dt99cmVbQ4 @codeiqさんから
— あじ (@Azicore) November 19, 2014
FBありがとうございました。解答公開しました。
http://t.co/RT3vAFjsNL
挑戦者求む!中学入試から:数字の個数 by @Nabetani http://t.co/G6zXEQP7im @codeiqさんから
— haruya (@haruya1212) November 19, 2014
コード晒します。http://t.co/nKG99RSosM
「中学入試から:数字の個数」の 解説・解題 - Codeへの愛とCuriosity http://t.co/eYe8zonqhi
— Mu (@keiji_mu) November 18, 2014
@Nabetani 解いてみました。 http://t.co/ij5e9rDC4I
— nido(はなおか) (@nidouchi) 2014, 11月 27
事前に解けた方も、実装しようと努力して力尽きた方も、他の方の実装を見ておくといいと思う。
あと。解けた方は、是非解けてない方のためにも公開する方向で。
まだ解いていない方は、
http://nabetani.hatenablog.com/entry/codeiq_digicount_q1138
に問題が載っているので、まず解くところから。
「中学入試から:数字の個数」の 解説・解題
CodeIQ に「中学入試から:数字の個数」という問題
https://codeiq.jp/ace/nabetani_takenori/q1138
を出した。
中学入試算数問題第4弾。
挑戦の募集はすでに締めきっている。
というわけで、解説・解題。
で。
まずは問題
問題
■問題の概要
中学入試の問題に、以下の様な問題が出ることがあります。整数aのなかに現れるnの個数を《a, n》と表します。 例えば 《110, 0》=1 《1112, 1》=3 《1234, 5》=0 《141421, 4》=2 です。 このとき、100から200までの整数の中に現れる 2 の個数の合計、つまり 《100, 2》+《101, 2》+ … +《200, 2》 を求めなさい。この問題を
整数aのなかに現れるnの個数を《a, n》と表します。 例えば 《110, 0》=1 《1112, 1》=3 《1234, 5》=0 《141421, 4》=2 です。 このとき、AからBまでの整数の中に現れる C の個数の合計、つまり 《A, C》+《A+1, C》+ … +《B, C》 を求めなさい。と考え、A, B, C を入力として与えます。問題の答えを計算するプログラムを書いて下さい。
■具体的な課題
下記リンクの zip 内に data.txt というファイルがあります。
これらのファイルの各行は
「データID、空欄A〜Cの内容、空欄A〜Cの内容に対応した答え」
を TAB区切りでならべたものです。
ほとんどのデータは正しい答えになっています。
答えが間違っているデータが数件あります。それらのデータの ID を答えて下さい。■補足
・データIDがTで始まるデータは、すべて正しい答えになっています。テストにお使い下さい。
・不正な入力に対処する必要はありません。
・間違いの数は、5件より多く、20件より少なくなっています。
・空欄A〜C は、空白なしのコンマ区切りでならべられています。
・0<A、A+1<B<(10の18乗)、A, B はいずれも整数、C は0〜9 のいずれかです。
■資料
http://nabetani.sakura.ne.jp/codeiq/q1138.zip
上記リンク先の zip ファイルの中には、以下のファイル含まれています・ data.txt
→ 調査対象およびテストデータです。■解答形式
「【解答】」の行に続いて解答をお書き下さい。
「【感想・工夫した点など】」の行に続いて、感想、引っかかった点、工夫した点、問題が曖昧だと感じた場合はそこをどう解釈したか、などをお書き下さい。
「【言語と処理系】」の行に続いて、言語名、処理系のバージョン、コマンドラインオプションなどをお書き下さい。
「【ソースコード】」の行に続いて、ソースコードをお書き下さい。ソースコードが複数になるようでしたら、その旨がわかるようにお願いします。
こんな感じ。
FileReader が必ず close されるのかどうかの続き
FileReader が必ず close されるのかどうかの続き
FileReader が必ず close されるのかどうか ( http://nabetani.hatenablog.com/entry/2014/10/24/003239
)の続き。
結論
結論から書いてみる。
// 「BufferedReader に任せた」版 try (BufferedReader br = new BufferedReader(new FileReader(path))) { // do something. }
// 「FileReader close しすぎ」版 try ( FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr) ) { // do something. }
のどちらも正当。
私の場合
- 仕事で製品に入れるなら「FileReader close しすぎ」版を好む
- CodeIQ の解答とかに書くなら「BufferedReader に任せた」版を好む
と思う。
とはいえ、java.nio.file.Files.newBufferedReader が使えるのなら、そのほうが良い。
私について
実は。業務での Java 歴は1年ぐらいしかない。
CodeIQ で出す問題では、必要ならちゃんとコードを読む言語に入れているけど、正直あんまり自信がない。
状況をもう一度整理
「BufferedReader に任せた」版でマズイことが起こる条件は
A0. BufferedReader の new ( コンストラクタの前 ) でエラーが発生する
A1. BufferedReader のコンストラクタ内で例外・エラーが発生する
B. A で発生した例外・エラーがキャッチされ、処理が続く
C. リークしたハンドルが GC で回収されずに貯まる
という条件の組み合わせ( ( A0 or A1 ) and B and C ) が真になる場合に限られる。
順に見ていこう。
A0. BufferedReader の new ( コンストラクタの前 ) でエラーが発生する
これが発生するのはひどくまずい状況に限られる。
これが発生しない前提の仕事も多いと思う。
発生するのはメモリ不足だけなのか、クラスローダーとかが例外を投げることもあるのか、そのあたりはよくわかっていないんだけど、いずれにせよ、プロセスごと死んでもいい場合が多いと思う。
A1. BufferedReader のコンストラクタ内で例外・エラーが発生する
一方。
BufferedReader のコンストラクタ内には
new char[8192];
のようなことが書いてあり、状況によってはメモリ不足エラーは視野に入れておくべきだと思う。
※ 例外( Exception ) は発生しない。
結局どうなの?
これが原因で具体的にマズイことになることは極めて稀だと思う。
実際に発生する環境が用意できる気がしない。
稀とはいえ、私の理解が正しければ、「BufferedReader に任せた」版 だとトラブルになり、「FileReader close しすぎ」版 だとトラブルにならないという状況がありうる。
一方。「FileReader close しすぎ」版 は、正常系では FileReader を close しすぎていて、実行速度面でもメモリフットプリントでももったいない感じではある。
というわけで、どちらもメリット・デメリットがあるのでケースバイケースで使い分けるというのが正解だと思う。
で。
具体的には。
ウェブサーバー内で動くとか、組み込み機器内で動くとか言うことなら、「FileReader close しすぎ」版 がよい場合が多いと思う。
デスクトップアプリケーションなら、「FileReader close しすぎ」版 が良い場合が多いと思う。
ケースバイケースなんかめんどくさいからどっちかに決めたい、ということなら、「FileReader close しすぎ」版 が良いと思う。
「常にちょっと close しすぎ」と、「極稀にファイルハンドルリークするかも。しないかも。」だと、前者のほうがマシだと感じる。
とはいえ結局。
nio を使え、ということだと思う。
最後に
識者のツッコミお待ちしております。
追記
どうも、上記話は正しくなさそうな感じ。Java 難しい。
@Air_Hold nioの内部実装は
(略)
Reader reader = new InputStreamReader(newInputStream(path), decoder);
return new BufferedReader(reader);
— チョコレートバー (@Air_Hold) 2014, 10月 25
@Air_Hold
そこではtry-catchしてないですよ。
FileReaderのcloseが云々と言っておいて、newBufferedReader使えってのは意味不明すぎです。だからこそ太一さんは実装見ろとおっしゃったのですし。
— チョコレートバー (@Air_Hold) 2014, 10月 25
FileReader が必ず close されるのかどうか。
Java で、
try (BufferedReader br = new BufferedReader(new FileReader(path))) { // do something. }
というような記述をよく見る。
実際、上記のコードは Oracle 様 のサイト
http://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html
から連れてきたもの。
しかし。これって、 BufferedReader のコンストラクタとかその直前にあるはずのメモリ確保とかが例外を発生させると FileReader が close されないよね。
というわけで、
try ( FileReader fr = new FileReader(path); BufferedReader br = new BufferedReader(fr) ) { // do something. }
と書くべきだと思うんだけど、どうなんだろ。
以下、10/24の 午前1時ごろ更新
で。
Twitter に
#Java の try-with-resources についての記事
http://t.co/ucb7MH7FS5
を書いたよ。
教えて偉い人。
— 鍋谷 武典 (@Nabetani) 2014, 10月 23
と書いたところ、教えていただいたので tweet をはっておく。
@Nabetani 後者の方がより正しいのですがBufferedReaderのメモリ確保で失敗するような状況でFileReaderをcloseするだけのメモリを確保できるのか疑わしいですし、
— 太一 (@ryushi) 2014, 10月 23
@ryushi @Nabetani OutOfMemoryErrorが発生したらその後正常に動く保証はないので、宣言を別にしても閉じられない可能性があるのは同じですね
— 山本://裕介 (@yusuke) 2014, 10月 23
どうも、try に両方書くのが厳密には正解だけど、書いても意味がある場合が稀なので最初に上げた例のように書くことが多い、ということみたい。
以下、10/24の 19時ごろ更新
さらに情報を頂いたので貼ります。張ります。
@Nabetani @ryushi Errorが発生した場合に対応するコードを書くのは「厳密には正確」ではないんじゃないかと。Throwableを継承するクラスで、Exceptionはプログラムで対応可能、Errorは対応不可能なものなので
— 山本://裕介 (@yusuke) 2014, 10月 24
@Nabetani
BufferedReaderのcloseでFileReaderのcloseが呼ばれるので、分けて書くと2回FileReaderのcloseが発生します。
保証のない特殊な状況のために、普段余分なステップ発生させるのでは本末転倒だと思います。
— チョコレートバー (@Air_Hold) 2014, 10月 23
BufferedReader のコンストラクタ内で例外が発生するのが「対応不可能」だったり「保証のない特殊な状況」だったりするということみたい。
私は Java力不足で判断は保留。
少しずつ調べていこうと思っている。
それと。
補足ですが、ファイルのパスからBufferedReaderが欲しいのであれば、java.nio.file.Files.newBufferedReaderというAPIがあります。そちらの実装もご確認下さい。
— 太一 (@ryushi) 2014, 10月 23
nio なら迷いがないということみたい。
なるほど。
そして続編
FileReader が必ず close されるのかどうかの続き - Codeへの愛とCuriosity
。
「中学入試から:正三角形?二等辺?」の解答リンク集
というわけで、解答リンク集。
- http://ideone.com/xwysV3 ( @KoukiMino 様 / Python 3 )
- http://ideone.com/gCsaNy ( @g_m_k 様 / Python 3 )
- https://ideone.com/CJ1cET ( @suppy193 様 / ruby )
- http://ideone.com/bZtPk9 ( @jczni 様 / Python 3 )
- https://gist.github.com/kuuso/2791b8656e339fbdbf0b ( kuuso 様 / C# )
- https://gist.github.com/keiji-mu/933fe62fe71e07782717 ( @keiji_mu 様 / ruby )
- http://ideone.com/RgIU7r ( @cielavenir 様 / ruby )
- http://d.hatena.ne.jp/haruya12/20141018/1413589866 ( @haruya1212 様 / ruby)
- https://gist.github.com/nyaoyura/c2d7607064f2c1cb6a92 ( @nyaoyura 様 / ruby )
- http://ideone.com/0fIusa ( @bananawani_mc 様 / Java / バリデーションなし )
- http://ideone.com/kihCHf ( @bananawani_mc 様 / Java / バリデーションあり )
- https://gist.github.com/mikecat/92374dfa804039f3f6dc ( mikecat様 / C言語 )
- https://gist.github.com/basso414f/f1d91a14630e3b2f4e6a ( basso414f 様 / ruby )
- http://qiita.com/MasayaMizuhara/items/6e15d12d9a228ee5a17f ( MasayaMizuhara 様 / C++ / 解説あり )
- http://nabetani.hatenablog.com/entry/codeiq_clatri_q1097 ( 私 / ruby )
解いている方は、Code IQ 上で挑戦した方もそうでない方もぜひ解答を公開する方向で。
しかし ruby のシェアが圧倒的であることだなあ(詠嘆)
事前に解けた方も、実装しようと努力して力尽きた方も、他の方の実装を見ておくといいと思う。
まだ解いていない方は、
に問題が載っているので、まず解くところから。
「中学入試から:正三角形?二等辺?」の、解説・解題
CodeIQ に「中学入試から:正三角形?二等辺?」という問題
https://codeiq.jp/ace/nabetani_takenori/q1097
を出した。
中学入試算数問題第3弾。
挑戦の募集はすでに締めきっている。
というわけで、解説・解題。
で。
まずは問題
問題
■問題の概要
中学入試の問題に、以下の様な問題が出ることがあります。三角形ABCがあります。 角C=30度,BA=2cm,CA=2cm です。 この三角形の性質について正しく述べているものを下記のあ〜うからひとつ選んで下さい。 あ)正三角形である。 い)二等辺三角形である。(ただし、正三角形であるとはいえない。) う)二等辺三角形ではない。または、二等辺三角形かどうかわからない。ABとACが等しいので、二等辺三角形。つまり、「い」が正解です。
この問題を
三角形ABCがあります。 【 A 】 です。 この三角形の性質について正しく述べているものを下記のあ〜うからひとつ選んで下さい。 あ)正三角形である。 い)二等辺三角形である。(ただし、正三角形であるとはいえない。) う)二等辺三角形ではない。または、二等辺三角形かどうかわからない。と考え、A を入力として与えます。問題の答えを計算するプログラムを書いて下さい。
■具体的な課題
下記リンクの zip 内に data.utf8.txt および data.sjis.txt というファイルがあります。
これらのファイルの各行は
「データID、空欄Aの内容、空欄Aの内容に対応した答え」
を TAB区切りでならべたものです。
ほとんどのデータは正しい答えになっています。
答えが間違っているデータが数件あります。それらのデータの ID を答えて下さい。data.utf8.txt と data.sjis.txt は、文字コードが異なるだけで内容はまったく同じです。
お好きな方をお使い下さい。■補足
・データIDがTで始まるデータは、すべて正しい答えになっています。テストにお使い下さい。
・不正な入力に対処する必要はありません。
・間違いの数は、5件より多く、20件より少なくなっています。
・空欄Aに入る内容は、長さまたは角度について記述されたものをコンマ区切りでならべたものです。
・長さについては「AB=3cm」のような形式です。長さの単位はすべて cm です。
・角度については「角A=30度」のような形式です。頭に「角」があり、単位は「度」です。
■資料
http://nabetani.sakura.ne.jp/codeiq/q1097.zip上記リンク先の zip ファイルの中には、以下のファイル含まれています
・ data.utf8.txt
→ 調査対象およびテストデータです。文字コードは UTF-8 になっています。・ data.sjis.txt
→ 調査対象およびテストデータです。文字コードは Shift_JIS になっています。■解答形式
「【解答】」の行に続いて解答をお書き下さい。
「【感想・工夫した点など】」の行に続いて、感想、引っかかった点、工夫した点、問題が曖昧だと感じた場合はそこをどう解釈したか、などをお書き下さい。
「【言語と処理系】」の行に続いて、言語名、処理系のバージョン、コマンドラインオプションなどをお書き下さい。
「【ソースコード】」の行に続いて、ソースコードをお書き下さい。ソースコードが複数になるようでしたら、その旨がわかるようにお願いします。
こんな感じ。
「中学入試から:単位のある計算」の解答リンク集
というわけで、解答リンク集。
- http://d.hatena.ne.jp/haruya12/20140925 ( haruya12様 / ruby )
- http://ideone.com/d2NJOw ( @tomwot様 / ruby )
- https://gist.github.com/kuuso/6754d9321b5e1fe1d408 ( kuuso様 / C# )
- http://ideone.com/0a8MwJ ( @keiji_mu 様 / ruby )
- http://ideone.com/M9vnnl ( @Azicore様 / perl )
- http://ideone.com/7Juzdb ( @bananawani_mc 様/ Java )
- http://ideone.com/ilmPHV ( @cielavenir 様 / ruby )
- https://gist.github.com/mikecat/f23bb1aa6630ea2bf1f6 ( mikecat様 / C++ )
- http://qiita.com/nidouchi/items/6943fa89dca3e19a151e ( nidouchi 様 / ruby )
- http://nabetani.hatenablog.com/entry/codeiq_unit_q1058 ( 私 / ruby )
事前に解けた方も、実装しようと努力して力尽きた方も、他の方の実装を見ておくといいと思う。
まだ解いていない方は、
に問題が載っているので、まず解くところから。