Language detail: J - 's unsolved challenges

島の数をカウントする (Nested Flatten)
m×nの長方形のマス目のうちいくつかを黒く塗りつぶします。
このとき、白の島、黒の島がそれぞれいくつあるかをカウントしてください。

ただし、2つのマスは、同色マスの上下左右の移動で移れるとき、
同じ島にあると定義します。

例:
□■■□
□□■□
□■□□
□■■□
白の島は2つ
黒の島は2つ

例:
□□□□
■□■□
□■□□
□□□□
白の島は1つ
黒の島は3つ
inline/embeded bytecode assembly (Nested Flatten)

Duff's deviceをinline bytecode assemblyを使って実装してください。C言語ではよくあるinline asmのほかの言語バージョンといったところです。copyのsrcとdstは呼び出し側から渡すようにしてください。(要はbytecode側で閉じていてはならない)

Duff's deviceとは、 http://ja.wikipedia.org/wiki/Duff%27s_device に説明がありますが、ループ展開したコピーのコードです。もちろんbytecodeである時点で速度の話をするのはナンセンスです。

bytecodeで速くするとかいう話よりも、ある言語で書かれたcodeの中にその言語で使用されているbytecodeが埋め込めるかどうか、どのようにできるのかが、このお題の意図です。面白い使い道があるならsiteしていただけると幸いです。

また、1言語につき1種のbytecodeとは限りません。たとえば、PythonならCPythonのbytecode, JythonのJavaVMのbytecode, IronPythonのCIL/CLRなどがあります。 もちろん特定アーキテクチャのasmを呼んでもよいです。x86を書くことができるpyasmなんてものもあるらしいです。 http://members.verizon.net/olsongt/usersGuide.pdf

疑似並行処理 (Nested Flatten)

数値(たとえば1から10)と、アルファベット(たとえばAからJまで)を順に出力する別々のループ処理を並行に実行させ、共通の出力先に出力する極力シンプルなコードを書いてください。

念のため、実行後、出力先に数値とアルファベットが混ざって出力されている(たとえば、数値がすべて出力されてからアルファベットが続く…というふうになっていない)ことを確認してください。混ざってさえいれば、それぞれ1文字ずつ交互である必要はありませんし、もちろん交互でも構いません。

出力先や出力方法は自由です。標準出力、テキストファイル、コンテナオブジェクト(配列、リスト、コレクション)など使いやすいもので構いません。

例として Squeak Smalltalk でのコードと結果を示します。シンプルなコードなので Smalltalk に馴染みがない人も、おおよその内容は掴めると思います。

1
2
3
4
5
6
7
| out |
out := OrderedCollection new.

[(1 to: 10) do: [:each | out add: each. Processor yield]] fork.
[($A to: $J) do: [:each | out add: each. Processor yield]] forkAndWait.

^out asArray  "=> #(1 $A 2 $B 3 $C 4 $D 5 $E 6 $F 7 $G 8 $H 9 $I 10 $J) "
世界時計 (Nested Flatten)
プログラムを実行した端末のロケールと、グリニッジ標準時と、ロサンゼルスの現在時刻をそれぞれ表示してください。 時刻の表示はリアルタイムでなく、一回限りで構いません。 時刻のフォーマットは自由とします。
1
2
3
4
出力例
現在の時刻は、2008年10月29日 11時36分21秒です。
グリニッジ標準時刻は、2008年10月29日 2時36分21秒です。
アメリカ・ロサンゼルスの時刻は、2008年10月28日 19時36分21秒です。
π (Nested Flatten)

円周率を計算してください。

積分を計算するも、素朴な方法も、速さを目指すも、LLで計算する意味を問うもあるでしょう。

http://ja.wikipedia.org/wiki/%E5%86%86%E5%91%A8%E7%8E%87

LL Golf Hole 9 - トラックバックを打つ (Nested Flatten)

LL Golf Hole 9のリリースをアナウンスしているエントリにトラックバックを打ってください(トラックバックURL)。マシンガンのようには打たないでください。ただし、このエントリにはスパムフィルタが搭載されているため、寄せることはできてもカップインできないかもしれません。その場合はtakano32が用意させていただきました打ちっ放し場にてガンガン試し打ちください(トラックバックURL)。

余力のあるものは感想を公式ブログ感想エントリにトラックバックくしてください。 余力がなくても感想をトラックバックしてくれるとスタッフがよろこびます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/usr/bin/env ruby
require 'net/http'
require 'uri'
uri = URI.parse('http://ll.jus.or.jp/2008/blog/archives/38/trackback')
Net::HTTP.start(uri.host) do |http|
    ping = "title=LL+Futureに行ってきた!&" +
        "excerpt=参加者としてもLL+Futureおもしろかったよ!¥n" +
        "でも、司会ぐだぐだですみません。次から頑張ります!&" +
        "url=http://ja.doukaku.org/207/&" +
        "blog_name=LL+Golf+Hole+9"
    response, = http.post(uri.path, ping)
    puts response.body
end
起動オプションの解析 (Nested Flatten)
いわゆる、コマンドライン引数の取得(http://ja.doukaku.org/118/)からの派生です。
やっぱ、自分のコマンドってオプションつけたいですよね(笑
タグに「クックブック」なんてつけてみました
長文なのはご容赦ください^^;;
-----
次の起動インタフェースを持つコマンドを作成してください。

書式:cmdopt -o [-q] -d{0|1|2} 文字列 [文字列 ...]

書式を説明すると
- オプション「o」
  必須オプションです。指定されていない場合、異常終了してください。
- オプション「q」
  選択オプションです。
  省略されていても問題有りません。
- オプション「d」
  引数付きオプションです。
  「0」「1」「2」のいずかが続いて指定されます。
- 文字列
  パラメータです。
  1つ以上であればいくつでも指定できます。
  指定されていなかった場合、異常終了してください。

オプションの開始が「-」になっていますが
「+」や「/」でもかまいません。
余力があればロングオプションに対応してもよいです。

起動例:(すべて許容されるのが望ましいです)
1. cmdopt -o AAA
2. cmdopt -o AAA BBB CCC
3. cmdopt -oq AAA
4. cmdopt -o  -q AAA
5. cmdopt -o -s1 AAA
6. cmdopt -o -s 1 AAA
7. cmdopt -q -s2 -o AAA

出力例:
[オプション情報]
o(output): ON|OFF
q(quote): ON|OFF
d(debug): 0|1|2 

[パラメータ情報]
指定数: N
1: 文字列1
2: 文字列2
...
N: 文字列N
echoクライアント (Nested Flatten)

TCPのechoクライアントを書いてください。

  • サーバのホスト名ないしIPアドレス、およびポートはコマンドライン引数で指定します。
  • 標準入力からユーザの入力を受け取り、echoサーバに送信します。
  • echoサーバから受信したデータを標準出力に出力します。

Windowsなら、Simple TCP/IP Servicesを起動してやれば、ローカルの確認用echo サーバとして使えます。

my_program localhost 7 < input_file > result_file

のようにしてリダイレクトを行った場合にも、result_fileがinput_fileの内容と一致するようにしてみてください。

LL Golf Hole 4 - 文章から単語の索引を作る (Nested Flatten)

GNU GENERAL PUBLIC LICENSE Version 3に登場する単語について、単語が登場する行を示した索引を作成してください。

与えられる文章についてはリテラルで表記する、標準入力で与えられる、引数でファイル名が与えられるなどは自由とします。

余力のあるものはこのプログラムを短くしてみたり、短くしてみたり、短くしてください。

※LL Future実行委員の高野光弘です。この出題は LL Future公式の出題であり、優れたものについてはLL Golfのセッションでご紹介させていただくかもしれません。ご理解の上、ご投稿ください。また、LL Futureのチケットは現在も発売中です。よろしければ、メインイベントの方にもぜひご参加ください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/usr/bin/env ruby
require 'open-uri'
lines = open('http://www.gnu.org/licenses/gpl.txt').readlines
dic = {}
lines.each_with_index do |line, index|
    line.scan(/\w+/).each do |word|
        dic[word] = dic[word] ? dic[word] << index + 1 : [index + 1]
    end
end
p dic
tailの実装 (Nested Flatten)

'tail'を実装してください。

巨大なファイルでも効率的に動作するようにしてください。

最低限必要な機能は、

  • 行数指定
  • 「-f」パラメータの対応

です。

lessの実装 (Nested Flatten)

'less'を実装してください。

巨大なファイルでも効率的に動作するようにしてください。

最低限必要な機能は、

  • 上下スクロール
  • 検索

です。

LL Golf Hole 1 - tinyurl.comを使ってURLを短縮する (Nested Flatten)

tinyurl.com( http://tinyurl.com/ )のサービスを利用し、 http://ll.jus.or.jp/2008/info/xgihyo というURLを短縮しなさい。tinyurl.comのalias機能は使わないものとする。 なお、参考までに短縮したURLは http://tinyurl.com/5mngx8 となる。

余力のあるものはこのプログラムを短くしてみたり、短くしてみたり、短くしてみよ。

※LL Future実行委員の高野光弘です。この出題は LL Future公式の出題であり、優れたものについてはLL Golfのセッションでご紹介させていただくかもしれません。ご理解の上、ご投稿ください。また、LL Futureのチケットは現在も発売中です。よろしければ、メインイベントの方にもぜひご参加ください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env ruby

require 'rubygems'
require 'mechanize'

def tinyurl(url, _alias = nil)
    m = WWW::Mechanize.new
    res = m.get('http://tinyurl.com/')
    form = res.forms[1]
    form['url'] = url
    form['alias'] = _alias if _alias
    res = m.submit(form)
    regexp = Regexp.new('.*(http\:\//tinyurl.com/[a-z0-9-]+).*')
    match = regexp.match(res.body)
    return match[1] if match
end

if __FILE__ == $0 then
    puts tinyurl('http://ll.jus.or.jp/2008/info/xgihyo')
end
コード圧縮 (Nested Flatten)
スペースやインデントなど、本来は必要なく開発効率を上げるために記述が許可されている項目について、
それらを可能な限り減らし、コードを短くするコード書いてください。
また、投稿時に対象とする言語と、実際の処理結果を記載できるとわかり易いかと思います。

以下詳細
・全てを行う必要はありません、どこまで行うかは任意です。
・ローカル宣言など、消しても動作に関係のない構文の削除や置き換えを行っても構いません。
・必ず同じ入力に同じ結果が返るのであれば処理内容を変えることもかまいませんが、推奨・強制はしません。
・コンパイラや実行環境に依存する圧縮は避けてください。
設定ファイルから値を取得 (Nested Flatten)
設定ファイルから項目名をキーとして値を取得するコードを書いてください。
設定ファイルのイメージも載せてください。

ここで設定ファイルとは、
 ・項目名と値のペアが書いてあるファイル
 ・フォーマットはその言語で扱いやすいものでよい
 ・コードと分離され、コードに影響を与えずに変更が可能
を条件とします。ファイルが難しければ同等のものでもかまいません(テーブル、環境変数など)。

例)
----
ファイル:ShowPrice.ini
ITEM_NAME=りんご
ITEM_COST=200

> showPrice()
「りんご」は210円(税込み)
----
ITEM_NAME=みかん
ITEM_COST=100

> showPrice()
「みかん」は105円(税込み)
コメントの削除 (Nested Flatten)
ソースコードからコメント部分を削除するプログラム decomment を書いてください.
すくなくとも,decomment を記述したのと同じ言語で書かれているソースコードが
扱えるようにしてください.



コード中の文字の頻度分析 (Nested Flatten)

プログラムコード中の文字の頻度は言語によって相当にばらつきがあると思います。ある言語はピリオドが頻出するとか、別の言語はカッコの頻出頻度が高い、とか。そこで、

  • 文字の頻度解析をするプログラムを作成し、
  • 適当なプログラムに対して実行し、結果を出力して、そのような頻度になっている理由を教えてください。

(その言語で書かれた「典型的な」プログラムコード、といえるようなものがあると良いのですが・・)

簡単すぎるという方は、複数文字にしてみたり単語の頻度にしてみてください。

参考;Wikipedia 頻度分析

http://ja.wikipedia.org/wiki/%E9%A0%BB%E5%BA%A6%E5%88%86%E6%9E%90

出力の一時停止と再開 (Nested Flatten)

起動すると、標準出力に1秒毎に'a'の1文字を出力し続けるプログラムで、 以下の条件を満たすものを「どう書く?」

  • 'q'キーが押されるとプログラムは終了する
  • 出力中に'p'キーが押されると一時停止する
  • 一時停止中に'p'キーが押されると出力を再開する
METHINKS IT IS A WEASEL (Nested Flatten)

ランダムな文字からMETHINKS IT IS A WEASELを作るプログラムを作れ。

簡単に流れを書いてみます。

1:ランダムな20文字を持つ文字列をもった300個作ります。

2:その文字列が"METHINKSITISAWEASEL"に近いものからソートします。

3:それぞれの文字列のなか1文字を別の文字に変化させたものを3つ用意します。

4:それを2:のソートをして上位300個残す。(900個あるうちで上位300個残すということです。)

5:以後3:と4:を繰り返す。

ランダムな文字変化は大文字だけでいいです。簡単にするために空白文字を外してあります。

METHINKS IT IS WEASELができたら終了。3と4の間でソートしたもので一番上位のものを毎回表示させると変化が楽しめます。:-)

Rickard Dawkinsがブラインドウォッチメイカー(現題:盲目の時計職人)の3章で書いていた有名なものです。さらに一般化してもらってもいいです。

参考

マルバツゲーム:賢いプレイヤー (Nested Flatten)
#6190 の続編です。
マルバツゲームで、賢いプレイヤーの思考ルーチンを実装してください。

賢いといってもいろいろありますが、
1.負けない
2.できるだけ勝つ
という条件でいってみたいと思います。

ランダムプレイヤーと1万回バトルした結果(勝ち・負け・分け)を表示してください。
先攻になっても後攻になっても無敗!となれば言うことなしです。
マルバツゲーム (Nested Flatten)

マルバツゲームは3×3の格子に交互に○と×を書き込み、先に縦・横・斜めに記号をそろえたほうが勝ちというおなじみのゲームです。

「毎ターン乱数を使って手を決めるランダムプレイヤー同士を対戦させる」というのが今回のお題です。 1万回対戦させ、勝ち・負け・引き分けの数を表示してください。 そして先手が有利であることを確かめてください。

良い手を思考するプレイヤーについては別のお題にしようと思っています。 プレイヤーを簡単に差し換えることができる設計を目指してください。

α置換 (Nested Flatten)
標準入力から与えられたソースコードの変数名
を置換するプログラムを作ってください。
最近はリファクタリングツールなどの普及でこ
のような需要は少ないかと思われますが、viな
ど貧弱なエディタを使っているときに困る
のが変数名の置換です。さすがに以下の例のよ
うなプログラムは例としてしか書きませんが、
置換しようとしている変数名と同じ綴りの他の
ものがプログラム中に出てくることはまれにあ
ります。そこで、与えられたソースコードに現
れる変数だけを指定された名前に置換してくだ
さい。
置換対象となるソースコードと使用言語は同じ
ものを使ってください。与えられるソースコー
ドは、完全なコンパイル単位、もしくはパース
して意味が通る範囲のものどちらであってもか
まいません。後者の場合、一番外側の変数だけ
置換できるようにしてください。
C言語での解答例をつけたかったのですが、と
ても難しかったためまだ作成できていません。
ご容赦ください。

例
$ cat a.c
/* a */
int foo()
{
        struct a {int a;} a;
#if FOO
        a.a = 1;
#endif
        { int a; }
	return 0;
}
$ alpha -DFOO=1 b a < a.c
/* a */
int foo()
{
        struct a {int a;} b;
#if FOO
        b.a = 1;
#endif
        { int a; }
	return 0;
}
固定長データ (Nested Flatten)

固定長のデータが記載されたファイルを読み込むプログラムを作成してください。読み込んだデータは、複数の値を格納できるデータ型に格納してください。

ファイルには、すべて ascii 文字で以下のデータが格納されています。デリミタはなく、固定長で格納されています。レコードとレコードのあいだも改行はありません。

  1. 姓 (12文字) 文字数が足りない場合は、後ろを空白で埋めてあります。
  2. 名 (12文字) 文字数が足りない場合は、後ろを空白で埋めてあります。
  3. 性別 (F,M,Uの3種類、1文字)
  4. 年齢 (3桁の数字、桁数が足りない場合は、ゼロで埋めず、頭を空白で埋めてあります。
  5. 年 2008 固定
  6. 月 03 固定
  7. さらに以下のデータが日付分くりかえされます。
    1. 日付 (01 〜 31) 2文字
    2. 朝食のメニュー (500文字)
    3. 昼食のメニュー (500文字)
    4. 夕食のメニュー (500文字)

以上の形式のデータ500人分を読みこんで、データを複数の値を格納できるデータ型に格納してください。データに大して何か処理を行う必要はなく、すぐに破棄してかまいません。

この問題は、このようなファイルをどのように扱うかを知りたくて作成しました。

メソッドのフック (Nested Flatten)

例えば、あるクラスのあるメソッドを実行する前に他の処理を呼びたい(例えばログやトランザクション開始など)。 また、そのメソッドの終了後にも何らかの後処理を呼びたい(トランザクション終了など)。

そのような、メソッドに対するフック処理を書いてください。 ライブラリを使用してメソッドのフックを実現した場合は ライブラリの名前を紹介してくれると助かります。

ポリゴンを表示するプログラム (Nested Flatten)
適当なポリゴンを表示させて、描画するプログラムを書いてください。
ポリゴンは回転させてください。

2D処理だけなら、標準ライブラリで大体いけますが、
3D処理は追加でライブラリを利用すると思うので、
何のライブラリを利用したのか書いてください。
変数の初期値 (Nested Flatten)
WEB+DB 43のRecent Perl Worldを読んで知りました。

変数を初期化するに当たってPerlでは
my $var ||= 'foo';
とかきます。この不備を補うためPerlの5.10には
Defined-or演算子が実装されたそうです。
$zero //= 25;
このような変数のデフォルト設定を行う方法を各種言語ではどうかくのでしょうか。


不動点演算子 (Nested Flatten)

不動点演算子とは、関数を引数に取り、その関数の不動点を返すような関数です。 つまり、不動点演算子である関数gが関数fを引数に取るとき、 f(g(f)) = g(f) となります。

お題は不動点演算子を実装することです。(Yコンビネータを実装しても結構ですが、それ以外でも、コンビネータになっていなくてもOKとします)

指定コマンドを別プロセスで起動 (Nested Flatten)

与えられた文字列のコマンドを、別プロセスで実行してください。 異なるPIDのプロセスが立ち上がり、指定したコマンドを実行することが条件です。

あわせて、実行結果のリターンコードと、別プロセスが出力した標準出力を受け取る方法も記載してください。

今回投稿する上で、別プロセスとして実行するコマンドの与え方は自由ですが、実行した結果、何らかの損害を与えるようなコマンドは埋め込まないようにお願いします。

ライフゲーム (Nested Flatten)
セルオートマトンに関するお題です. 
2次元タイプの'ライフゲーム'を実装して下さい. 
初期値としては10行10列程度の格子上の平面に0.3程度の人口(?)密度を考え, 
末端はループするようにして下さい. (例: 座標[-1, -1] = [10, 10])

それだけだと簡単すぎると思われる方は, 
過密状態で間引きが発生するような機能を組み込んで下さい. 
間引きは, 少なくともその後の1時間ステップにおける死亡率が, 
それをしなかった場合よりも小さくなれば結構です. 
(死亡率の最小化は複雑性が高すぎる感がありますし. )
サンプル:
t = 0
[ ][*][ ][ ][ ][ ][*][*][*][ ]
[ ][ ][ ][ ][*][ ][ ][*][*][ ]
[ ][ ][ ][*][ ][ ][*][ ][*][ ]
[*][ ][*][*][ ][ ][*][ ][ ][ ]
[ ][*][ ][ ][ ][ ][ ][ ][*][ ]
[*][ ][ ][ ][*][ ][*][*][ ][*]
[ ][*][ ][ ][ ][ ][*][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*]
[*][ ][ ][ ][ ][ ][*][ ][ ][*]
[ ][ ][ ][ ][*][*][ ][ ][*][ ]
t = 1
[ ][ ][ ][ ][*][ ][ ][ ][ ][*]
[ ][ ][ ][ ][ ][*][ ][ ][ ][*]
[ ][ ][*][ ][*][*][*][ ][*][*]
[ ][*][ ][*][ ][ ][ ][ ][ ][*]
[ ][ ][*][*][ ][*][*][ ][*][ ]
[ ][*][ ][ ][ ][*][*][ ][*][*]
[ ][ ][ ][ ][ ][*][*][*][*][*]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*]
[*][ ][ ][ ][ ][*][ ][ ][*][ ]
[*][ ][ ][ ][ ][ ][ ][ ][ ][ ]
除算・余剰を使わずに閏年 (Nested Flatten)
ある西暦が閏年か否かを判定するプログラムを書いてください。 ただし、除算・余剰を求める演算子、組み込み関数、ライブラリ関数等を使用してはいけません。 また、閏年は以下のように定義されています。 1. 西暦年が4で割り切れる年は閏年 2. ただし、西暦年が100で割り切れる年は平年 3. ただし、西暦年が400で割り切れる年は閏年
必ず解ける迷路 (Nested Flatten)
以下のルールを満たすn×mの迷路を出力するプログラムを作ってください。

1. 格子状の迷路であること。
2. 経路の幅は均等であること。
3. 迷路のある地点からの全ての地点に到達する経路が1つだけ存在すること。
   ループも認めません。
4. 出力の度にランダムな迷路であること。
   ランダムシードが同じ時に同じ迷路になってしまうのはよいです。

たとえば、n=4, m=5の迷路の出力は以下のようになります。

 |1|2|3|4|
―■■■■■■■■■
1■   ■   ■
―■■■ ■■■ ■
2■   ■   ■
―■ ■■■ ■ ■
3■     ■ ■
―■ ■■■ ■ ■
4■ ■   ■ ■
―■ ■ ■■■ ■
5■ ■   ■ ■
―■■■■■■■■■

こう言うのは、×の部分が3のルールに違反するのでダメです。
 |1|2|3|4|
―■■■■■■■■■
1■   ■×■ ■
―■■■ ■■■ ■
2■   ■   ■
―■ ■■■ ■ ■
3■     ■ ■
―■ ■■■■■ ■
4■ ■×××■ ■
―■ ■×■■■ ■
5■ ■×××■ ■
―■■■■■■■■■

このようなループも2のルールに違反するのでダメです。
 |1|2|3|4|
―■■■■■■■■■
1■     ■ ■
―■■■ ■ ■ ■
2■   ■   ■
―■ ■■■ ■ ■
3■     ■ ■
―■ ■■■ ■ ■
4■ ■   ■ ■
―■ ■ ■■■ ■
5■     ■ ■
―■■■■■■■■■

できたプログラムを使って n=1024, m=1024 の迷路を作るのにかかった時間を教えてください。


難易度高めです。限られたメモリを使って縦方向に無限に広い迷路を
どうやって作るのかを考えると答えが見えてくると思います。
ソースコードはJavaで150行程度になりました。
西暦 to 和暦 (Nested Flatten)
西暦を和暦に変換するプログラムを書いてください。元号の切り替わる日など、複数の表記が可能な場合には両方表示し、西暦が無効な日付の場合には「範囲外」と表示するようにしてください。対応すべき日付は明治元年以降とします。

>a.py 1868/12/2
明治1年12月2日

>a.py 1926/12/24
大正15年12月24日

>a.py 2007/12/01
平成19年12月1日

>a.py 1926/12/25
大正15年12月25日 昭和1年12月25日

>a.py 1868/1/2
範囲外

>a.py 1868/100/2
範囲外
ポーカーの役判定 (Nested Flatten)

引数に手札を与えると、ポーカーの役を表示するプログラムを作ってください。

条件:

  • スートはS,D,H,C、ランクはA,2~9,T,J,Q,Kのそれぞれ一文字で表します。
  • 手札は S2D5H3CQS9 のように10文字で指定されます。特にソートはされていません。
  • 手札にジョーカーは含まれません。
  • ストレートで取りうるランクの種類はA2345, 23456 ... 9TJQK, TJQKAの10種類で、JQKA2のようにK-A-2をまたぐものはストレートではありません。

実行例:

% ./poker SQSJSASKST
Royal flush

% ./poker D9D7D6D5D8
Straight flush

% ./poker C2D2S2H3H2
Four of a kind

% ./poker C2D3S2H3H2
Full house

% ./poker S9S4S8STSJ
Flush

% ./poker C4H7D5S6H3
Straight

% ./poker S6H6C5DQC6
Three of a kind

% ./poker S6HQC5DQC6
Two pair

% ./poker S6H4C5DQC6
One pair

% ./poker SJSQSKSAC2
No pair
コラッツ・角谷の問題 (Nested Flatten)
任意の数nを与えたときに
・nが偶数ならば2で割る (n=n/2)
・nが奇数ならば3倍して1を足す (n = 3*n+1)
を繰り返すと、いづれは1になる。というものがあります。

数値計算の上ではかなりの数まで成り立つことが知られています。
(すべての数について成り立つかは不明)
参考リンク先参照

ある任意の数nがコラッツ・角谷の問題で1になるまでのステップ数をf(n)とします。
1~2^20までの数でf(n)を求めて、f(n)が最大になるときのnとf(n)を表示してください。

たとえばn=9だと次のような数列をたどって、19ステップで1になります。
9->28->14->7->22->11->34->17->52->26->13->40->20->10->5->16->8->4->2->1
つまりf(9)=19です。

また、最大を求めた際の実行時間と環境を書いてください。
ワーカスレッドを安全に終了させるまで待機 (Nested Flatten)

スレッドプールに複数のワーカスレッドが待機しており、メインスレッドはいつでもワーカスレッドに仕事を渡せるような状態になっているとします。

さて、メインスレッドからスレッドプールにいくつか仕事を与え、メインスレッドは与えた仕事すべてが終了するまで待機し、次の処理に行ってはいけない、というようなコードを書いてください。 #現実に書く機会が多そうなコードですね…。

ここでの仕事の内容は、適当に5秒から15秒の間スレッドをスリープする、というもので結構です。 また、ワーカスレッドのスレッドプール自体の使用を終了するか、または残して再利用するかは問いません。できればコメントにスレッドプールを残したかどうかを書いてください。

HTTPでGET その2 (Nested Flatten)
HTTPでGET その2

前回のお題
http://ja.doukaku.org/18/

HTTPで指定されたURLをGETするコードを書いてください。 
URLは「http://ja.doukaku.org/feeds/comments/」とします。 

ただし
・Proxyサーバを経由してGETしてください。
・タイムアウトを1秒に設定してください。
 (デフォルトが1秒でも、1秒に変更してください)
・タイムアウトを十分に小さくした場合、GETが失敗することを確認してください。

もしOSに依存する場合はそのOS名のタグを、 依存しない場合は「OS非依存」というタグをつけてください。
 わからなければつけなくても構いません。
Meertens数 (Nested Flatten)

お題#100「正整数のゲーデル数化?」で定義した goedel を適用すると自分自身になるような数,すなわち goedel (n) == n となるような正整数 n を見つける関数を定義してください.

このような数のことをMeertens数と言うそうです.

32bitsの符号なし整数(あるいは10進10桁整数)までの範囲で探すのにどのくらい計算時間がかかったかをCPUのスペックとともに教えてください.また,その実装で64bit符号なし整数(あるいは10進20桁整数)までの範囲で探すのにどのくらい計算時間がかかりそうか見積ってください(もちろん実際に計算して計算時間を示していただくのでもかまいません).

与えられた並べ替えを実現するあみだくじの生成 (Nested Flatten)

お題#4476を見て思いつきました。

0からn (n>=1) までの数字を任意の順で並べたリストが与えられた時、0からnまでが順に並んだ状態から出発して、与えられたリストの順で結果が得られるようなあみだくじを作成して出力するプログラムを書いてください。

与えられたリストが (3 5 2 4 0 1) の場合、出力の1例を示します:

 0 1 2 3 4 5
 | | |-| |-|
 | |-| |-| |
 |-| |-| | |
 | |-| |-| |
 | | |-| |-|
 | | | |-| |
 3 5 2 4 0 1

一応、制約条件を示しておきます。

  • あみだの横棒は縦棒をまたぐことはできません。常に隣接する縦棒同士の交換となります 。
  • 同じ行に複数の横棒があっても良いですが、ひとつの縦棒の同じ点からふたつ横棒が出ることはありません。

一つのリストに対して複数の解があり得ます。ナイーブな解に飽き足らなければ出力行数をなるべく少なくする解を求める方法を考えてみてください。

魔方分割数 (Nested Flatten)
1 .. N^2までの数をN個の数字の和が等しいN個のグループに分けたいと思います。

たとえば、N=3のときは、
(1) { 1, 5, 9 }, { 2, 6, 7 }, { 3, 4, 8 } 
(2) { 1, 6, 8 }, { 2, 4, 9 }, { 3, 5, 7 }
の2通りの方法があります。

ここで指定されたNに対して、何通りのグループ分けの方法があるかを数えるプログラムを作ってください。
(何通りかという値だけが出力されればよいのですが、予め計算してある結果を返すのはダメですよ。)
また、N=5を指定したときの実行時間もあわせて教えてください。

なお、数え上げるときの注意として、

・{ 1, 5, 9 } と { 1, 9, 5 }は同じもの

・{ 1, 5, 9 }, { 2, 6, 7 }, { 3, 4, 8 }と
 { 1, 5, 9 }, { 3, 4, 8 }, { 2, 6, 7 }は同じもの
とすることに注意してください。
最大公約数(除算禁止) (Nested Flatten)

あなたが使っている言語で除算と剰余が使えなくなりました。

以下の条件のもと最大公約数を求めるプログラムを書いてください。

条件

  • 除算および剰余の使用禁止
  • 加算や乗算から除算・剰余を単純に定義することも禁止とする
  • ただし, ビットシフトが面倒な場合には引数を2で割った商を返す関数を実装しても構わない
  • 多倍長演算をサポートすること(各言語のライブラリ状況を見たいので)
  • 引数は2つの正整数と仮定して構わない
  • F_1=1, F_2=1のフィボナッチ数列で2000番目と1999番目の最大公約数を求めたときのループ回数を教えてください
小町算 (Nested Flatten)

古典的なパズルである小町算を解くプログラムを作成してください。

小町算とは:

1□2□3□4□5□6□7□8□9=100

四角の中に、空白、+、-、×、÷のいずれかを一つ入れ、等式が成り立つようにするパズルです。

解答例:

1-2-3+4×56÷7+8×9=100

1+234×5÷6-7-89=100

参考: http://ja.wikipedia.org/wiki/%E5%B0%8F%E7%94%BA%E7%AE%97

  • evalやそれに類するものを使うか否かは自由です。
  • 割り算の際には小数点以下の切捨てが起こらないのが望ましいです。(必須ではない)
    • 切捨てが起こる場合の解答例:1÷2÷3+4+5÷6+7+89=100
  • 余裕があれば括弧を含むようにしてもいいかもしれません。

手元で20数行ほどのPythonスクリプトを書いてみたところ、101個の解答が得られました。

あみだくじ (Nested Flatten)
次のような書式で与えられた「あみだくじ」があります。
(あみだくじはコード中に埋め込んでも、標準入力や
外部ファイルから読み込んでも、書きやすい方法でかまいません)

A B C D E
| | |-| |
|-| | |-|
| |-| |-|
|-| |-| |
|-| | | |

このあみだくじをたどって
A B C D E
| | |-| |
|-| | |-|
| |-| |-|
|-| |-| |
|-| | | |
B D C A E
のように結果を表示させるプログラムを作ってください。
文字列の八方向検索 (Nested Flatten)
与えられた矩形状の文字列中に存在する文字列"ウオリ"の位置を全て出力するプログラムを
書いてください。
文字列の検索方向は八方全てで、また連続している(左右や上下の境界をまたがない)ものを
対象とします。出力は起点"ウ"の座標と方向のリストにしてください。

サンプル入力:

リオウウリウ
ウオリウオリ
オリリオリウ
リリオオウオ

サンプル出力:

(2, 0), 左
(0, 1), 右
(0, 1), 下
(3, 1), 右
(4, 3), 左上

--
より一般には、任意の検索文字列への対応も考えてみてください。
自然数の分割(別表現) (Nested Flatten)
正整数の分割といったとき,同じ組み合わせのもの同じ分割とみなし,
0 を除いて降順に並べたものを指すことも多いのではないかと思います.

たとえば,

partitions 1  ⇒ [[1]]
partitions 2  ⇒ [[2],[1,1]]
partitions 3  ⇒ [[3],[2,1],[1,1,1]]
partitions 4  ⇒ [[4],[3,1],[2,2],[2,1,1],[1,1,1,1]]
partitions 5  ⇒ [[5],[4,1],[3,2],[3,1,1],[2,2,1],[2,1,1,1],[1,1,1,1,1]]
partitions 6  ⇒ [[6],[5,1],[4,2],[3,3],[4,1,1],[3,2,1],[2,2,2],[3,1,1,1]
                 ,[2,2,1,1],[2,1,1,1,1],[1,1,1,1,1,1]]

すなわち,

- 1つの分割は非増加列
- 分割は長さが短いものが先
- 同じ長さの分割では辞書順で大きいものが先

という規則でならべたものです.一つの分割に一つのヤング図形が対応します.
たとえば、5 の分割に対応するヤング図形を列挙すると以下 7 つのようになります.

□□□□□
               
□□□□
□

□□□
□□

□□□
□
□

□□
□□
□

□□
□
□
□

□
□
□
□
□

お題:
正整数を与えられたとき上の意味での分割に対応するヤング図形をすべて
標準出力に印字する関数 young を定義してください.ヤング図形の出力は
上の例のように文字'□'を並べてください.

young 50 の出力をファイルにリダイレクトしたときの処理時間はどの程度
かかったかもCPUスペックとあわせt教えてください.
擬似lsの実装 (Nested Flatten)
スラッシュで区切られた文字列の配列(以下パスリスト)がある。
このパスリストにたいして擬似的なlsを行いたい。
lsはパスリストと表示対象ディレクトリのパスを入力する。

例としては以下のようになる。
pathList = ["aaa/bbb","aaa/ccc","aaa/ddd/eee","bbb/ddd/eee"]

ls(pathList,"aaa/")
>["bbb","ccc","ddd/"]

ls(pathList,"aaa/ddd/")
>["eee"]

なおパスリストが大きくなったとき、速度がなるべく低下しないように実装するのが望ましい。
文字列は任意の文字コードであると仮定してかまわない。
printfの自作 (Nested Flatten)
printf関数を自作してください。
printfの説明は不要だと思います。とりあえずWikiPediaのリンクをはっておきます。

実際にはsprintf関数を作ってください。
注意事項
  • 標準でついているprintf系関数の使用禁止
  • 標準でついているライブラリ以外の使用禁止
  • 引数・返り値等の仕様はできるだけ似せればよい

可変長引数など、言語によっては難しい/不可能な仕様もありますが、いろいろ工夫して本物に近づくようにしてみてください。
1
2
3
4
5
6
7
#include <string.h>

// なにもフォーマットしてない
int mysprintf(char *str, const char *format, ... ){
    strcpy(str, format);
    return strlen(str);
}
正しい文(クイズ) (Nested Flatten)
「この文は0が□個,1が□個,...,9が□個あります」
が正しくなるように□を埋めてください.数値は10進数とします.
一般のn(<=16で可)進数でも解いてみてください.

たとえば2進数なら
「この文は0が11個,1が100個あります」
となります.
文字列の均等分割 (Nested Flatten)
一行の文字列を指定した数の行にできるだけ文字数が均等になるように分割してください.
ただし,除算や剰余算を使わないで書いてみてください.

sample = "ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく"

divid 4 sample =>
 "ゆめよりもはかなき世のなかを"
 "なげきわびつゝあかしくらすほ"
 "どに四月十よひにもなりぬれ"
 "ば木のしたくらがりもてゆく"

divid 5 sample => 
 "ゆめよりもはかなき世の"
 "なかをなげきわびつゝあ"
 "かしくらすほどに四月十"
 "よひにもなりぬれば木の"
 "したくらがりもてゆく"

divid 6 sample => 
 "ゆめよりもはかなき"
 "世のなかをなげきわ"
 "びつゝあかしくらす"
 "ほどに四月十よひに"
 "もなりぬれば木のし"
 "たくらがりもてゆく"
文字列リストをTRIE Optimizeされた正規表現に (Nested Flatten)

これは、実例を見た方が簡単だと思います。 CPANにRegexp::Assembleというモジュールがあるのですが、要はこれの簡易版を作って欲しいということです。私自身、同様のことを行うモジュールを過去にいくつか作っています(e.g Regexp::Optimizer)。

ここでは、文字列のリストを受け取って、それをTRIE化した正規表現に出来ればOKです。Regexp::AssembleやRegexp::Optimizerは正規表現を受け取ってそれをTrie化することも可能ですし、Perl 5.10では内部的にTrie Optimizationを行ったりするのですが、そこまでの機能は求めません。

なお、ここで言う「正規表現」は、必ずしもPerl互換のものである必要はありません。それがTrieになっていることをきちんと示せればOKです。

とはいうものの、Perl5互換になっていた方が、サポートしている環境が多くて有用性は高そうです。可能であればそうして下さい。

Dan the Regexp Assembler

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/usr/local/bin/perl
use strict;
use warnings;
use Regexp::Assemble;

my $ra = Regexp::Assemble->new;
while(<>){
    chomp;
    next unless $_;
    $ra->add($_);
}
print $ra->re, "\n"
__END__

% grep program /usr/share/dict/words 
program
programist
programistic
programma
programmar
programmatic
programmatically
programmatist
programmer

% grep program /usr/share/dict/words | perl sample.pl 
(?-xism:program(?:m(?:a(?:ti(?:c(?:ally)?|st)|r)?|er)|ist(?:ic)?)?)