Language detail: Bash - 's unsolved challenges
'tail'を実装してください。
巨大なファイルでも効率的に動作するようにしてください。
最低限必要な機能は、
- 行数指定
- 「-f」パラメータの対応
です。
スペースやインデントなど、本来は必要なく開発効率を上げるために記述が許可されている項目について、 それらを可能な限り減らし、コードを短くするコード書いてください。 また、投稿時に対象とする言語と、実際の処理結果を記載できるとわかり易いかと思います。 以下詳細 ・全てを行う必要はありません、どこまで行うかは任意です。 ・ローカル宣言など、消しても動作に関係のない構文の削除や置き換えを行っても構いません。 ・必ず同じ入力に同じ結果が返るのであれば処理内容を変えることもかまいませんが、推奨・強制はしません。 ・コンパイラや実行環境に依存する圧縮は避けてください。
クリップボード(や同等の機能)へテキストを転送するプログラムをお願いします。 また可能でしたらクリップボードのデータを取り出すプログラムもお願いします。
システムに依存する内容ですが、応用範囲が広いと思いましたので出題させてもらいました。
ソート対象のデータ同士で一切比較などを行わずにソートし、ソート結果を出力するプログラムを作成してください。条件は以下の通り。 ・最低値・最大値・個数・並び替え対象の4つを引数として受け取る ・最大値と最低値はあくまで取りうる可能性であり、実際に出現することを保障するものではない。 ・同値が複数出現することがある。 ・入出力方法及びフォーマットは自由、関数として実装し引数に渡す形でも良い。 ・小数点以下の数値が渡されることはないが、負の数は渡される可能性がある。 ・最大値や最低値を元に算出した数値との比較は使用しても問題ありません。 ・出来るだけ多様な条件のデータをソートできるアルゴリズムを使ってください(データが多少多いときや一定の並び順だとソート失敗するものはダメ) ・昇順降順はどちらでもかまいません 以下サンプル入出力 >>入力 -1 10 10 -1 9 4 8 9 6 3 9 5 2 >>出力 -1 2 3 4 5 6 8 9 9 9
ソースコードからコメント部分を削除するプログラム decomment を書いてください. すくなくとも,decomment を記述したのと同じ言語で書かれているソースコードが 扱えるようにしてください.
YYYY年mm月dd日HH時MM分SS.xxx秒なら、「YYYYmmddHHMMSS.xxx」のようにミリ秒まで含んだ文字列を返すプログラムを書いてください。
プログラムコード中の文字の頻度は言語によって相当にばらつきがあると思います。ある言語はピリオドが頻出するとか、別の言語はカッコの頻出頻度が高い、とか。そこで、
- 文字の頻度解析をするプログラムを作成し、
- 適当なプログラムに対して実行し、結果を出力して、そのような頻度になっている理由を教えてください。
(その言語で書かれた「典型的な」プログラムコード、といえるようなものがあると良いのですが・・)
簡単すぎるという方は、複数文字にしてみたり単語の頻度にしてみてください。
参考;Wikipedia 頻度分析
http://ja.wikipedia.org/wiki/%E9%A0%BB%E5%BA%A6%E5%88%86%E6%9E%90
整数nを与えると 範囲lowからhigh内での位置を返すmodular関数を作ってください。
(
low <high かつ n=0のとき low を返す
n = 1 のとき low + 1 を返す。
n = high - lowのときhighを返す。
n = high - low + 1 のときlowを返す。
(循環 : 例* を参考にしてください)
n = high - low + 2 のときlow+1を返す。
n = 整数 * (high - low) + 1 のときlowを返す。
n = 整数 * (high - low) のときhighを返す。
n = 整数 * (high - low) + 2 のときlow+1を返す。
....循環の繰り返し
)
例
modular(n,low,high) -> 出力
modular(0,100,200) -> 100
modular(50,100,200) -> 150
modular(100,100,200) -> 200
*例
modular(101,100,200) -> 100
modular(-1,100,200) -> 200
modular(1,-5,200) -> -4
modular(-500,-5,-1) -> -5
ランダムな文字から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章で書いていた有名なものです。さらに一般化してもらってもいいです。
参考
マルバツゲームで、賢いプレイヤーの思考ルーチンを実装してください。
賢いといってもいろいろありますが、
1.負けない
2.できるだけ勝つ
という条件でいってみたいと思います。
ランダムプレイヤーと1万回バトルした結果(勝ち・負け・分け)を表示してください。
先攻になっても後攻になっても無敗!となれば言うことなしです。
マルバツゲームは3×3の格子に交互に○と×を書き込み、先に縦・横・斜めに記号をそろえたほうが勝ちというおなじみのゲームです。
「毎ターン乱数を使って手を決めるランダムプレイヤー同士を対戦させる」というのが今回のお題です。 1万回対戦させ、勝ち・負け・引き分けの数を表示してください。 そして先手が有利であることを確かめてください。
良い手を思考するプレイヤーについては別のお題にしようと思っています。 プレイヤーを簡単に差し換えることができる設計を目指してください。
標準入力から与えられたソースコードの変数名
を置換するプログラムを作ってください。
最近はリファクタリングツールなどの普及でこ
のような需要は少ないかと思われますが、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;
}
適当なポリゴンを表示させて、描画するプログラムを書いてください。 ポリゴンは回転させてください。 2D処理だけなら、標準ライブラリで大体いけますが、 3D処理は追加でライブラリを利用すると思うので、 何のライブラリを利用したのか書いてください。
(x, y) の座標情報を以下の2種類の方法で整列する機能を実現してください。
- (x, y) の辞書順(まず x で昇順に整列して、x が同じデータに対して y で昇順に整列する)
- (0, 0) からの距離の昇順
データの表現方法はタプルなり構造体/オブジェクトなり各自で適当に選んで下さい。
不動点演算子とは、関数を引数に取り、その関数の不動点を返すような関数です。 つまり、不動点演算子である関数gが関数fを引数に取るとき、 f(g(f)) = g(f) となります。
お題は不動点演算子を実装することです。(Yコンビネータを実装しても結構ですが、それ以外でも、コンビネータになっていなくてもOKとします)
see: Wikipedia
任意の偶数Nのチームの総当たり戦を最短日数(N-1日)で行う場合の日程表を1つ作成してください。 解はひとつではない場合もあります。 もし、余力があれば、全ての可能性も求めてください。 これは、スポーツスケジューリングと言う分野の問題で、数学的には、カークマンの問題と言うのが近いようです。 例えば、4チームであれば、 1-2 3-4 1-3 2-4 1-4 2-3 6チームであれば 1-2 3-4 5-6 1-3 2-5 4-6 1-4 2-6 3-5 1-5 2-4 3-6 1-6 2-3 4-5 が解のひとつです。
see: カークマンの組分け
予め言語内に用意されている場合は、(1)一般的な使用法と、(2)より進んだ使用方法を提示して下さい。
'ABCDEF'と'abcdef'等すべて対応する文字を書く必要があるものを、(1)基本版、'A-Z'と'a-z'のように"-"で範囲を指定できるものを(2)拡張版、2を更に発展させたものを(3)発展版とします。任意のものを選んで解答して下さい。
実行例. (与えられた文字列が、"typewriter"の場合)
tr 'qwertyuiop' 'QWERTYUIOP' "typewriter"
=> TYPEWRITER
1 2 3 4 5 6 7 8 | ;; 基本版/Arc
(def tr (orig subst str)
(tostring
(each c str
(pr (aif (pos c orig) (subst it) c)))))
(tr "qwertyuiop" "QWERTYUIOP" "typewriter")
;=>"TYPEWRITER"
|
セルオートマトンに関するお題です. 2次元タイプの'ライフゲーム'を実装して下さい. 初期値としては10行10列程度の格子上の平面に0.3程度の人口(?)密度を考え, 末端はループするようにして下さい. (例: 座標[-1, -1] = [10, 10]) それだけだと簡単すぎると思われる方は, 過密状態で間引きが発生するような機能を組み込んで下さい. 間引きは, 少なくともその後の1時間ステップにおける死亡率が, それをしなかった場合よりも小さくなれば結構です. (死亡率の最小化は複雑性が高すぎる感がありますし. ) サンプル: t = 0 [ ][*][ ][ ][ ][ ][*][*][*][ ] [ ][ ][ ][ ][*][ ][ ][*][*][ ] [ ][ ][ ][*][ ][ ][*][ ][*][ ] [*][ ][*][*][ ][ ][*][ ][ ][ ] [ ][*][ ][ ][ ][ ][ ][ ][*][ ] [*][ ][ ][ ][*][ ][*][*][ ][*] [ ][*][ ][ ][ ][ ][*][ ][ ][ ] [ ][ ][ ][ ][ ][ ][ ][ ][ ][*] [*][ ][ ][ ][ ][ ][*][ ][ ][*] [ ][ ][ ][ ][*][*][ ][ ][*][ ] t = 1 [ ][ ][ ][ ][*][ ][ ][ ][ ][*] [ ][ ][ ][ ][ ][*][ ][ ][ ][*] [ ][ ][*][ ][*][*][*][ ][*][*] [ ][*][ ][*][ ][ ][ ][ ][ ][*] [ ][ ][*][*][ ][*][*][ ][*][ ] [ ][*][ ][ ][ ][*][*][ ][*][*] [ ][ ][ ][ ][ ][*][*][*][*][*] [ ][ ][ ][ ][ ][ ][ ][ ][ ][*] [*][ ][ ][ ][ ][*][ ][ ][*][ ] [*][ ][ ][ ][ ][ ][ ][ ][ ][ ]
see: Wikipedia:ライフゲーム
see: Wikipedia 閏年
以下のルールを満たす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行程度になりました。
>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
範囲外
see: 和暦西暦対応表
任意の数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です。 また、最大を求めた際の実行時間と環境を書いてください。
see: コラッツの問題の成り立つ範囲
スレッドプールに複数のワーカスレッドが待機しており、メインスレッドはいつでもワーカスレッドに仕事を渡せるような状態になっているとします。
さて、メインスレッドからスレッドプールにいくつか仕事を与え、メインスレッドは与えた仕事すべてが終了するまで待機し、次の処理に行ってはいけない、というようなコードを書いてください。 #現実に書く機会が多そうなコードですね…。
ここでの仕事の内容は、適当に5秒から15秒の間スレッドをスリープする、というもので結構です。 また、ワーカスレッドのスレッドプール自体の使用を終了するか、または残して再利用するかは問いません。できればコメントにスレッドプールを残したかどうかを書いてください。
ここでいう法演算とは,与えられた数(ここでは「法」と言います)で剰余をとりながら行う計算のことです.たとえば,法が10である場合,以下のように計算します.
- 足し算
- 1 + 2 = 3
- 7 + 3 = 0 (10を10で割った余りは0)
- 11 + 12 = 1 + 2 = 3
- 引き算
- 3 - 2 = 1
- 2 - 3 = 9
- 掛け算
- 2 * 3 = 6
- 11 * 12 = 1 * 2 = 2
- 18 * 39 = 8 * 9 = 2
式と法を与えたときに,このような法演算を行い,計算結果を表示するプログラムを作成してください.
注意点
- プログラムの入力には,式と法が与えられます.
- 式に現れる数は,整数のみと仮定してかまいません.しかし,法より大きな数が与えられるかもしれませんし,負の数が与えられるかもしれません.
- 法は2以上の正整数のみが与えられます.
- 式と法は,プログラムにとって都合のよい形式で与えられると仮定してかまいません.ソースコード中に埋め込んでしまってもかまいません.
- 足し算,引き算,掛け算に対応してください.
- 法10の世界においては,1 - 2 と 1 + 8 は同じ意味です.引き算の計算においては,この性質を使い,足し算に変換してから計算してもかまいません.
プログラムの出力として,計算結果を表示して下さい.
- 与えられた式の中に,範囲外の数(負の数や,法の数以上の数)が現れた時には,必ず一度,式全体を正規化し,その結果を表示してから計算を行って下さい.
- ここでいう「正規化」とは,式の中のすべての項をいったん法で剰余をとり,0以上,法-1以下の範囲になるようにする,ということです
- 正規化をする際に,引き算を足し算へ変換する処理を一緒に行ってもかまいません.
- 計算過程で範囲外の数が現れたときには,正規化を行うことが望ましいですが,必ずしも行う必要はありません.(最終的な計算結果が正しければよしとします)
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非依存」というタグをつけてください。 わからなければつけなくても構いません。
see: HTTPでGET
お題#100「正整数のゲーデル数化?」で定義した goedel を適用すると自分自身になるような数,すなわち goedel (n) == n となるような正整数 n を見つける関数を定義してください.
このような数のことをMeertens数と言うそうです.
32bitsの符号なし整数(あるいは10進10桁整数)までの範囲で探すのにどのくらい計算時間がかかったかをCPUのスペックとともに教えてください.また,その実装で64bit符号なし整数(あるいは10進20桁整数)までの範囲で探すのにどのくらい計算時間がかかりそうか見積ってください(もちろん実際に計算して計算時間を示していただくのでもかまいません).
お題#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
一応、制約条件を示しておきます。
- あみだの横棒は縦棒をまたぐことはできません。常に隣接する縦棒同士の交換となります 。
- 同じ行に複数の横棒があっても良いですが、ひとつの縦棒の同じ点からふたつ横棒が出ることはありません。
一つのリストに対して複数の解があり得ます。ナイーブな解に飽き足らなければ出力行数をなるべく少なくする解を求める方法を考えてみてください。
たとえば、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 }は同じもの
とすることに注意してください。
あなたが使っている言語で除算と剰余が使えなくなりました。
以下の条件のもと最大公約数を求めるプログラムを書いてください。
条件
- 除算および剰余の使用禁止
- 加算や乗算から除算・剰余を単純に定義することも禁止とする
- ただし, ビットシフトが面倒な場合には引数を2で割った商を返す関数を実装しても構わない
- 多倍長演算をサポートすること(各言語のライブラリ状況を見たいので)
- 引数は2つの正整数と仮定して構わない
- F_1=1, F_2=1のフィボナッチ数列で2000番目と1999番目の最大公約数を求めたときのループ回数を教えてください
古典的なパズルである小町算を解くプログラムを作成してください。
小町算とは:
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個の解答が得られました。
次のような書式で与えられた「あみだくじ」があります。 (あみだくじはコード中に埋め込んでも、標準入力や 外部ファイルから読み込んでも、書きやすい方法でかまいません) A B C D E | | |-| | |-| | |-| | |-| |-| |-| |-| | |-| | | | このあみだくじをたどって A B C D E | | |-| | |-| | |-| | |-| |-| |-| |-| | |-| | | | B D C A E のように結果を表示させるプログラムを作ってください。
正の整数 n を引数としてとり, 2^d1 * 3^d2 * 5^d3 ... * pk^dk を返す関数 goedel を定義してください. ただし,n を10進表現で k 桁の数としたときの各桁の数が数列 [d1,d2,d3,...,dk] をなすとし,dk が 1 の位,d1 が 10^(k-1) の位です.また,pk は k番目の素数です. goedel 9 ⇒ 2^9 ⇒ 512 goedel 81 ⇒ 2^8 * 3^1 ⇒ 768 goedel 230 ⇒ 2^2 * 3^3 * 5^0 ⇒ 108
see: ゲーデル数
与えられた矩形状の文字列中に存在する文字列"ウオリ"の位置を全て出力するプログラムを 書いてください。 文字列の検索方向は八方全てで、また連続している(左右や上下の境界をまたがない)ものを 対象とします。出力は起点"ウ"の座標と方向のリストにしてください。 サンプル入力: リオウウリウ ウオリウオリ オリリオリウ リリオオウオ サンプル出力: (2, 0), 左 (0, 1), 右 (0, 1), 下 (3, 1), 右 (4, 3), 左上 -- より一般には、任意の検索文字列への対応も考えてみてください。
正整数の分割といったとき,同じ組み合わせのもの同じ分割とみなし,
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教えてください.
see: ヤング図形
- 標準でついているprintf系関数の使用禁止
- 標準でついているライブラリ以外の使用禁止
- 引数・返り値等の仕様はできるだけ似せればよい
1 2 3 4 5 6 7 | #include <string.h>
// なにもフォーマットしてない
int mysprintf(char *str, const char *format, ... ){
strcpy(str, format);
return strlen(str);
}
|
「この文は0が□個,1が□個,...,9が□個あります」 が正しくなるように□を埋めてください.数値は10進数とします. 一般のn(<=16で可)進数でも解いてみてください. たとえば2進数なら 「この文は0が11個,1が100個あります」 となります.
自然数nとm(n>=m>0)が与えられたとき,nをm個の非負の整数の和で表すやり方を全て出力してください. その際,和の組(x_1, ..., x_m)は大きい順に出力してください. ここでm = 3の時の「(a, b, c)が(A, B, C)より大きい」とは (a > A) (a == A) かつ (b > B) (a == A) かつ (b == B) かつ (c > C) のいずれかが成り立つとき(つまりは辞書的順序)とします. 例:n = 5, m = 3が与えられたときは 5, 0, 0, 4, 1, 0, 4, 0, 1, 3, 2, 0, 3, 1, 1, ... 0, 1, 4, 0, 0, 5, を出力する.
一行の文字列を指定した数の行にできるだけ文字数が均等になるように分割してください. ただし,除算や剰余算を使わないで書いてみてください. sample = "ゆめよりもはかなき世のなかをなげきわびつゝあかしくらすほどに四月十よひにもなりぬれば木のしたくらがりもてゆく" divid 4 sample => "ゆめよりもはかなき世のなかを" "なげきわびつゝあかしくらすほ" "どに四月十よひにもなりぬれ" "ば木のしたくらがりもてゆく" divid 5 sample => "ゆめよりもはかなき世の" "なかをなげきわびつゝあ" "かしくらすほどに四月十" "よひにもなりぬれば木の" "したくらがりもてゆく" divid 6 sample => "ゆめよりもはかなき" "世のなかをなげきわ" "びつゝあかしくらす" "ほどに四月十よひに" "もなりぬれば木のし" "たくらがりもてゆく"
文字列を指定のカラム幅にセンタリング配置する関数を示してください。文字列の長さが指定した幅より長い場合には文字列の両端をできるだけ均等に切り落して指定幅に収めてください。1文字は1カラムに収まるものと仮定してかまいません。
これは、実例を見た方が簡単だと思います。 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
see: Trie (en.wikipedia)
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)?)?)
|
「どう書く?」でまだ出ていないのが不思議なお題。それがBF処理系。 ここでは、BFで書かれたソースを、同じ言語に変換するコンパイラーを募集します。
私自身、すでにPerlとJavaScriptに関しては http://blog.livedoor.jp/dankogai/archives/50545151.html でやっているのですが、他の言語バージョンも是非見たいので。
Dan the Brainf.ucker
与えられた四字熟語のリストから下のように四角く配置することのできる熟語の組み合わせを探すプログラムを作成してください。
出力例:
無憂無風 礼 林 千 火 万水千山 知行合一 者 筆 不 勾 言語道断
四字熟語は左から右、上から下へ読むものとします。また右上隅の漢字と左下隅の漢字は異なるものでなければいけません。
四字熟語のデータは扱いやすい形(たとえばユニコード文字列のリスト)で与えられていると仮定して構いません。サンプルデータが必要であれば FOR Microsoft IME The四字熟語辞典(データ / 文書作成) にテキスト形式のデータが入っているのでそれを使えると思います。
問題の規模の参考までに、40行程度のPythonスクリプトでこのデータ(重複をのぞいて8312件)を処理してみたところ2.4GHzのCPUで13秒程度かかりました。結果は8133件出力されました。
A, B, Cの容器があり,それぞれ水が4L, 2L, 10L入っている. ここで次の操作を繰り返す.
(*)「A, B, Cのどれか二つの容器から水を1Lずつくみ上げ,残りの容器に移す.」
たとえばA, Bから1Lずつくみ上げて移せばA=3L, B=1L, C=12Lとなる. くみ上げる前の容器には必ず水が入っているとする.
(*)を繰り返してどれか一つの容器にのみ水がはいっている状態にする最小手数を求めよ.
可能ならA=827392L,B=65536L,C=122880Lのときも求めよ.
このお題は光成さんの投稿を元に作成しました。ご協力ありがとうございます。
与えられた文字列を前後反転する関数 reverseString2 を書いてください。
ただし、reverseString2 は単純に文字列を反転するのではなく、括弧の対応
を保存するようにしてください。
以前のお題で作成した単純に与えられた文字列を単純に前後反転したもの返す
reverseString では
reverseString("文字列(もじれつ)の反転(はんてん)")
→ ")んてんは(転反の)つれじも(列字文"
のように括弧の対応は保存されませんが、reverseString2 では
reverseString2("文字列(もじれつ)の反転(はんてん)")
→ "(んてんは)転反の(つれじも)列字文"
のように括弧の対応が保存されます。
括弧文字は、'('と')'、'{'と'}'、'['と']'で、それぞれASCII文字と仮定し
てください。
reverseString2("対応[の{とれている(さまざまな)括弧}の(例)]です。")
→ "。すで[(例)の{弧括(なまざまさ)るいてれと}の]応対"
入力文字列では対応の取れている括弧の内側には対応の取れない括弧文字はな
いと解釈してください。たとえば、
reverseString2("これ(は(対応のとれていない)括弧がある例です。")
→ "。すで例るあが弧括(いないてれとの応対)は(れこ"
次のような場合は対応のとれている括弧はないという解釈になります。
reverseString2("これ(も{対応の)とれていない}括弧の例です")
→ "。すで例の弧括}いないてれと)の応対{も(れこ"
日本語対応にする場合の文字のエンコーディングは実装側で都合のよいように
仮定してください。日本語対応であることは望ましいですが、必須ではありま
せん。
---
このお題はnobsunさんに投稿いただきました。ご協力ありがとうございます。
「 ファイル内の重複行削除(後優先) 」の続編です。
1行あたり平均60文字のデータが書き込まれた、巨大なファイルがあるとします。どのくらい巨大かというと、積んでいるメモリの10倍程度の容量があります。このファイルから、同じ内容が書かれている行を取り除くプログラムを作ってください。ただし、同じ内容が書かれている行のうち、最後に出現したものを残すものとします。
このサイズのファイルを丸ごとメモリに読み込もうとしてしまうと、 スラッシング - Wikipedia が発生することが予想されます。そこで行単位で読み込もう、というのが前回のお題の趣旨でした。
しかし、与えられたファイルが運悪く「一致する部分のないファイル」である可能性を考えてみましょう。たとえ1行ずつ読んで処理をしたとしても、「重複するかどうかの判定」のために前の行をまるごとメモリに取っておいたのでは、最終的にファイルを丸ごとメモリに乗せることになってしまいます。
こういうデータが入力されうる状況の場合にどう書くか、というお題です。前回のお題の条件3「ファイル全体を一度にメモリに読み込んで処理しないこと」を「たとえすべての行が異なるようなデータであっても、メモリの消費量をファイルサイズのおよそ10%程度に抑えること」と読み替えてください。
追記:「メモリの10倍」はさすがに条件として厳しすぎました。「ファイルのサイズは4ギガバイト未満であり、メモリの消費量をファイルサイズの半分以下に抑えること」と読み替えてください。半分以下に抑えられているのならば題意は満たすものとします。もちろん、頑張ってもっと少ないメモリで動くようにするのもアリです。
入力されたテキストデータから重複する行をとりのぞいて、その結果を標準出力へ出力するプログラムを作成してください。
重複行の排除については、以下の仕様を満たしてください。
- 読み込み順序は変更しないこと
- 重複する行があった場合、以前のデータを削除すること (後に読み込んだ方が強い)
- ファイル全体を一度にメモリに読み込んで処理しないこと
- 比較は行全体で行うこと
#4.はおまけですがある/なしで作りが変わってくると思われるので追加しました。
この問題はraynstardさんにご投稿いただきました。ご協力ありがとうございます。 ところで、素朴な実装のしかたをするとメモリ容量の数倍のサイズのすべての行が異なっているファイルを読ませたときに大変なことが起こりそうな気がしますが、そういうシビアなお題設定ではないので素朴に解いてしまって構いません。シビアなのは続編にしたいと思います。
n個の整数をソートするプログラムを生成するプログラム gensort を 書いて下さい.条件は以下のとおり
- 生成するプログラム,生成されたプログラムは同じ言語にして下さい.
- 生成したプログラムはファイルに書き込んでください.
- 生成されたプログラムでは最初に n 個の整数を読み込んで, n個の変数を初期化してください.「可能なら」変数名は,アルファベット 一文字で a,b,c ... の順で使ってください.n = 5 なら 変数は a, b, c, d, e です.
- 生成されたプログラムでは,if 文あるいは if 式で2つの変数を比較して いって,変数の順が確定したら,その順で変数の値を出力するようにして 下さい.
- 生成される側のプログラムでのアルゴリズムやデータ構造を工夫する問題では ありません :)
gensort 3 で生成した Pascal のプログラム例は以下のとおりです.
program sort(input,output);
var
a,b,c : integer;
begin
readln(a,b,c);
if a < b then
if b < c then
writeln(a,b,c)
else if a < c then
writeln(a,c,b)
else
writeln(c,a,b)
else
if a < c then
writeln(b,a,c)
else if b < c then
writeln(b,c,a)
else
writeln(c,b,a)
end.
n の値を 2 〜 10 くらいまで変化させて以下の処理時間を測定してください.
1. gensort n の処理
2. 生成したプログラムの処理
2-1. コンパイル言語の場合は,コンパイル時間と実行時間
2-2. インタプリタ言語の場合,可能ならロード時間と実行時間を別測定,
分解できないなら実行時間
ごさっしのとおり,出力されたプログラムは n の値で急激に大きくなります.
n が大きいと gensort n で文法的に正しいプログラムは生成できてもコンパ イル
や実行ができないということもありえると思います.処理系ごとの限界がわか
ると面白いのではないかと思います.オリジナルの問題は Pascal のプログラム
コードを生成するプログラムを書けという問題でしたが,生成する側とされる側
の言語を同じにするほうが面白いですよね.
この問題はnobsunさんからの投稿です。ご投稿ありがとうございました。助かります。
Pythonで34行のスクリプトを書いて得られた出力の例が下のようになります。
37 199148647.999978 58 24591257752.000000 67 147197952743.999999 163 262537412640768744.000000この問題は光成さんに教えて頂いた e^{π*sqrt{163}}≒26253741640768744 が元になっています。ご協力ありがとうございました。
使用したライブラリはタグでつけてください。またOSに依存する場合もタグ



nu #7080() Rating-1/9=-0.11
TCPのechoクライアントを書いてください。
Windowsなら、Simple TCP/IP Servicesを起動してやれば、ローカルの確認用echo サーバとして使えます。
my_program localhost 7 < input_file > result_file
のようにしてリダイレクトを行った場合にも、result_fileがinput_fileの内容と一致するようにしてみてください。
[ reply ]