2014年5月2日金曜日

約数の数

先日、Topcorder Single Round Match 466 DIV 2の500ポイントの問題を考えていましたが、解き方が全くわかりませんでした。

問題は、以下のとおりです。
    
Bob likes to play the lottery, but it's so hard to win without cheating. Each lottery ticket has an identifier which contains exactly n decimal digits. If an identifier contains only '0's, it is considered a winning ticket. Otherwise, the identifier is interpreted as a positive integer X written in decimal notation (possibly with leading zeros). If X has an odd number of positive integer divisors, it is a winning ticket, otherwise, it is not. A positive integer is a divisor of X if it divides X evenly. 



Unfortunately, Bob only has enough money to buy one ticket, and he cannot see the identifier before buying a ticket. Therefore, he decides to cheat by buying a ticket and modifying its identifier to make it a winning ticket. In a single change operation, he can choose one digit, erase it, and print some other digit in the same position. No other types of modifications are allowed. He can perform any number of these change operations, but he wants to perform as few as possible to minimize the risk of getting caught. 



You are given a String ID, the initial identifier on Bob's ticket. Return the minimal number of change operations necessary to transform the identifier into a winning one. If the initial identifier is already a winner, return 0.
要するに求めるのは、与えられたIDがすべて0にするのか、それとも約数が奇数個ある値に変換するかどちらか変更する数値の数の少ない手番数を答えなさいというもの。

情けないことに、約数が奇数個ある。というものがどんな数値なのか思いつきませんでした。(1つ1つ書いてみればわかったかもしれない)

地道に書いてみると以下のようになる。

1 = 1
2 = 1, 2
3 = 1, 3
4 = 1, 2, 4
5 = 1, 5
6 = 1, 2, 3, 6
7 = 1, 7
8 = 1, 2, 4, 8
9 = 1, 3, 9
10 = 1, 2, 5, 10
11 = 1, 11
12 = 1, 2, 3, 4, 6, 12
13 = 1, 13
14 = 1, 2, 7, 14
15 = 1, 3, 5, 15
16 = 1, 2, 4, 8, 16
17 = 1, 17
18 = 1, 2, 3, 6, 9, 18

ちなみに約数の数を数えるには、素因数分解をすると良いらしい。
18 = 2^1 * 3^2   ( 2 * 3 = 6個 累乗の数+1同士をかけると約数のパターン数がでる)

1〜18までの値で、約数が奇数となるのは、以下のとおり
1,4,9,16

規則性を見つけるとしたら、
1^2, 2^2, 3^2, 4^2, ..... となるから、ある値の2乗の値は、約数が奇数であることになる。

数学的な証明は目的としないので省略しますが・・・

これがわかると、あとは約数が奇数の数値に変えるのが手番が少ないのか、すべて0にするのが手番が少ないのかを考えればよいだけになる。

頭の硬くなった年代にはちょっとむずかしい問題でした・・・orz




2014年3月15日土曜日

GL04PとOCNのSIMカードを利用した通信費用削減の効果

2013年の12月からGL04Pを利用してしばらく経ちました。
携帯料金の平均的な金額はかなり下がり、以前は10,000円こえることもありましたが、現在はなんと2,000円。

パケ放題が馬鹿らしいくらい。

ただ、ちょっと通信がおそかったり、手間がかかるのが面倒な時がある。それが許容できれば経済的。


iostatの勘違い(redhat系)

正しく表示内容を理解していなかったといえばそれだけだけど・・・。
iostatの%utilのディスクビジー率。この値が大きければディスクが忙しいというイメージ。
だいたいあっていそうなので真剣に向き合わないで放置してましたが・・・。

ディスクビジーってなんだよ。って思うと不信感が出てきます。

%util は結局のところ、ディスクIOがどのくらい処理されていたかを示しているだけでこいつに振り回される必要はないと気づいた。
性能を表しているわけでもないし、この値が大きくても慌ててはいけないと。

ディスクIOがどのくらい処理されていたか、ということは、iostatなどの値で考えると次のようになる。

  svctm * ( r/s + w/s ) / 単位時間  (単位時間とは、iostatなどの情報の採取間隔と考えておいてください)
  参考:http://d.hatena.ne.jp/yohei-a/20110711/1310396665

この式を眺めていると気づくのは、%utilの値が大きくなる場合がいくつかあります。

  1. svctm(IOリクエストの平均処理時間(msec))が長い。
  2. r/s(1秒間あたりのread発行回数) か w/s(1秒間あたりのwrite発行回数)が多い
上記のいづれかが原因で%utilが大きな値を示しているかが重要です。
1msecで処理できているw/sが1000回実行された場合と、1secで処理できているw/sが1回実行された場合。どちらも%utilは同じ値です。
落ち着きましょう。(自分)

iostatには、他にもありますが、それはまた次の機会で

2013年12月15日日曜日

Androidのグラフ描画ライブラリを探してみる。

Androidアプリに限らず、ツールを作成しているとグラフが描きたい場面に遭遇することはあるかと思います。
しかしながら、グラフ描画をゼロから作成するなんて簡単ではないです。(少なくとも自分には)

そこで、だれかが開発しているであろうライブラリを探すのですが・・・
探す上で幾つか問題が出てきます。

1. 使いやすいのか?
2. ライセンスは大丈夫か?

など。いろいろなライブラリを紹介しているサイトがあるので一覧を作成しませんが、個人的に使おうと決めたライブラリを紹介。

achartengine なにが良かったのか。
当然ですが、描きたいグラフが描ける。ライセンスが厳しくない(厳しいとか厳しくないとかの次元ではないですが、Apache License 2.0)
あと、設定が細かくできるため使いやすかったです。

公開しているアプリもこれを使いました。

棒グラフと折れ線グラフが同じグラフに表示できたり、複数の折れ線グラフを重ねることができたり。
便利です。

Apache License は以下の2点だけ気をつけました。

1. Google Play の記載情報として、以下の文を載せる。
このソフトウェアは、 Apache 2.0ライセンスで配布されている製作物が含まれています。
2. ソースファイルに以下を追記する。(XXXXXXの箇所は隠しました。)
/*
* Copyright (C) 2013 XXXXXXXXX
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

他にもやることあるかもしれないですが、このくらいで。

2013年12月14日土曜日

Androidのアプリ開発におけるStringの注意点

なんとなく普段Javaを書く感覚で開発してたところ、Eclipseに出ていたWarningが気になった。

以下、出力された渓谷
Provides more information about this issue.
Calling String#toLowerCase() or #toUpperCase()
 without specifying an explicit locale is a common
 source of bugs. The reason for that is that those
 methods will use the current locale on the user's
 device, and even though the code appears to work
 correctly when you are developing the app, it will fail
 in some locales. For example, in the Turkish locale,
 the uppercase replacement for i is not I.
If you want the methods to just perform ASCII
 replacement, for example to convert an enum name,
 call String#toUpperCase(Locale.US) instead. If you
 really want to use the current locale, call
 String#toUpperCase(Locale.getDefault()) instead.


詳細メッセージを表示してみた。

URL書いてあったので移動(ここ)。

たぶん、文字列を扱う際に英語以外の言語に注意しろと言っていると思う。
トルコ文字の"i"と”I"は違うんだ!って書いてあった。
他の事例はわからんけど、toUpperCaseとか文字列変換を気軽にやると痛い目に会うよということらしい。
USはたくさん使ってる人いるし、使いやすい。みたいなことが書いてあってすごく適当な仕様だとおもった。

普段使う文には大丈夫なんだろうけど、Locale.USをいつも指定すれば、平気かなぁなんて考えてる。

Warningが減ったので気分はすこしすっきり。

2013年11月23日土曜日

SO_KEEPALIVEの設定はデフォルトで有効になっててほしい

プロセス間で通信を行うアプリケーションを作成した場合、ちょっと考えを怠ると、無通信な状態で応答を待ち続けてしまうことがある。

趣味で作っていたらすぐ直せばいいんだろうけど、そうも行かない場合もある。
そんなとき、ファイアウォールとかプロキシサーバとかが無通信状態のコネクションをさくっと切断してくれるので、一定時間経過すると必ず失敗する状態になってしまう。

一般的に、無通信状態は良くないので、サーバ側が応答無かった場合、リソースの開放の意味を含めてコネクションを切断する機能がOSに備わってたりする。

keepaliveはその無応答状態を検知して接続先に応答確認を行ってくれる。
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/tcp.7.html

何度も読んだり、検索したりしてkeepaliveってなんだろうと考えてたんだけど
少なくとも無通信状態を検出してコネクションを切断する奴らからコネクションを守る機能ではないと思った。

でも、そういう使い方もできるなぁと。
ちなみに、ソケット作成時にSO_KEEPALIVEをオプションとして有効にしないとこの機能は使われないので、誤ってサーバが無応答になったらクライアントも無応答に。。悲惨だ。。

2013年11月17日日曜日

SSID毎の通信量を確認したいため、Androidアプリを作りました。

GL04PにOCNのSIMを指して一ヶ月くらいが経過しました。
通信量は足りていると思うのですが、本当に十分かどうかを確認したいことと、
利用の抑制のため、通信量を確認したいと思ってました。

OCNのエントリーDでは、どこを探しても現在の通信量を表示するページはありませんでした。

そこで、こんなアプリを作成してみました。
あくまで通信量の目安ですが、通信量を把握することができます。

突貫で作成したため、昨日は殆ど無いですが、一月分の合計が見れればいいかなと。

Wi-Fi通信量 監視ツール

モバイルデータ通信をOFFにしてパケット代を節約しようとしている人には通信量の確認としてはいいのではと思います。


追加:2013年12月22日
FileDir.comに追加されたと連絡がありました。海外のサイトなので日本にはあまり関係ないですが、掲載していただいたのでリンクを張ります。
Download Wi-Fi traffic counter tool / Android