tag:blogger.com,1999:blog-2093387744314789772024-02-21T06:14:45.670+09:00明日の今日個人的メモ帳放置ブログ。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.comBlogger92125tag:blogger.com,1999:blog-209338774431478977.post-1378362532084262712015-02-15T23:43:00.000+09:002015-02-15T23:43:20.148+09:00ブラウザとNode.jsで動作するライブラリの書いたときのやり方<h2>動機</h2><a href="http://aaharu.github.io/gifken/">gifken</a> というJavaScriptでGIF画像を作ったり、GIFアニメを分割や逆再生するようなライブラリをちまちま書いています。<br />
もともとブラウザで動作させることしか考えていなかったのですが、Node.jsでも動かせそうだったので、対応させたときのやり方を書きます。<br />
<span style="font-size: x-small;">(ただNode.js環境でGIF画像など扱いたい場合は </span><a href="http://aheckmann.github.io/gm/" style="font-size: small;">http://aheckmann.github.io/gm/</a><span style="font-size: x-small;"> などでGraphicsMagickやImageMagick使った方が素直だし速度面などを考えても良いです)</span><br />
<br />
<h2>導入</h2><span style="font-size: xx-small;">もっと良い方法がありそうな気もします……</span><br />
<br />
もともとのものが1つの大きなJavaScriptだったので、ブラウザ依存の処理と、共通で利用できる処理をまず分けました。<br />
Node.jsにはモジュールの仕組みが既にあり、ブラウザでその処理を動くようにするソフトウェアが既にあるのでそれを利用するのが楽でしょう。(Browserify, Webpackなど)<br />
私は <a href="http://browserify.org/">Browserify</a> を利用しました。<br />
<br />
Browserify の導入自体は楽だったのですが、Browserifyはrequireなどの依存関係を解決してJavaScriptファイルを書き出してくれますが、Browserifyで生成した関数に閉じた状態で出力されるので、scriptタグで読み込むだけで使えるようになる、という状態にはなりません。<br />
Browserify のオプションを見ても特にそれらしいものは見つかりませんでした。<br />
よって、以下のようにしました。<br />
<script src="https://gist.github.com/aaharu/dd40bd104da9d906a591.js"></script><br />
windowオブジェクトに追加してしまいます。<br />
<span style="font-size: x-small;">WebWorkerではwindowがglobal objectではないので、importScriptsする前に var window = self; とでもしてください……</span><br />
<br />
<h2>まとめ</h2><br />
Browserifyの導入とglobal objectへの追加で何とかなった。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-60289445852175747452014-04-10T01:19:00.003+09:002014-04-10T01:19:55.095+09:00Vert.xでScalaのサンプルをとりあえず動かす<a href="http://vertx.io/">Vert.x</a> が最近気になっているので、サンプルを動かすところまでやってみたいと思います。<br />
Javaのサンプルでもいいのですが、多言語対応がウリの1つで、Scalaでも書けるということなので、せっかくだからScalaを使ってみたいと思います。<br />
<br />
使用する Vert.x のバージョンは現在最新の 2.1RC3 を使います。<br />
<br />
<h2>Vert.x のインストール</h2><br />
<a href="http://vertx.io/install.html">公式サイトの手順</a>を参考に進めます。<br />
<br />
2.1RC3のダウンロード後、解凍する。<br />
<pre>$ tar -zxf ~/Downloads/vert.x-2.1RC3.tar.gz
$ ~/vert.x-2.1RC3/bin/vertx version
2.1RC3 (built 2014-04-02 10:07:26)
</pre><br />
<h2>Scala モジュールのインストール</h2><br />
2.1RC3の時点では、 Scala は標準では使えず、別途言語モジュールとして提供されているようです。<br />
詳しくは知らないですが、 <a href="http://modulereg.vertx.io/">Vert.x Module Registry</a> に <br />
<blockquote>io.vertx~lang-scala~1.0.0</blockquote>が登録されているので、どうやらこれのようです。<br />
<br />
<a href="http://vertx.io/mods_manual.html">公式のモジュールマニュアル</a>を参考にインストールしてみます。<br />
<br />
<pre>$ ~/vert.x-2.1RC3/bin/vertx install io.vertx~lang-scala~1.0.0
Attempting to install module io.vertx~lang-scala~1.0.0
Downloading io.vertx~lang-scala~1.0.0. Please wait...
Downloading 100%
Module io.vertx~lang-scala~1.0.0 successfully installed
Succeeded in installing module
</pre><br />
どうやらインストールできたっぽい。<br />
<br />
<h2>サンプルの実行</h2><br />
<a href="https://github.com/vert-x/vertx-examples">Vert.x Examples</a>としてサンプルがGitHubに公開されているので、 Scala の <a href="https://github.com/vert-x/vertx-examples/tree/master/src/raw/scala/route_match">Route Match</a> を動かしてみたいです。<br />
<pre>$ git clone https://github.com/vert-x/vertx-examples.git
$ cd vertx-examples/src/raw/scala/
$ ~/vert.x-2.1RC3/bin/vertx run route_match/RouteMatchExample.scala
Failed in deploying verticle
java.lang.ClassNotFoundException: route_match/RouteMatchExample.scala
at org.vertx.java.platform.impl.ModuleClassLoader.loadFromModule(ModuleClassLoader.java:127)
at org.vertx.java.platform.impl.ModuleClassLoader.loadClass(ModuleClassLoader.java:108)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.vertx.java.platform.impl.java.JavaVerticleFactory.createVerticle(JavaVerticleFactory.java:55)
at org.vertx.java.platform.impl.DefaultPlatformManager$21.run(DefaultPlatformManager.java:1723)
at org.vertx.java.core.impl.DefaultContext$3.run(DefaultContext.java:175)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:370)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at java.lang.Thread.run(Thread.java:724)
Failed in deploying verticle
java.lang.ClassNotFoundException: route_match/RouteMatchExample.scala
at org.vertx.java.platform.impl.ModuleClassLoader.loadFromModule(ModuleClassLoader.java:127)
at org.vertx.java.platform.impl.ModuleClassLoader.loadClass(ModuleClassLoader.java:108)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.vertx.java.platform.impl.java.JavaVerticleFactory.createVerticle(JavaVerticleFactory.java:55)
at org.vertx.java.platform.impl.DefaultPlatformManager$21.run(DefaultPlatformManager.java:1723)
at org.vertx.java.core.impl.DefaultContext$3.run(DefaultContext.java:175)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:370)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
at java.lang.Thread.run(Thread.java:724)
</pre>module のインストールがうまくいってない気がしてくるエラーです。<br />
<a href="http://vertx.io/mods_manual.html">http://vertx.io/mods_manual.html</a> をもう少し丁寧に読んでみると、 lang-impl に書いてあることが参考になりそうでした。<br />
~/vert.x-2.1RC3/conf/langs.properties を覗くと<br />
<blockquote>groovy=io.vertx~lang-groovy~2.0.0-final:org.vertx.groovy.platform.impl.GroovyVerticleFactory</blockquote>のような記述があり、これにならって Scala の設定も書けば動きそうな気がしてきます。<br />
<br />
<pre># ~/vert.x-2.1RC3/conf/langs.properties に以下を追加
scala=io.vertx~lang-scala~1.0.0:org.vertx.scala.platform.impl.ScalaVerticleFactory
.scala=scala
</pre><br />
再度サンプルを実行。<br />
<pre>$ ~/vert.x-2.1RC3/bin/vertx run route_match/RouteMatchExample.scala
Compiling route_match/RouteMatchExample.scala as Scala script
Starting route_match/RouteMatchExample.scala
Succeeded in deploying verticle
</pre>うまく実行されたので、 localhost:8080 を開いて動作を確認するところまでできました。<br />
<br />
<br />
とりあえず動かすとこまでできたので、次はパフォーマンスの検証などしてみたいです。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-22852254660559143602014-03-02T23:29:00.003+09:002014-03-02T23:30:08.693+09:00画像に文字を上書きできるようなものを作ってみたWEBにある画像の文字だけ書き換えたいなーってときに、一度保存してからペイントで編集して〜っていう作業が面倒だと思ったので、それっぽいものを作ってみた。<br />
<br />
<div>
<a href="http://komenuka.herokuapp.com/">komenuka</a></div>
<div>
<a href="http://komenuka.herokuapp.com/">http://komenuka.herokuapp.com</a></div>
<div>
<br /></div>
<div>
実は1年くらい前から公開してたのですが、放置してました。</div>
<div>
デザインももっとマシにしようとは思いつつも手をつけてないので察してください。</div>
<div>
<br /></div>
<div>
どういうことができるかというと、</div>
<div>
元画像( <a href="http://img.tiqav.com/3tB.jpg">http://img.tiqav.com/3tB.jpg</a> )があって、URLで必要な情報を与えることによって文字を上書きした画像( <a href="http://komenuka.herokuapp.com/tiqav/v1/%7B%22rectangle%22%3A%7B%22x1%22%3A545%2C%22y1%22%3A35%2C%22x2%22%3A660%2C%22y2%22%3A335%7D%2C%22tategaki%22%3A%7B%22x%22%3A598%2C%22y%22%3A32%2C%22text%22%3A%22%E5%92%B2%E3%81%95%E3%82%93%E3%81%8B%E3%82%8F%E3%81%84%E3%81%84%22%2C%22size%22%3A43%7D%7D/3tB.jpg">http://komenuka.herokuapp.com/tiqav/v1/%7B%22rectangle%22%3A%7B%22x1%22%3A545%2C%22y1%22%3A35%2C%22x2%22%3A660%2C%22y2%22%3A335%7D%2C%22tategaki%22%3A%7B%22x%22%3A598%2C%22y%22%3A32%2C%22text%22%3A%22%E5%92%B2%E3%81%95%E3%82%93%E3%81%8B%E3%82%8F%E3%81%84%E3%81%84%22%2C%22size%22%3A43%7D%7D/3tB.jpg</a> )ができます。</div>
<div>
<br /></div>
<div>
URLのパラメータをぽちぽち変更するのは大変だったので、JavaScriptで簡単なURLメーカーもつくりました。</div>
<div>
<a href="http://komenuka.herokuapp.com/make">http://komenuka.herokuapp.com/make</a></div>
<div>
<br /></div>
<div>
機能しょぼいですが、クソ文字コラメーカーぐらいにはなるのかなーという気はします。</div>
<div>
Twitter Cardsにも対応させた気がするので、Twitterでの画像展開もされるかも。</div>
aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-86988566149750202552013-10-06T17:46:00.001+09:002013-10-06T17:52:20.679+09:00JavaScriptでGIFアニメの分解と逆再生やってみたかったネット上に転がっているGIFアニメ、とても好きなのですが、フレーム早すぎてなにが写っているかわからないものもあったりでフレーム毎に分割したいと思うことが何度かありました。<br />
ImageMagickとかで分割とかはとても楽にできますが、貧弱なサーバーだとちょっとアクセス来ただけで残念なことになってしまうので、クライアント側でできないのかなってことでJavaScriptで実行してみることにした。<br />
<br />
一応それなりに動くところまでできたので公開します。<br />
現在Chrome拡張機能だけです。Firefoxはそのうち……<br />
<br />
ソース&説明: <a href="https://github.com/aaharu/gifken/tree/master/sample/chromeextension">https://github.com/aaharu/gifken/tree/master/sample/chromeextension</a><br />
ダウンロード: <a href="https://www.dropbox.com/s/gkrl4scag4hf2tt/chromeextension.crx">https://www.dropbox.com/s/gkrl4scag4hf2tt/chromeextension.crx</a><br />
<br />
実際使うとどんな感じになるのか?<br />
こんな感じになります。<br />
<br />
GifgigのとあるGIFアニメ。うまくできた&わかりやすい画像選んでみました。<br />
<a href="https://gifgig.com/pin/316">岐阜gazo - まどマギ</a><br />
<a href="https://gifgig.s3-ap-northeast-1.amazonaws.com/pins/2013/09/gif_d1a2232e05565e77401bc5c70976e3bb_316.gif" imageanchor="1"><img border="0" src="https://gifgig.s3-ap-northeast-1.amazonaws.com/pins/2013/09/gif_d1a2232e05565e77401bc5c70976e3bb_316.gif" /></a><br />
<br />
右クリックで「GIFアニメ分解」を選択<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibXv1f8YenDqB6AQmtvcgQvWZ0HcCDY0JDiMacYtb0y-B0VArCawaC0DJneVOkMQZ5OO9YlTNCS4rjN8UL2vX9ktkVsfHiZsRAqm-9bc3CzwLMxsI0L4Q23FIGeqmMKn6LVc7A5qSbPKgY/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-10-06+17.37.45.png" imageanchor="1"><img border="0" height="370" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibXv1f8YenDqB6AQmtvcgQvWZ0HcCDY0JDiMacYtb0y-B0VArCawaC0DJneVOkMQZ5OO9YlTNCS4rjN8UL2vX9ktkVsfHiZsRAqm-9bc3CzwLMxsI0L4Q23FIGeqmMKn6LVc7A5qSbPKgY/s400/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-10-06+17.37.45.png" width="400" /></a><br />
<br />
新しいタブで結果画像が表示される<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg52qpJzlmgnyvsxITrt3uwDizuFwvEBjTodJj8l9lE63cy11aDVJD4_QAF1OEzLVgg3otFyhqloHU5UsEEhyphenhyphen8NYNswxDqlAvDvmiMEccbWJWPAUzL6i7V8JQkSDVpjS_tMnALUeB56Ogj2/s1600/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-10-06+17.42.36.png" imageanchor="1"><img border="0" height="283" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg52qpJzlmgnyvsxITrt3uwDizuFwvEBjTodJj8l9lE63cy11aDVJD4_QAF1OEzLVgg3otFyhqloHU5UsEEhyphenhyphen8NYNswxDqlAvDvmiMEccbWJWPAUzL6i7V8JQkSDVpjS_tMnALUeB56Ogj2/s400/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88+2013-10-06+17.42.36.png" width="400" /></a><br />
<br />
ArrayBufferでバイナリ解析できるので、それで実装しています。バイナリ解析行っているところはTypeScriptで実装してみました。<br />
不完全なので、うまくいかない画像あったら教えてください。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-41508550865661699342013-05-11T22:16:00.001+09:002013-05-11T22:21:09.121+09:00EaselJS (CreateJS) を拡張してTextで縦書きできるようにしてみた最近EaselJSをさわりはじめたんですが、AS3を少しやっていたのでAPIがにていてわかりやすいです。<br />
そんなに複雑なもの作ろうとしているわけじゃないので、別に素のJSをつかってかいても良かったんですが、、、<br />
<br />
EaselJSの<a href="http://www.createjs.com/Docs/EaselJS/classes/Text.html">Text</a>ですが、例によって縦書きはできないようで、縦書きをたまに使用する日本人にはかゆいところに手が届かない感じです。<br />
EaselJSはMITライセンスのOSSだったので、勉強がてら拡張して縦書きもできるTextExを作ってみました。<br />
<br />
<a href="http://komenuka.herokuapp.com/js/TextEx.js">TextEx.js</a><br />
<br />
変更点はdirectionプロパティを追加して、directionが"vertical"のときforで一文字ずつ縦に描画するようにしただけです。<br />
<pre class="brush: diff">--- Text.js 2013-05-11 19:36:31.000000000 +0900
+++ TextEx.js 2013-05-11 20:57:56.000000000 +0900
@@ -41,7 +41,7 @@
* multiple font styles, you will need to create multiple text instances, and position them manually.
*
* <h4>Example</h4>
- * var text = new createjs.Text("Hello World", "20px Arial", "#ff7700");
+ * var text = new createjs.TextEx("Hello World", "20px Arial", "#ff7700");
* text.x = 100;
* text.textBaseline = "alphabetic";
*
@@ -59,17 +59,17 @@
* @param {String} [color] The color to draw the text in. Any valid value for the CSS color attribute is acceptable (ex.
* "#F00", "red", or "#FF0000").
**/
-var Text = function(text, font, color) {
+var TextEx = function(text, font, color) {
this.initialize(text, font, color);
}
-var p = Text.prototype = new createjs.DisplayObject();
+var p = TextEx.prototype = new createjs.DisplayObject();
/**
* @property _workingContext
* @type CanvasRenderingContext2D
* @private
**/
- Text._workingContext = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas")).getContext("2d");
+ TextEx._workingContext = (createjs.createCanvas?createjs.createCanvas():document.createElement("canvas")).getContext("2d");
// public properties:
/**
@@ -142,6 +142,13 @@
**/
p.lineWidth = null;
+ /**
+ * Indicates the text direction. Any of "horizontal" or "vertical". Default is "horizontal".
+ * @property direction
+ * @type String
+ */
+ p.direction = "horizontal";
+
// constructor:
/**
* @property DisplayObject_initialize
@@ -182,7 +189,7 @@
p.DisplayObject_draw = p.draw;
/**
- * Draws the Text into the specified context ignoring it's visible, alpha, shadow, and transform.
+ * Draws the TextEx into the specified context ignoring it's visible, alpha, shadow, and transform.
* Returns true if the draw was handled (useful for overriding functionality).
* NOTE: This method is mainly for internal use, though it may be useful for advanced uses.
* @method draw
@@ -226,7 +233,7 @@
/**
* Returns the approximate height of multi-line text by multiplying the number of lines against either the
- * <code>lineHeight</code> (if specified) or {{#crossLink "Text/getMeasuredLineHeight"}}{{/crossLink}}. Note that
+ * <code>lineHeight</code> (if specified) or {{#crossLink "TextEx/getMeasuredLineHeight"}}{{/crossLink}}. Note that
* this operation requires the text flowing logic to run, which has an associated CPU cost.
* @method getMeasuredHeight
* @return {Number} The approximate height of the drawn multi-line text.
@@ -236,12 +243,12 @@
}
/**
- * Returns a clone of the Text instance.
+ * Returns a clone of the TextEx instance.
* @method clone
- * @return {Text} a clone of the Text instance.
+ * @return {TextEx} a clone of the TextEx instance.
**/
p.clone = function() {
- var o = new Text(this.text, this.font, this.color);
+ var o = new TextEx(this.text, this.font, this.color);
this.cloneProps(o);
return o;
}
@@ -252,7 +259,7 @@
* @return {String} a string representation of the instance.
**/
p.toString = function() {
- return "[Text (text="+ (this.text.length > 20 ? this.text.substr(0, 17)+"..." : this.text) +")]";
+ return "[TextEx (text="+ (this.text.length > 20 ? this.text.substr(0, 17)+"..." : this.text) +")]";
}
// private methods:
@@ -266,7 +273,7 @@
/**
* @method cloneProps
- * @param {Text} o
+ * @param {TextEx} o
* @protected
**/
p.cloneProps = function(o) {
@@ -284,7 +291,7 @@
* @protected
**/
p._getWorkingContext = function() {
- var ctx = Text._workingContext;
+ var ctx = TextEx._workingContext;
ctx.font = this.font;
ctx.textAlign = this.textAlign||"start";
ctx.textBaseline = this.textBaseline||"alphabetic";
@@ -333,16 +340,28 @@
/**
* @method _drawTextLine
* @param {CanvasRenderingContext2D} ctx
- * @param {Text} text
+ * @param {String} text
* @param {Number} y
* @protected
**/
p._drawTextLine = function(ctx, text, y) {
// Chrome 17 will fail to draw the text if the last param is included but null, so we feed it a large value instead:
+ if (this.direction === "vertical") {
+ var lineHeight = this.lineHeight||this.getMeasuredLineHeight();
+ if (this.outline) {
+ for (var i=0, l=text.length; i<l; ++i) {
+ ctx.strokeText(text.charAt(i), -y - lineHeight, i*lineHeight, this.maxWidth||0xFFFF);
+ }
+ } else {
+ for (var i=0, l=text.length; i<l; ++i) {
+ ctx.fillText(text.charAt(i), -y - lineHeight, i*lineHeight, this.maxWidth||0xFFFF);
+ }
+ }
+ } else {
if (this.outline) { ctx.strokeText(text, 0, y, this.maxWidth||0xFFFF); }
else { ctx.fillText(text, 0, y, this.maxWidth||0xFFFF); }
-
+ }
}
-createjs.Text = Text;
-}());
\ No newline at end of file
+createjs.TextEx = TextEx;
+}());</pre>aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com1tag:blogger.com,1999:blog-209338774431478977.post-45586116994313016782012-01-22T22:37:00.001+09:002012-01-29T23:48:47.953+09:00きんつば今日は上野・浅草あたりをぶらぶらしてきたんですが、お店で「きんつば」を見つけたので買ってみました。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW7Ntk0jqDvTXsakgfk80Z84hKkSjxMi0ndF0IkFwOleI8XttFWgpcUIsp1eIRvLc6wZsIgytKOeD0q3K8LNBMtAJ-6DFDZz4TFGp0ZDBQkZrFZa5ACpW5wwK4qhxQmWglEnGduKzo7gTh/s1600/IMAG0028.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgW7Ntk0jqDvTXsakgfk80Z84hKkSjxMi0ndF0IkFwOleI8XttFWgpcUIsp1eIRvLc6wZsIgytKOeD0q3K8LNBMtAJ-6DFDZz4TFGp0ZDBQkZrFZa5ACpW5wwK4qhxQmWglEnGduKzo7gTh/s320/IMAG0028.jpg" width="320" /></a></div>
<br />
この「きんつば」というお菓子、Wikipediaにも書かれてますが、私の出身のほう(福島県会津)では、今川焼き(大判焼き)のことをきんつばと呼んでたりします。<br />
<a href="http://ja.wikipedia.org/wiki/%E3%81%8D%E3%82%93%E3%81%A4%E3%81%B0">http://ja.wikipedia.org/wiki/%E3%81%8D%E3%82%93%E3%81%A4%E3%81%B0</a> <br />
<br />
各地で呼び方が異なるならまだしも、その名前の別のお菓子があるとなると非常に紛らわしいです。罠です。陰謀です。<br />
<br />
地元の人は今川焼きじゃないきんつばのこと知らない人が多いんじゃないかと思います。私も知ったのは比較的最近(大学生の時)で、友人に話しても「え?マジで?」みたいな反応です。<br />
会津でも場所によると思いますが、喜多方、若松あたりはきんつばって呼んでる?と思うので、ほぼ会津全域そうなんじゃないかなー。<br />
中通りになるとどうだかしらないですけど。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-53090419191795632602012-01-08T00:57:00.000+09:002012-01-08T01:01:11.625+09:00Flashで3Dなお絵描き大学の時にブラウザ上で3Dモデルに絵を描くアプリケーションを作りました。<br />
<br />
長い間ブログを放置していたので、それの紹介でもしたいと思います。<br />
<br />
まずブラウザで3Dを扱うというのはあまりない話です。重いですし。<br />
下のリンクでは描いたテクスチャを3Dモデルに貼り付けるようなことをやっていました。<br />
<a href="http://labs.logosware.com/archives/21">http://labs.logosware.com/archives/21</a><br />
<br />
なんやかんやあってFlashで作るのがいいだろうって話になって、そこからは自分がいろいろ試して作っていくことになりました。<br />
Flashもそんな詳しいわけではなかったし、3Dは全く分からないというぐらいだったので開発には苦労しました。<br />
ブログの過去記事などを見ると試行錯誤の跡が少し見られると思います。<br />
<br />
まず3Dモデルをどうするかという話でしたが、開発メンバーが有料のモデリングソフトもってない、Flashの3Dライブラリでサポートされてるといった点などを考えた結果、Collada(.xml)形式にしました。<br />
<br />
で、3Dライブラリは当時(今でも?)一番メジャーなPapervision3Dにしようと考えていました。<br />
<br />
<a href="http://blog.r3c7.net/?p=333">http://blog.r3c7.net/?p=333</a><br />
上の記事を参考にサンプルを作っていきました。3Dモデルの作成や、マウスイベントなど苦労しましたがなんとかそれっぽいものはできました。<br />
じゃあ次はシェーダーを試そうと思った時に問題が起きました。<br />
<a href="http://aaharu.blogspot.com/2009/10/pv3duv.html">http://aaharu.blogspot.com/2009/10/pv3duv.html</a><br />
UVマッピングを使用したモデルにシェーダーを適用すると黒い線が出てきました。<br />
これの解決方法は結局わからず、Papervision3D以外のライブラリではどうなのか試してみることにしました。<br />
<br />
で、試したのがAway3Dです。<br />
まあFlashの3Dライブラリといってもメジャーなのは、Papervision3DとAway3DとAlternativa3Dぐらいでしたし、Papervision3Dから派生したものだと聞いて今までのが移植しやすいかなーと。<br />
<br />
それで試した結果、Away3Dは問題なく動作することがわかり、3DライブラリはAway3Dを使用することに決めました。<br />
Away3Dにして良かった点はいくつかありました。<br />
・上の黒い線の問題が解決したこと<br />
・3Dマウスイベントが豊富なこと<br />
・シェーダーなども豊富で、きれいであったこと<br />
絵を描くということを考えると3Dのオブジェクトのマウスイベントがあるのはとてもよかったです。<br />
悪いと思った点もいくらかあります。<br />
・重い<br />
・そんなに移植しやすいわけではなかった<br />
<br />
とそんな感じでぐだぐだと作りました。<br />
せっかくなので、FlashDevelopで書き直した、一部機能削除版をソースコードごと公開します。(開発時はFlashBuilderを使いました。学生だったので無料ライセンスで)<br />
今見るといろいろと直したくなりますがそこらへんは許してやってください。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXFNXeuAF-LwSPllOXp-Fk5gL07EXP3_CB7GChPrSSvjLJbAwFRdB8ke1Z0AkILojEyjthgQ0J1xYvj164nOi19MFdmm6DqEqOB5j5otZbLE1Ya9-qi5yAfNGMls6DwRazromRA2OdjKl/s1600/uru.png" imageanchor="1" style=""><img border="0" height="260" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXFNXeuAF-LwSPllOXp-Fk5gL07EXP3_CB7GChPrSSvjLJbAwFRdB8ke1Z0AkILojEyjthgQ0J1xYvj164nOi19MFdmm6DqEqOB5j5otZbLE1Ya9-qi5yAfNGMls6DwRazromRA2OdjKl/s320/uru.png" /></a></div><br />
Flexアプリ <a href="http://www.aaharu.com/data/UruLabCreater.swf">http://www.aaharu.com/data/UruLabCreater.swf</a><br />
ソースコード(Flex) <a href="http://www.aaharu.com/data/srcview_urulabcreater/index.html">http://www.aaharu.com/data/srcview_urulabcreater/index.html</a><br />
ソースコード(ライブラリ)<a href="http://www.aaharu.com/data/srcview_urulab/index.html">http://www.aaharu.com/data/srcview_urulab/index.html</a><br />
<br />
ソースコード書き出し後に修正行ってるのでソースコード最新じゃないですけどだいたいあってます。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-34696822844359837772011-08-10T23:01:00.000+09:002011-08-10T23:01:46.223+09:00GAE/PのtemplateのextendsでちょっとはまったGoogle App Engine (Python) のdjangoのテンプレートを使っていてちょっと躓いたことがあった。<br />
<br />
私は、 http://www.aaharu.com/ というサイトを持っていますが、これはGAEで作っていて、DNSもGoogle Appsで設定しています。<br />
お金がかかっているのはドメインだけ。<br />
<br />
以前まではテンプレートを使わないでHTMLを表示していたわけですが、更新のたびにすべてのHTMLを変更するのが面倒になったので、テンプレートを使ってみることにしました。<br />
GAEには標準でDjangoのテンプレートエンジンが入っていて、テンプレート継承の仕組みがあります。<br />
<a href="http://djangoproject.jp/doc/ja/1.0/topics/templates.html">http://djangoproject.jp/doc/ja/1.0/topics/templates.html</a><br />
<a href="http://d.hatena.ne.jp/griefworker/20091028/gae_inherit_template">http://d.hatena.ne.jp/griefworker/20091028/gae_inherit_template</a><br />
<br />
それで、テンプレート継承を使ってみたわけなのですが、HTMLの表示がくずれる現象が起きました。<br />
HTMLのソースを表示させても問題は見当たらない。そしてなぜかOperaだけは正しく表示してくれる。<br />
<br />
Chromeの『要素を検証』で確認してみると、どうやらbase.htmlの内容の前に空文字が挿入されているようだったので原因をいろいろ調べると、原因はUTF-8の<a href="http://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF">BOM</a>だった。<br />
base.htmlがBOMありのUTF-8だったため、先頭の1文字を変な風に解釈していたようです。<br />
<br />
というわけで、PythonでUTF-8扱うときはBOMは消そうと思いました。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-24791357772192567372011-07-24T00:16:00.002+09:002011-07-24T00:28:28.035+09:00ドリキャスの怪しげな商品購入してみた社会人になって多少懐にも余裕が出たので、ネタ商品を購入してみた。<br />
<br />
今回買ったのはこれです。<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=aaharu-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=B0053AY1FC" style="height: 240px; width: 120px;"></iframe><br />
私が購入した時はAmazonでは品切れだったので、Yahoo!ショッピングを利用しました。<br />
<a href="http://atq.ck.valuecommerce.com/servlet/atq/referral?sid=2219441&pid=877212733&vcptn=shpg%2Fp%2FBeL6ALurTa.1LOOJM2zb&vc_url=http%3A%2F%2Fstore.shopping.yahoo.co.jp%2Fichibankan%2F43-8241.html" target="_blank"><img alt="Dreamcast SDL/TF(microSD) / ドリームキャスト専用 バックアップツール" border="0" src="http://item.shopping.c.yimg.jp/i/j/ichibankan_43-8241" /><br />
Dreamcast SDL/TF(microSD) / ドリームキャスト専用 バックアップツール<img border="0" height="1" src="http://atq.ad.valuecommerce.com/servlet/atq/gifbanner?sid=2219441&pid=877212733&vcptn=shpg%2Fp%2FBeL6ALurTa.1LOOJM2zb" width="1" /></a><br />
<br />
今現在(2011年7月)は4千円程度が相場でしょうか。<br />
以前はオークションで8千円以上はしたドリームキャストのブロードバンドアダプターも、この方法ができてから値下がり傾向にあるっぽい?です。<br />
<br />
商品説明に『※玄人専用』って書いてあるのがなんかアレゲです。<br />
<br />
少し知識があれば<a href="http://f17.aaa.livedoor.jp/~takotako/dcserial_ft232bm.php">こちら</a>のサイトを参考に自作できるようなもので、結構安く仕上がるものらしいです。<br />
でも道具も知識もないのでとりあえず買ってみることにした。<br />
<br />
使うもの<br />
DC本体(MIL-CD対応版)<br />
上の商品<br />
microSD<br />
CD<br />
<br />
手順<br />
dcsdripを <a href="http://f17.aaa.livedoor.jp/~takotako/dcserial_ft232bm.php">http://f17.aaa.livedoor.jp/~takotako/dcserial_ft232bm.php</a> からDL<br />
↓<br />
CDに焼く<br />
参考: <a href="http://ayasuke.exblog.jp/14771039/">http://ayasuke.exblog.jp/14771039/</a><br />
私も上のサイトと同じようにDir2bootを使用しましたが、DiscJugglerがなかったので代わりにImgBurnを使用しました。dllファイルがないと言われたのでそこは適当にやっつけた。<br />
ImgBurnでよくわからないアラートが出たけど無視しても問題なかった。<br />
↓<br />
CDをDCにセットして吸出し<br />
参考: <a href="http://ayasuke.exblog.jp/14773019/">http://ayasuke.exblog.jp/14773019/</a><br />
ちなみに同じファイル名があった場合上書きされる仕様なので、2枚分のデータを1つのSDにやりたいときは名前変えるとよろし。<br />
実機ではプレイできても、少しでも傷がついているものはリードエラーになるものが多かったです。<br />
↓<br />
nulldcをDL<br />
<a href="http://code.google.com/p/nulldc/">http://code.google.com/p/nulldc/</a><br />
上のページにあるように、<a href="http://www.microsoft.com/downloads/ja-jp/details.aspx?familyid=a7b7a05e-6de6-4d3a-a423-37bf0912db84&displaylang=ja-nec">Visual C++ 2010 Runtimes</a>と<a href="http://www.microsoft.com/downloads/ja-jp/details.aspx?familyid=2da43d38-db71-4c1b-bc6a-9b6652cd92a3&displaylang=ja-nec">DirectX 9c Runtimes</a>が必要。<br />
データフォルダにflashとbiosを名前を変えて置けば準備完了。<br />
<br />
nulldcはShiftがスタートで、xcvbがABCD、asがLRとかでした。キーボードよりも360コントローラーでやるとやりやすそうですね。<br />
しかし、nulldcの開発自体は去年から止まっているっぽい?<br />
寄付も募集していたようですけど、今はどうなっているのかよくわらかないです。<br />
あと、日本語フォルダ読めないようなので注意。<br />
<br />
nulldcの完成度はそこそこですが、これ以上のアップデートもなさそうだし、互換が完璧というわけでもないので、やはりVGAボックスと実機でプレイというのが今のとこ一番かなぁ。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikYJmXhjVJ6fmPeSYo283QD8TVkU8jY3_cZd3d75L9HBNsHBNvtV6q6LMG05ZVzW94mWYy-K5YmvKAkdpTQYZK7LBXDuBcNfjpMEhR3chTzBS1vxiJ9ed2ghWy9bHw6tlrhSpzAOjE7kru/s1600/%25E3%2582%25AD%25E3%2583%25A3%25E3%2583%2597%25E3%2583%2581%25E3%2583%25A3.PNG" imageanchor="1"><img border="0" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikYJmXhjVJ6fmPeSYo283QD8TVkU8jY3_cZd3d75L9HBNsHBNvtV6q6LMG05ZVzW94mWYy-K5YmvKAkdpTQYZK7LBXDuBcNfjpMEhR3chTzBS1vxiJ9ed2ghWy9bHw6tlrhSpzAOjE7kru/s200/%25E3%2582%25AD%25E3%2583%25A3%25E3%2583%2597%25E3%2583%2581%25E3%2583%25A3.PNG" width="200" /></a></div>aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com1tag:blogger.com,1999:blog-209338774431478977.post-42524565728656629732011-04-26T21:56:00.001+09:002011-04-26T22:07:03.433+09:00アイマス2 ファーストレビュー最近プログラミングしてなくてネタがないのでゲームレビューする。<br />
<br />
『アイドルマスター2』<br />
まだクリアしてないので、ファーストレビューです。セカンド以降はあるか微妙ですが。<br />
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=aaharu-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=B003V1WILE" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><br />
<br />
過去シリーズは、360版、L4U、SP(ミッシングムーン)、DSってプレイしてます。つまりAC版以外だいたいやってる。<br />
<br />
アイマス待望の続編ってことで期待されてた作品ですが、発売前からネットで騒ぎ(?)を起こして、悪い意味で話題にもなった作品です。<br />
<br />
プレイ時間は今のところ5時間程度。中盤なのかな?<br />
あくまで今の時点でのレビューです。<br />
<br />
・良い点<br />
グラフィック<br />
新曲<br />
新キャラ(響と貴音)<br />
S4U<br />
<br />
良い点は上で挙げた通り。<br />
S4Uはこれだけで楽しめるし自分は好きです。<br />
<br />
・良くない点<br />
曲の数<br />
序盤<br />
テンポ<br />
ステージ<br />
<br />
曲の数は特別少ないわけではありませんが、前作であった曲がないというのはさみしい。<br />
容量的に厳しいのかもしれませんが、あったほうがよかったなーって思います。<br />
また、今回はトリオを組むのが基本なのですが、序盤はメンバー内の仲が悪かったりします。<br />
正直アイドル同士の仲が悪いのを見たくないw<br />
やよいが、「今日も仲良し2人組で、、あっ! すみません! 3人組 で・・・」なんて言うとか耐えられないぉ(´;ω;`)<br />
<br />
あと相変わらずテンポが悪いです。<br />
もうこれはシリーズ通してそう感じてるんで半分諦めてますが・・・<br />
「突風アイドル・・・」とかいらねーから。<br />
ついでに言うとレッスンもいらないと個人的に思う。中途半端なアクションとかいらない、シミュレーションでいい。<br />
<br />
最後にステージについてですが、残念だと思うことが2つ。<br />
1つは歌うパートが選べないということ。ユニットのポジションで決まってるっぽい?<br />
もう1つはカメラ。これも選べなくなっているんですが、自分はむしろそれよりもDSにあった視点がなくなってるのが残念です。<br />
DSでは、アイドル後方から観客席を移すカメラアングルがあったんですよね。<br />
<a href="http://www.youtube.com/watch?v=5AbFeMRcGAQ#t=0m28s">こんなの</a><br />
自分はこれが気に入っていて、DSで一番良かったものだと思ってるくらい。<br />
<br />
まだやりこんでないので、間違ってたらごめんなさい。<br />
悪い点ばかり長く書いてますが、つまらないってわけじゃないです。<br />
中盤以降はやることもわかってきて、アイドルもギスギスしてないので面白いです。<br />
<br />
<br />
というか2でサイネリアが1位とかどういうことなの・・・<br />
<br />
DSってゲーム性がなくて、あまり評価されてない面もありますが、自分は好きです。<br />
変態的な(主に涼ちん)シナリオが目立ちますが、システムも頑張ってたんだなーと。まあグラフィックと音質はDSなんであれなんですが。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-52851094369241832562011-04-23T21:39:00.000+09:002011-04-23T21:39:17.140+09:00FlexのBase64DecoderDC startup generatorのソースコードを少し修正した。<br />
んで、mx.utils.Base64Decoderを使うときにちょっと躓いたのでメモ。<br />
<br />
修正個所は、zlib圧縮をやめたのと、<br />
修正前はライブラリを使ってBase64を扱っていたのですが、どうやらFlex4には最初から<br />
mx.utils.Base64Decoder<br />
なるものがあるらしいので使ってみることにした。<br />
<br />
*自分はFlash Builder 4で開発してます。<br />
<br />
まず、普通にAS3プロジェクトを作ってもBase64Decoderをインポートできない。<br />
「framework.swc」というswcファイルが必要になります。<br />
<a href="http://blog.wszz.org/archives/650">Base64Encoder/Base64Decoderを使う</a><br />
これはSDKがあるディレクトリの、[frameworks/libs]の中にあります。<br />
<br />
しかしまだエラーが残るので厄介。<br />
<a href="http://blog.glasses-factory.net/2010/09/26/Base64Deoder-utils">Base64Decoder 使おうとしたら「リソースバンドルutilsを解決できません」とか言い出したのでやっつけた</a><br />
なぜかダミーのフォルダを作らないといけないようです・・・<br />
<br />
あとは問題なく使えます。<br />
設定さえ終われば便利です。<br />
<br />
以下ソースコード。<br />
<pre class="brush:as3">package
{
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.filters.BlurFilter;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.ByteArray;
import mx.utils.Base64Decoder;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Cubic;
import org.libspark.betweenas3.easing.Quad;
import org.libspark.betweenas3.tweens.ITween;
public class DC extends Sprite
{
private function Base64toByteArray(data:String):ByteArray
{
var byteArray:ByteArray;
var base64Decoder:Base64Decoder = new Base64Decoder();
base64Decoder.decode(data);
try {
byteArray = base64Decoder.toByteArray();
byteArray.position = 0;
} catch (e:Error) {
return null;
}
return byteArray;
}
private const R:uint = 60;
private const W:Number = stage.stageWidth / 2;
private const H:Number = stage.stageHeight / 2;
private var _letter:Array = [];
private var _ball:Ball;
private var _temp:TextField = new TextField();
private var _bounceTiem:Number = 0.36;
public function DC()
{
stage.scaleMode = StageScaleMode.SHOW_ALL;
stage.frameRate = 60;
var param:Object = loaderInfo.parameters;
var word:String = param["w"];
if(word == null)
word = "Dreamcast";
else {
var ba:ByteArray = new ByteArray();
ba = Base64toByteArray(word);
if(!ba) {
navigateToURL(new URLRequest("/dc/"));
} else {
word = ba.readUTFBytes(ba.length);
}
}
_temp.text = word;
var format:TextFormat = new TextFormat(null, R);
_temp.setTextFormat(format);
for(var i:int = 0; i < _temp.text.length; i++)
{
var tf:TextField = new TextField();
tf.text = _temp.text.charAt(i);
tf.selectable = false;
tf.setTextFormat(format);
if(i)
tf.x = _letter[i-1].x + _letter[i-1].textWidth;
else
tf.x = W - _temp.textWidth / 2;
tf.y = H + R/2;
_letter.push(tf);
}
_ball = new Ball();
_ball.filters = [new BlurFilter()];
_ball.x = _letter[0].x - R*2.2;
_ball.y = _letter[0].y - R*4;
addChild(_ball);
var tween:ITween = BetweenAS3.bezierTo(_ball, {x: _letter[0].x + _letter[0].textWidth, y: _letter[0].y + 35}, {x: _letter[0].x + R, y: _letter[0].y - R}, 2, Cubic.easeIn);
tween.onComplete = bounce;
tween.onCompleteParams = [1];
tween.play();
}
private function bounce(n:uint):void
{
character(n-1);
var tween:ITween = BetweenAS3.bezierTo(_ball, {x: _letter[n].x + _letter[n].textWidth, y: _ball.y}, {x: _letter[n].x + _letter[n].textWidth / 4, y: _letter[n].y - 10}, _bounceTiem);
if(_bounceTiem >= 0.22) {
_bounceTiem -= 0.02;
}
if(n < _temp.text.length - 1)
tween.onComplete = function():void
{
bounce(n+1)
};
else
tween.onComplete = ぴょーん;
tween.play();
}
private function character(index:uint):void
{
addChild(_letter[index]);
BetweenAS3.tween(_letter[index], {y: _letter[index].y, alpha: 1}, {y: _letter[index].y + 20, alpha: 0}).play();
}
private function ぴょーん():void
{
character(_temp.text.length - 1);
var tween:ITween = BetweenAS3.bezierTo(_ball, {x: W, y: _letter[0].y - R*0.8}, {x: (W + _ball.x) / 2, y: _letter[0].y - R*5}, 1.2, Quad.easeOut);
tween.play();
tween.onComplete = ぐるぐる;
}
private function ぐるぐる():void
{
var sp:Sprite = new Sprite();
sp.filters = [new BlurFilter()];
addChild(sp);
sp.graphics.lineStyle(6, _ball.color);
sp.graphics.moveTo(_ball.x, _ball.y);
addEventListener(Event.ENTER_FRAME, onEnterFrame(sp));
var tweenArray:Array = [];
for(var i:int = 0; i < 900; i++)
{
var toX:Number = _ball.x - R * i / 720 * Math.cos(i * Math.PI / 180);
var toY:Number = _ball.y - R * i / 720 * Math.sin(i * Math.PI / 180);
tweenArray.push(BetweenAS3.to(_ball, {x: toX, y: toY}, 0.002));
}
var tween:ITween = BetweenAS3.serialTweens(tweenArray);
tween.onComplete = function():void
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
sp.graphics.lineTo(_ball.x, _ball.y);
removeChild(_ball);
};
tween.play();
}
private function onEnterFrame(sp:Sprite):Function
{
return function(e:Event):void
{
sp.graphics.lineTo(_ball.x, _ball.y);
};
}
}
}
import flash.display.Sprite;
class Ball extends Sprite
{
private var _color:uint;
public function get color():uint
{
return _color;
}
public function Ball(j:Boolean = true) {
if(j)
{
graphics.beginFill(0xea5504);
_color = 0xea5504;
} else {
graphics.beginFill(0x0000FF);
_color = 0x0000FF;
}
graphics.drawCircle(0, 0, 4);
graphics.endFill();
}
}</pre>aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-80336512735146575772011-04-18T21:16:00.000+09:002011-04-18T21:16:54.373+09:00BottomCoder SRM398 DIV2下書きのままだったので公開する。<br />
<br />
昔過ぎてもう問題覚えてない。<br />
たしかこれはどっちも解けたはず。<br />
<br />
<pre class="brush:java">import java.util.Arrays;
public class MinDifference {
public double EPS = 1e-6;
public int closestElements(int A0, int X, int Y, int M, int n) {
int[] a = new int[n];
a[0] = A0;
for(int i = 1; i < n; i++) {
a[i] = (a[i - 1] * X + Y) % M;
}
Arrays.sort(a);
int res = Integer.MAX_VALUE;
for(int i = a.length - 1; i > 0; i--) {
res = Math.min(res, a[i] - a[i - 1]);
}
return res;
}
public void tr(Object... o) { System.out.println(o.length > 1 || o[0].getClass().isArray() ? Arrays.deepToString(o) : o[0]); }
}</pre><br />
<br />
激しい。<br />
こんなことしなくても解ける・・・<br />
<pre class="brush:java">import java.util.Arrays;
import java.util.LinkedList;
public class CountExpressions {
public double EPS = 1e-6;
private LinkedList<integer> list = new LinkedList<integer>();
private int res = 0;
private int ans;
public int calcExpressions(int x, int y, int val) {
ans = val;
list.add(x);
list.add(x);
list.add(y);
list.add(y);
dfs("+", 0, list.poll(), 0);
list = new LinkedList<integer>();
list.add(x);
list.add(y);
list.add(x);
list.add(y);
dfs("+", 0, list.poll(), 0);
list = new LinkedList<integer>();
list.add(x);
list.add(y);
list.add(y);
list.add(x);
dfs("+", 0, list.poll(), 0);
list = new LinkedList<integer>();
list.add(y);
list.add(y);
list.add(x);
list.add(x);
dfs("+", 0, list.poll(), 0);
list = new LinkedList<integer>();
list.add(y);
list.add(x);
list.add(x);
list.add(y);
dfs("+", 0, list.poll(), 0);
list = new LinkedList<integer>();
list.add(y);
list.add(x);
list.add(y);
list.add(x);
dfs("+", 0, list.poll(), 0);
tr(res);
return res;
}
private void dfs(String s, long val, int v, int n) {
if(s.equals("+")) {
val += (long)v;
} else if(s.equals("-")) {
val -= (long)v;
} else {
val *= (long)v;
}
if(n > 2) {
if(val == ans) {
res++;
}
list.add(0, v);
return;
}
dfs("+", val, list.poll(), n + 1);
dfs("-", val, list.poll(), n + 1);
dfs("*", val, list.poll(), n + 1);
list.add(0, v);
}
public void tr(Object... o) { System.out.println(o.length > 1 || o[0].getClass().isArray() ? Arrays.deepToString(o) : o[0]); }
}</pre>aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-87573115249372966952011-03-08T00:36:00.000+09:002011-03-08T00:36:37.068+09:00零の軌跡クリアした先日やっと『零の軌跡』をクリアしました。<br />
<br />
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=aaharu-22&o=9&p=8&l=as4&m=amazon&f=ifr&asins=B003ULN9N6" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe><br />
<br />
それなりに面白かったです。いい意味でも悪い意味でもシステム面で過去作からの大きな変化はない。<br />
個人的には、戦闘システムをちょっと変えて欲しい。<br />
<br />
プレイ時間はセーブデータを見ると、79時間39分(ハード)。RPGとしてはたぶん一般的な長さだと思う。<br />
ただ今の自分にとってはちょっと長い・・・買ったのは去年の10月だからクリアまで半年ぐらいかかってる。<br />
英雄伝説の空の軌跡シリーズは全部PSPでプレイしてますが、各作品のプレイ時間は<br />
FC 53時間22分(ノーマル)<br />
SC 90時間36分(ノーマル)<br />
3rd 58時間43分(ノーマル)<br />
となっていて過去作と比べても長めなのかも。<br />
<br />
今回は初回プレイからハードにした。<br />
戦闘は銀戦が一番苦労した。ラスボスより面倒だよね、あれ。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-63105382781071971602011-02-27T23:20:00.002+09:002011-02-27T23:22:53.596+09:00メモっすちょっと暇なのでブックマーク整理を兼ねたメモ。<br />
かぶってるのあるかも。古いのも載ってるので注意。<br />
<br />
<a href="http://jp.layer8.sh/reference/entry/show/id/908">CentOSにJava SE Development Kit (JDK)をインストールするメモ - Layer8 Reference</a><br />
<br />
<a href="http://blog.livedoor.jp/sasata299/archives/51344765.html">Cloudera を使って CentOS に Hadoop on EC2 な環境を整える 第一回 - (゚∀゚)o彡 sasata299's blog</a><br />
<br />
<a href="http://blog.liris.org/2009/05/hadooppythonno.html">Emerge Technology: [翻訳]Hadoopで動くPythonのMapReduceプログラムを書く</a><br />
<br />
<a href="http://www.atmarkit.co.jp/fwcr/rensai2/flex4_05/01.html">Flexアプリを3つのパブリック・クラウドと連携する方法(1/4)- @IT</a><br />
<br />
<a href="http://0-oo.net/sbox/python-box/appengine-oauth">Google App Engineで手軽にOAuthアプリを作成!(Twitterとか!) - AppEngine-OAuth [ゼロと無限の間に]</a><br />
<br />
<a href="http://metasearch.sourceforge.jp/wiki/index.php?Hadoop%A5%BB%A5%C3%A5%C8%A5%A2%A5%C3%A5%D7">Hadoopセットアップ - Meta Search</a><br />
<br />
<a href="http://blog.mikuriya.biz/archives/52">Javaオープンソース「Nutch」はクロール→インデクシング→検索までいける | RwJ</a><br />
<br />
<a href="http://hgotoh.jp/wiki/wiki.cgi?page=SSH%A4%C7%A5%D1%A5%B9%A5%EF%A1%BC%A5%C9%CC%B5%A4%B7%A4%CE%A5%ED%A5%B0%A5%A4%A5%F3">SSHでパスワード無しのログイン - 努力したWiki</a><br />
<br />
<a href="http://stackoverflow.com/questions/81451/upload-files-in-google-app-engine">Upload files in Google App Engine - Stack Overflow</a><br />
<br />
<a href="http://blog.mudaimemo.com/2010/03/google-app-engine-twitteroauth.html">無題メモランダム: TwitterボットをOAuthに対応させてみた - Google App Engine(Python)</a><br />
<br />
<a href="http://blog.mudaimemo.com/2010/02/google-app-engine-twitter-oauth.html">無題メモランダム: Google App Engine + Twitter + OAuthでTwitterにつぶやくためのメモ</a><br />
<br />
<a href="http://coliss.com/articles/freebies/freebies-handwriting-japanese-font.html">漢字も使える手書き風の日本語フォントのまとめ | コリス</a>aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-39102020129574409102010-12-25T19:49:00.000+09:002010-12-25T19:49:15.305+09:00BottomCoder SRM403 DIV2これからは本番はTopCoderってタイトルで、練習はBottomCoderってタイトルにします。<br />
最近TopCoderの記事が多いのでもっとほかの記事も書きたいです。<br />
<br />
250<br />
<pre class="brush:java">public class TheLargestLuckyNumber {
public int find(int n) {
outer: for(int i = n; i >= 4; i--) {
for(int j = 0; j < Integer.toString(i).length(); j++) {
if(Integer.toString(i).charAt(j) != '7' && Integer.toString(i).charAt(j) != '4') {
continue outer;
}
}
return i;
}
return 0;
}
}</pre>早く解けた。2重ループだとラベル便利。<br />
<br />
500 <br />
<pre class="brush:java">public class TheLuckyNumbers {
public int count(int a, int b) {
int count = 0;
String sa = Integer.toString(a);
String sb = Integer.toString(b);
int len = sb.length();
for(int j = 1; j <= len; j++) {
for(int mask = 0; mask < (1 << j); mask++) {
String str = "";
for(int i = 0; i < j; i++) {
if((mask & (1 << i)) > 0) {
str += "7";
} else {
str += "4";
}
}
if((str.length() > sa.length() || (str.length() == sa.length() && str.compareTo(sa) >= 0)) && (str.length() < sb.length() || str.compareTo(sb) <= 0)) {
count++;
}
}
}
return count;
}
}</pre>250のように全探索すると、2秒以内に終わらないので計算量を減らす必要がある問題。<br />
いろいろな解き方でアプローチしてて時間内に終わらなかった。<br />
自力で解くことはできたけど、これぐらいの問題を解けないと緑安定はしないし、解けるようになりたい。<br />
roseとlilyのときにも使ったビットを使った方法で解いてます。この問題は解き方いくつかありそう。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-30034614716973764632010-12-14T18:33:00.002+09:002010-12-16T16:17:10.136+09:00TopCoder練習 SRM424 DIV2250<a href="http://www.topcoder.com/stat?c=problem_statement&pm=10176">問題文</a><br />
<pre class="brush:java">public class MagicSpell {
public String fixTheSpell(String spell) {
String magic = new String();
for(int i = 0; i < spell.length(); i++) {
if(spell.charAt(i) == 'A' || spell.charAt(i) == 'Z') {
magic += spell.charAt(i);
}
}
String magicSpell = new String();
int count = 0;
for(int i = 0; i < spell.length(); i++) {
if(spell.charAt(i) == 'A' || spell.charAt(i) == 'Z') {
magicSpell += magic.charAt(magic.length()-1-count);
count++;
} else {
magicSpell += spell.charAt(i);
}
}
return magicSpell;
}
}</pre>問題文が読めれば解ける。コードは汚い。<br />
<br />
500<br />
<br />
<pre class="brush:java">import java.util.ArrayList;
public class ProductOfDigits {
public int smallestNumber(int N) {
if(N < 10) return 1;
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i = 9; i > 1; i--) {
if(N % i == 0) {
list.add(i);
}
}
if(list.size() < 1) return -1;
int index = 0;
int a = 0;
while(N > 1) {
if(N % list.get(index) == 0) {
a++;
N /= list.get(index);
} else {
if(index < list.size() -1) {
index++;
} else {
return -1;
}
}
}
return a;
}
}</pre>問題文の意味よく分からなくて1文字もかけなかった。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-35294478099308262042010-12-13T20:49:00.000+09:002010-12-13T20:49:27.009+09:00TopCoder練習 SRM 423 DIV2250<a href="http://www.topcoder.com/stat?c=problem_statement&pm=9966">問題文</a><br />
<pre class="brush:java">public class TheSimpleGame {
public int count(int n, int[] x, int[] y) {
int a = (n+1)/2;
int b = 0;
for(int i = 0; i < x.length; i++) {
b += (x[i] <= a) ? x[i] - 1 : n - x[i];
b += (y[i] <= a) ? y[i] - 1 : n - y[i];
}
return b;
}
}</pre>簡単。<br />
<br />
600<br />
<pre class="brush:java">import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class TheTower {
public int[] count(int[] x, int[] y) {
int[] a = new int[x.length];
a[0] = 0;
if(x.length == 1) {
return a;
}
ArrayList<Integer> xList = new ArrayList<Integer>();
ArrayList<Integer> yList = new ArrayList<Integer>();
for(int i = 0; i < x.length; i++) {
boolean flag1 = false;
boolean flag2 = false;
for(int j = 0; j < xList.size(); j++) {
if(x[i] == xList.get(j)) {
flag1 = true;
break;
}
}
if(!flag1) {
xList.add(x[i]);
}
for(int j = 0; j < yList.size(); j++) {
if(y[i] == yList.get(j)) {
flag2 = true;
break;
}
}
if(!flag2) {
yList.add(y[i]);
}
}
for(int i = 1; i < x.length; i++) {
ArrayList<Integer> list = new ArrayList<Integer>();
for(int j = 0; j < xList.size(); j++) {
for(int k = 0; k < yList.size(); k++) {
list.add(checkCell(xList.get(j), yList.get(k), i+1, x, y));
}
}
Collections.sort(list);
a[i] = list.get(0);
}
return a;
}
private int checkCell(int x, int y, int n, int[] arrayX, int[] arrayY) {
int[] array = new int[arrayX.length];
for(int i = 0; i < array.length; i++) {
array[i] = (int)Math.abs((double)(x - arrayX[i])) + (int)Math.abs((double)(y - arrayY[i]));
}
Arrays.sort(array);
int move = 0;
for(int i = 0; i < n; i++) {
move += array[i];
}
return move;
}
}</pre>間違えたので後で修正した解答。<br />
問題文は読めても結構難しい問題だと思う。これが600か。<br />
おそらく、移動先のx,yはそれぞれのメジアン(中央値)になる。(ただしチェッカーが偶数のときは中央2つの平均ではなく、その2つのどちらかになる<br />
そう考えると、x座標のリストと、y座標のリストの組み合わせ分だけ考慮すればいいので、その中で一番移動数が少ないものを選ぶ。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-52484062789021930532010-12-13T20:32:00.001+09:002010-12-16T16:16:05.526+09:00TopCoder SRM490 DIV22回目。落ち込む。チャレンジやってみたくてやったけど失敗した。<br />
250 ○<br />
500 未提出<br />
1000 未提出<br />
Rate 955 -> 789<br />
<br />
<a name='more'></a><br />
<br />
250<br />
<pre class="brush:java">public class LuckyCounter {
public int countLuckyMoments(String[] moments) {
int lucky = 0;
for(String s : moments) {
StringBuffer h = new StringBuffer(s.substring(0, 2));
StringBuffer m = new StringBuffer(s.substring(3));
if(h.toString().equals(m.toString())) {
lucky++;
continue;
}
if(h.toString().equals(m.reverse().toString())) {
lucky++;
continue;
}
if((h.toString().charAt(0) == h.toString().charAt(1)) && (m.toString().charAt(0) == m.toString().charAt(1))) {
lucky++;
}
}
return lucky;
}
private static void echo(Object out) {
System.out.println(out);
}
}</pre>StringBufferでreverseができるのを最近知って、使ってみたくて使ったらStringBufferはequalsが使えないの知らなくて時間が無駄にかかってしまった。<br />
今回Rateが大幅に下がった理由はこれ。<br />
というか俺Javaを知らなさすぎだろ・・・普通に解いたほうが早かったね・・・<br />
<br />
500<br />
<pre class="brush:java">public class Starport {
public double getExpectedTime(int N, int M) {
int a = gcd(N, M);
return (double)(N - a) / 2.0;
}
private int gcd(int a, int b) {
if(b == 0) return a;
return gcd(b, a % b);
}
private static void echo(Object out) {
System.out.println(out);
}
}</pre>式がわかればこんなに簡単にかけるのか・・・まだよく理解してない。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-74976862617665400442010-12-13T01:13:00.001+09:002010-12-16T16:16:37.620+09:00TopCoder SRM489 DIV2初めてのTopCoder本番ってわけだったんですが、結果は何とも言えないものにw<br />
250 チャレンジ<br />
500 未提出<br />
1000 未提出<br />
<br />
1問も解けなく、点数はもちろん0なわけですが、レートは955というそれなりに高いという結果に。いきなり緑。<br />
どうやら250の正解率が低かったみたい。<br />
<br />
<a name='more'></a><br />
修正済み250<br />
<pre class="brush:java">public class BadVocabulary {
public int count(String badPrefix, String badSuffix, String badSubstring, String[] vocabulary) {
int bad = 0;
for(String word : vocabulary) {
//pre
if(word.length() >= badPrefix.length()) {
if(word.substring(0, badPrefix.length()).equals(badPrefix)) {
bad++;
continue;
}
}
//suf
if(word.length() >= badSuffix.length()) {
if(word.substring(word.length() - badSuffix.length()).equals(badSuffix)) {
bad++;
continue;
}
}
//sub
if(word.length() >= badSubstring.length() + 2) {
boolean flag = false;
for(int i = 1; i < word.length() - badSubstring.length(); i++) {
if(word.substring(i, i + badSubstring.length()).equals(badSubstring)) {
bad++;
flag = true;
break;
}
}
if(flag) {
continue;
}
}
}
return bad;
}
}</pre>250を落とした理由はcontinueを書かなかったので、多めの結果を返していたからでした。<br />
はっきり言って問題の読み間違いですね。ほかの人が間違えてるとこと別のとこで間違えてた。アホス<br />
<br />
500<br />
<pre class="brush:java">public class BuyingFlowers {
public int buy(int[] roses, int[] lilies) {
int min = Integer.MAX_VALUE;
for(int mask = 1; mask < (1 << roses.length); mask++) {
int rose = 0;
int lily = 0;
for(int i = 0; i < roses.length; i++) {
if((mask & (1 << i)) > 0) {
rose += roses[i];
lily += lilies[i];
}
}
if(Math.abs(rose - lily) > 1) continue;
int area = rose + lily;
for(int l = 1; l * l <= area; l++) {
if(area % l == 0) {
min = Math.min(min, Math.abs(l - area / l));
}
}
}
if(min == Integer.MAX_VALUE) return -1;
else return min;
}
}</pre>問題は理解したけどどうやって解いていいかわからず。<br />
全パターン調べるのってこうやってやるんですね。これは正直知らないとできない・・・<br />
<br />
こういうテクニックってどこで教えてもらえるんですか・・・<a href="http://www.amazon.co.jp/gp/product/4839931992?ie=UTF8&tag=aaharu-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4839931992">プログラミングコンテストチャレンジブック</a><img alt="" border="0" height="1" src="http://www.assoc-amazon.jp/e/ir?t=aaharu-22&l=as2&o=9&a=4839931992" style="border: none !important; margin: 0px !important;" width="1" />買えばいいんですか?aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-87234351229937525782010-12-09T00:25:00.000+09:002010-12-09T00:25:59.232+09:00最近買ったの先日ホリパッドEX2ターボっていうXbox360のコントローラーを購入しました。(黒い方<br />
<br />
<iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=aaharu-22&o=9&p=8&l=as1&m=amazon&f=ifr&md=1X69VDGQCMF7Z30FM082&asins=B002L3SXO4" style="height: 240px; width: 120px;"></iframe><iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=aaharu-22&o=9&p=8&l=as1&m=amazon&f=ifr&md=1X69VDGQCMF7Z30FM082&asins=B002L3SXP8" style="height: 240px; width: 120px;"></iframe><br />
<br />
感想としては、悪くはないなーって感じです。<br />
もともと自分はXbox360の純正コントローラーが使いやすいって思っていた人なんで、アナログスティックとかは純正のほうが使いやすいと感じてます。しかし、純正のは方向キーがクソなので、それはこちらのほうがいいです。不満はありますが。<br />
<br />
そもそもなぜこのコントローラーを買ったかというと、「コントローラーで格闘ゲームやりたい」「PC用コントローラーに前面6ボタンのものが欲しい」っていうのが大きな理由。<br />
<a href="http://www.amazon.co.jp/gp/product/B002H9WISY?ie=UTF8&tag=aaharu-22&linkCode=as2&camp=247&creative=7399&creativeASIN=B002H9WISY">トーナメントエディション ファイトパッド for Xbox 360</a><img alt="" border="0" height="1" src="http://www.assoc-amazon.jp/e/ir?t=aaharu-22&l=as2&o=9&a=B002H9WISY" style="border: none !important; margin: 0px !important;" width="1" />とどちらを購入するか少し迷いましたが、安い方を購入しました。<br />
連射機能は特別欲しかったわけではありませんが、あったらあったで便利です。一部の実績の解除も楽になります。<br />
<br />
このコントローラーでSSFをちまちまプレイしていくです。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-34012493674548842682010-11-25T19:25:00.000+09:002010-11-25T19:25:57.728+09:00TopCoder練習 SRM420 DIV2250 <a href="http://www.topcoder.com/stat?c=problem_statement&pm=9914">問題文</a>(要ログイン)<br />
<pre class="brush:java">public class DeckRearranging {
public String rearrange(String deck, int[] above) {
String a = new String();
for(int i = 0; i < deck.length(); i++) {
a = a.substring(0, above[i]) + String.valueOf(deck.charAt(i)) + a.substring(above[i]);
}
return a;
}
}</pre>
簡単。<br />
500 <a href="http://www.topcoder.com/stat?c=problem_statement&pm=10058">問題文</a>(要ログイン)
<pre class="brush:java">import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
public class YearProgressbar {
public double percentage(String currentDate) {
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy HH:mm z", Locale.US);
Date date = sdf.parse(currentDate + " EST", new ParsePosition(0));
GregorianCalendar current = new GregorianCalendar();
current.setTime(date);
int year = current.get(GregorianCalendar.YEAR);
GregorianCalendar start = new GregorianCalendar();
String s = "January 01, " + Integer.toString(year) + " 00:00 EST";
start.setTime(sdf.parse(s, new ParsePosition(0)));
GregorianCalendar end = new GregorianCalendar();
s = "January 01, " + Integer.toString(year + 1) + " 00:00 EST";
end.setTime(sdf.parse(s, new ParsePosition(0)));
return (double)(current.getTimeInMillis() - start.getTimeInMillis()) / (double)(end.getTimeInMillis() - start.getTimeInMillis()) * 100.0;
}
}</pre>今までで一番苦労しました。せっかくJavaを使っているんだからってCalendarクラスを使おうとした結果がこれだよ!<br />
<br />
もう自分で実装したほうが早かったね・・・<br />
<br />
ローカルではTestCaseが通るのに、TopCoder側では通らないという謎。<br />
1時間以上悩んだ結果、原因は「夏時間」。<br />
調べるうちにDateFormatクラスがあるから使ってやんよ、と思ったらこれもまた苦戦。<br />
今度はローカルでSimpleDateFormatが動かない。なぜかTopCoder側で動く。<br />
これは、Localeを指定しないと、月(Mayとか)を正しくとってこられないっぽい。デフォルトのままだと「5月」みたいに日本語表示しか読み取れなかったみたい。<br />
そして、setTime(Date)した後は、setTimeZone(TimeZone)しても適用されていなくて、もうしょうがないから入力テキストにESTって記述してタイムゾーン指定してやったよ!!<br />
<br />
他の人の解凍を見るとDateクラスの非推奨のメソッド使うともっと簡単にできたっぽい。もうやだ。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-14515659135895260632010-11-20T15:45:00.000+09:002013-05-30T20:52:25.143+09:00ドリームキャスト起動画面のジェネレータ作ってみたドリキャスの起動画面をFlashで再現してみた。<br />
<br />
<a href="http://www.aaharu.com/dc/">DC startup generator</a><br />
<br />
生成されたURL(http://www.aaharu.com/dcdata/DC.swf?w=eJzzSM3JyddRCM8vyklRBAAfngRqなど)に飛べば、その文字列をいつでも再現できます。<br />
<br />
Flashのソースコードも公開してあります。<br />
Python(GAE)のコードの一部がこれ。<br />
<pre class="brush:python">class GenerateHandler(webapp.RequestHandler):
def post(self):
form = self.request.get('words')
if len(form) < 2:
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, {'alert': "2文字未満は未対応です・・・"}))
else:
form = zlib.compress(form.encode('utf_8'))
form = b64encode(form)
self.redirect("../dcdata/DC.swf?w="+form)</pre>
<br />
GETでswfに文字列を渡しているのですが、流れとしては<br />
HTMLのformで文字列をPOSTで送信→Pythonでzlib(gzip)圧縮→PythonでBase64エンコード→GETで渡す→swfでGET受信→ActionScriptでBase64をByteArrayにデコード→ByteArrayを解凍→文字列に挿入<br />
て感じです。ちょっと違う?aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-47275845116073670902010-11-20T00:29:00.000+09:002010-11-20T00:29:39.262+09:00TopCoder練習 SRM425 DIV2250<br />
<a href="http://www.topcoder.com/stat?c=problem_statement&pm=10118">問題文</a>(要ログイン)<br />
<pre class="brush:java">import java.util.Arrays;
public class InverseFactoring {
public int getTheNumber(int[] factors) {
if(factors.length == 1) return factors[0]*factors[0];
Arrays.sort(factors);
return factors[0]*factors[factors.length-1];
}
}</pre>問題読めたもん勝ち。最初のif文は別に書かなくてもいい。<br />
とても簡単。<br />
<br />
500<br />
<a href="http://www.topcoder.com/stat?c=problem_statement&pm=10095">問題文</a><br />
<pre class="brush:java">public class CrazyBot {
private boolean point[][] = new boolean[30][30];
private double _east;
private double _west;
private double _north;
private double _south;
private double result = 0.0;
public double getProbability(int n, int east, int west, int south, int north) {
for(int i = 0; i < 30; i++) {
for(int j = 0; j < 30; j++) {
point[i][j] = false;
}
}
_east = (double)east;
_west = (double)west;
_north = (double)north;
_south = (double)south;
dfs(n, 0, 0, 1.0);
return result;
}
private void dfs(int n, int x, int y, double p) {
if(point[y+15][x+15]) {
return;
}
if(n == 0) {
result += p;
return;
}
point[y+15][x+15] = true;
dfs(n-1, x+1, y, p*_east/100.0);
dfs(n-1, x-1, y, p*_west/100.0);
dfs(n-1, x, y+1, p*_north/100.0);
dfs(n-1, x, y-1, p*_south/100.0);
point[y+15][x+15] = false;
}
}</pre>
この問題は時間内に解けなくて、人の回答を参考にした。<br />
問題文読んでDFS(深さ優先探索)使えばいいんだなーって思ったけどどう実装していいかわからなかった。明らかな実力不足。勉強になりました。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-68774167210359247842010-11-17T19:34:00.001+09:002010-11-17T19:36:06.172+09:00TopCoder練習 SRM 422 DIV2250<br />
<a href="http://www.topcoder.com/stat?c=problem_statement&pm=10072">問題文</a>(要ログイン)<br />
<pre class="brush:java">public class MultiNumber {
public String check(int number) {
if(number < 10) {
return "NO";
}
String num = Integer.toString(number);
//String.valuOf(number);
for(int i = 1; i < num.length(); i++) {
String a = num.substring(0, i);
String b = num.substring(i);
int n = 1, m = 1;
for(int j = 0; j < a.length(); j++) {
n *= Integer.parseInt(a.substring(j, j+1));
}
for(int j = 0; j < b.length(); j++) {
m *= Integer.parseInt(b.substring(j, j+1));
}
if(n == m) {
return "YES";
}
}
return "NO";
}
}</pre>
Javaでint→StringとString→intの変換する方法がわからなくて手間取った。
今気づいたけど、このプログラムちょっと無駄なことしてるね。<br />
<br />
500<br />
<a href="http://www.topcoder.com/stat?c=problem_statement&pm=10033">問題文</a>
<pre class="brush:java">public class PrimeSoccer {
public double getProbability(int skillOfTeamA, int skillOfTeamB) {
double a = 0.0;
double b = 0.0;
//2
a += ((double)skillOfTeamA/100.0) * ((double)skillOfTeamA/100.0) * 153.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 16.0);
//3
a += Math.pow((double)skillOfTeamA/100.0, 3.0) * 816.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 15.0);
//5
a += Math.pow((double)skillOfTeamA/100.0, 5.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 13.0);
//7
a += Math.pow((double)skillOfTeamA/100.0, 7.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 11.0);
//11
a += Math.pow((double)skillOfTeamA/100.0, 11.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 7.0);
//13
a += Math.pow((double)skillOfTeamA/100.0, 13.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 5.0);
//17
a += Math.pow((double)skillOfTeamA/100.0, 17.0) * 18.0 * (double)(100 - skillOfTeamA)/100.0;
//2
b += ((double)skillOfTeamB/100.0) * ((double)skillOfTeamB/100.0) * 153.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 16.0);
//3
b += Math.pow((double)skillOfTeamB/100.0, 3.0) * 816.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 15.0);
//5
b += Math.pow((double)skillOfTeamB/100.0, 5.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 13.0);
//7
b += Math.pow((double)skillOfTeamB/100.0, 7.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 11.0);
//11
b += Math.pow((double)skillOfTeamB/100.0, 11.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 7.0);
//13
b += Math.pow((double)skillOfTeamB/100.0, 13.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 5.0);
//17
b += Math.pow((double)skillOfTeamB/100.0, 17.0) * 18.0 * (double)(100 - skillOfTeamB)/100.0;
double c = a*b;
return a+b-c;
}
}</pre>ただの計算。プログラムより電卓でやったほうがいいんじゃね?ってレベル。<br />
確率の計算です。組み合わせはGoogle電卓で出した。<br />
18までの素数は7つしかないので結構無理やり解いてます。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0tag:blogger.com,1999:blog-209338774431478977.post-28127227586631529952010-11-11T19:12:00.001+09:002010-11-17T19:15:59.746+09:00TopCoderやってみた。知り合いに誘われてTopCoderなるものに手を出してみました。<br />
なぜかJAVAで参戦。Python使わせてください。<br />
<br />
とりあえず、過去問で練習してます。<br />
だめだめですけど、自分の解答を載せます。<br />
<br />
TopCoder SRM 430 DIV 2<br />
Problem 500 BitwiseEquations<br />
<a href="http://www.topcoder.com/stat?c=problem_statement&pm=9921">問題文</a>(アカウントがないと見られません)<br />
<pre class="brush:java">public class BitwiseEquations {
public long kthPlusOrSolution(int x, int k) {
long a = 0, shift = 0;
while(k > 0) {
if((x & 1) == 0) {
a |= ((long)(k & 1) << shift);
k >>>= 1;
}
x >>>= 1;
shift++;
}
return a;
}
}</pre>xを2進数で表示したときに0になる桁に、kの2進数の1桁目から入れていく感じ。<br />
問題文からこのことを理解できれば解ける。結構時間かかった。<br />
<br />
TopCoder SRM 427 DIV 2<br />
Problem 250 LoveCalculator<br />
<a href="http://www.topcoder.com/stat?c=problem_statement&pm=10046">問題文</a><br />
<pre class="brush:java">import java.util.Arrays;
public class LoveCalculator {
public String findBoy(String girl, String[] boys) {
if(boys.length == 1) return boys[0];
Arrays.sort(boys);
int[] love = new int[boys.length];
for(int i = 0; i < boys.length; i++) {
int L = 0, O = 0, V = 0, E = 0;
for(int j = 0; j < girl.length(); j++) {
if(girl.charAt(j) == 'L') {
L++;
} else if(girl.charAt(j) == 'O') {
O++;
} else if(girl.charAt(j) == 'V') {
V++;
} else if(girl.charAt(j) == 'E') {
E++;
}
}
for(int j = 0; j < boys[i].length(); j++) {
if(boys[i].charAt(j) == 'L') {
L++;
} else if(boys[i].charAt(j) == 'O') {
O++;
} else if(boys[i].charAt(j) == 'V') {
V++;
} else if(boys[i].charAt(j) == 'E') {
E++;
}
}
love[i] = ((L+O)*(L+V)*(L+E)*(O+V)*(O+E)*(V+E))%100;
}
int max = love[0], maxI = 0;
for(int i = 1; i < love.length; i++) {
if(love[i] > max) {
maxI = i;
max = love[i];
}
}
return boys[maxI];
}
}</pre>そのまんま。コード汚い。aaharuhttp://www.blogger.com/profile/14446643278958061868noreply@blogger.com0