カテゴリー別アーカイブ: プログラミング

任意の長文を勝手にHello Worldのソースにする


「○○○は、Hello Worldを表示するプログラムだったんだよ!!」

「Ω ΩΩ<な、なんだってー!?」

本来プログラム言語といえばはじめに文法が決まっていて、そこに文法に従った文字列を入れると実行可能な何かができあがるというのが普通の流れです。

これを逆にしたらどうなるかと思ったのが今回の話題です。つまり、欲しい出力結果があって、適当な文字列があったとき、それをプログラム言語にするようなインタプリタを出力するプログラムを作ろう、というものです。メタプログラミングという用語をはじめて聞いたときに浮かんだ個人的イメージだったり。

もう少し動機を素直に言うと、Brainfu*kの仲間を見てふと思ったのです。Brainfu*k風のプログラム言語ってたくさんあるのですが、どれも本来の雰囲気を損なわないような入力文字列の例(だいたいHello World)を頑張って作っているじゃないですか。

名状しがたいプログラミング言語のようなもの
ジョジョ
長門有希
てってってー
プログラミング言語KQ

(ん、直書きで本来の雰囲気になっている場合も多い?)

でも、そこそこ長い文字列さえあれば、適当に文法を用意して勝手にプログラム言語にできるんじゃないかなと。

続きを読む


[#プリクラ問題]に対する貪欲解


別にプリクラに貪欲なわけではありません。

こちらの問題にまつわる話です。

下限については比較的よいものがすぐ求まるのですが、理論解となると私の知識では太刀打ち出来なさそうだと思いました。

困ったときにはコンピュータ。理論解ではありませんが、それらしい方針を与えて近似解を求めてもらおうという魂胆です。

ソースコードは一番下へどうぞ。正直な話、今回はソースをはりつけるために作られた記事です。

続きを読む


[作ってみた]物理ぷよぷよ


私のいる学科の演習のひとつに、「シミュレーション&ビジュアライゼーション演習」というものがあります。
シミュレーション&ビジュアライゼーション演習

簡易的ですが実際に動作を見れるシミュレータを題材に各人があれこれいじることで、いわゆる物理シミュレーションに関して比較的楽しく学ぼうという趣旨の授業です。

DA099_L

本来は演習用のソフトですが、せっかくソースコードも公開されているので、気晴らしにひとつ作ってみました。テーマは「物理演算+ぷよぷよ」です。ソースと実行ファイルは一番下に。

今回はぷよぷよといっても対戦要素は無しです。元のルールに物理演算(?)を組み込むことによる大惨事を見届けようというのが今回の趣旨になります。

続きを読む


「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム


どうしてこんなものを作ってしまったんだろう。

進捗どうどう進捗ですか

進捗どうどう進捗ですか

というわけで、今回のネタは無限の猿定理です。直接の元ネタはTwitterですが、下ネタ全開なのでリンクを開く際はご注意ください。

概要

タイトルにもあるように「進捗・どう・です・か」をランダムな順序で表示し、「進捗どうですか」が完成したところで適当にクエスチョンマークをつけて去っていくプログラムです。

特に意味もなく文字カウントします。おおよそ数十文字から1000文字程度で目的を成し遂げて去っていきます。

生成された煽り文句たち

煽り文句も煽り以外も結構バリエーションがあるものです。

「進捗どう進捗どう進捗どう」

焦っているんですかね。

「進捗ですです進捗どうです」

激しい進捗があった人のセリフでしょう。

「どう進捗ですか」

進捗を伝えてからの冷酷な迎え撃ち。

「進捗かどうかどうですか」

自信がなくなってきた。

「どうかどうか進捗進捗進捗」

締め切り間近。もうやばそう。

続きを読む


逆FizzBuzz問題をオブジェクト指向(C++)で解く


Blogの生存報告がてら。

ちょっと旬の過ぎた話題ですが、逆FizzBuzz問題をC++で、自分なりにがんばってオブジェクト指向っぽく解いてみます。

逆FizzBuzz問題

FizzBuzzゲームは英語圏での定番飲み会用ゲームで、日本で言うナベアツゲームみたいなものです。

ルールは各人が1から順に数を言っていき、3の倍数のときには数字の代わりにFizz、5の倍数のときにはBuzz、3かつ5の倍数のときにはFizzBuzzを言うというものです。

具体的にはこうなります: 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, …

プログラミング界隈では初歩的なコーディング問題として、相手が本当にプログラミングができるのかどうかを知る問題として使われるそうです。(現場で本当に使われているのかは知りません。)

さて、逆FizzBuzz問題というのは、これに関連した問題の逆問題として定義されます。

まず、1からでなく適当な数字から始め、さらに数字を言わないFizzBuzz問題を考えます。

例えば25から始めるとすると、25はBuzz、26は飛ばす、27はFizz、28は飛ばす、29は飛ばす、30はFizzBuzz、… となり、この結果はBuzz, Fizz, FizzBuzz, … となります。

これの逆問題を考えます。つまり、FizzやBuzzやFizzBuzzの羅列でできた文字列が与えられたとき、結果がそれに一致するような数列を求めたい、それを逆FizzBuzz問題と定義します。

それだけだと答えが複数あるので、今回はその中で最小の数列の最も小さい数から始まるものを答えとしましょう。

具体的な問題例とその答えは以下のようになります。

  • “Fizz”なら3
  • “Fizz, Buzz”なら9,10 (3,4,5より短い)
  • “FizzBuzz”なら15
  • “FizzBuzz, Fizz”なら15, 16, 17, 18

より詳しくは元ネタを和訳されている以下のリンクを参照してください:
逆FizzBuzz問題 (Inverse FizzBuzz) – 猫とC#について書くmatarilloの雑記

オブジェクト指向で逆FizzBuzz問題

ここからプログラミングの話題。

先に挙げたリンク先(とさらにその先の英語原文)では、オブジェクト指向プログラミングがプログラマーに滅びをもたらす思想であると認定され、代わりに関数型プログラミングが広く認められた近未来で逆FizzBuzz問題を解くお話になっています。

まあ、オブジェクト指向が悪であるかどうかは議論を避けるとして、ここでは2016年になってもやっぱりオブジェクト指向は世の中を支配していた、そしてその世界で逆FizzBuzz問題もオブジェクト指向のノリで解く必要に迫られたらどうなるのかをやってみた、という内容になります。(そもそも私は関数型プログラミングをきちんと勉強していない人なので、善悪の議論ができません。)
言語は例によってC++11です。だいたい次のように決めておきます。

  • 出力は逆FizzBuzz問題の解の数列の範囲。例:”Fizz Buzz” → “[3,5]”
  • 入力が空文字のときは[0,0]を返す。
  • 解がないときは適当に文句を返す。

先にソースコードを書いてしまいましょう。
続きを読む


Togetter「#俺が見たクソコード選手権 まとめ」の補足


Togetterで先日まとめた「#俺が見たクソコード選手権 まとめ」についての話です。

Taken by nebulux76, Flickr

Taken by nebulux76, Flickr

そこそこ反響があったのですが、「書いてある中身がよくわからない」という反応もいくらかあったので、一部抜粋してちょっとだけ補足してみたいと思います。

なるべく書いた側の身になって考えてみたいと思います。

何かコメントで見当はずれなところがありましたらご指摘よろしくお願いします。私もいわゆるクソコードを書いてしまうことがよくあるので。


掃除機で同じ所を何度もかけるようなノリですね。過去に何があったんでしょうか。

一応、マルチスレッドの処理などを適当に書いてしまうと、代入した変数の値が適当なタイミングで勝手に書き変わってしまうことがあります。

もっとも、その場合でも変数にvolatile宣言をしておかないと最適化で取り除かれてしまいますが。


絶対に実行されないコード。適当な変数が定数になったとき、機械的に置換していくとこういう記述が出てくるおそれがあります。

普通のコンパイラならWarning出してくれるような?

続きを読む


「クイックソートをHaskellで書くと5行、C++で書くと35行!」←いやそんなにかからないだろ


(この記事はC++メインの内容です。)

関数型言語のセンスも身につけておかないと、と思ってHaskellの簡単なお勉強をしようと思いました。

圏論のような背景や文法から把握するのもひとつのルートですが、まずは適当な例を見てみようと思ったわけです。
「関数型言語だとこんなことができる!」みたいな驚きがあったほうが楽しいですしね。

Taken by Robert Scarth, Flickr

Taken by Robert Scarth, Flickr

まずはHaskellでのクイックソートの実装例を探してみました。クイックソートというのはアルゴリズムの勉強を1からすると必ずと言っていいほど登場するほどのものですし、比較もできて面白そうです。

さて、「Haskell クイックソート」でGoogle検索にかけてみると、「C++だと35行のところがHaskellは5行で書ける」だの、「最も美しいコードのひとつ」だのとなかなか景気の良い記事が出てきます。

ところがもう少し読んでみると、「Haskellの5行クイックソートはクイックソートではない」みたいな議論がされているページがいくつか出てきます。

Togetterにいろいろな主張のまとめがありました。曰く、

「In-placeソートでないからだめ」「というか遅い」「いやHaskellに効率を求めてはいけない」「5行の例はPivotingをしていないのでだめ」「Pivotingはクイックソートの本質ではない」「メモリを抽象化していて扱えていないのでとても遅い」「Haskellでメモリの議論をするべきでないしIn-placeソートでなくてもよい」「Haskellでクイックソートをしっかり書きたいなら手続き型風に書くのが良い」

といった感じで、さっそく頭が痛くなってきました。

まあ今回はHaskellについては一旦置いておいて、その途中で出てきた「C++のクイックソートは35行」の部分についての話です。C++で普通に書いてももっと短くなっていいはずです。

結果から書きますと、普通に書いても9行くらいになりました。

続きを読む


マンデルブロー集合へ飛び込む


先日のマンデルブロー集合の10の200乗倍で作成したプログラムがあるので、今回はマンデルブロー集合の様々な地点へ飛び込んだ動画を作ってみました。

前回の記事を見ていない方はそちらからどうぞ:

[フラクタル] マンデルブロー集合 10の200乗倍への挑戦

今回訪れる地点は計5箇所です。どの点も拡大していく最中に集合全体と同じ形が現れます。フラクタルらしくて面白いと思います。

具体的には以下の点です。緑は前回の場所。それぞれ個性的な場所だと思います。

Mandelbrot Set with Circles (Picture from Wikimedia)

Mandelbrot Set with Circles (from Wikimedia)

この集合はフラクタルなので自己相似の図形ではあるのですが、ただ単純にどこでも同じ形を持っているわけではありません。拡大する場所を変えると景色が一変してしまいます。

肝心の動画はこちら。ニコニコ動画はこちら

続きを読む


C++11の新しい乱数の使い方おぼえがき


忘れた頃にふと必要になるので自分用にメモしておきます。

Taken by Matteo.Mazzoni, Flickr

Taken by Matteo.Mazzoni, Flickr

C++11には新しい乱数ライブラリが標準で用意されました。

もちろん従来の乱数rand()も使えますが、内部の実装が決まっていないのと、またその実装について様々な問題点が指摘されていることもあり、C++11ではより新しく使いやすい乱数が定義されたのでした。

これが int rand2(); みたいに定義されていれば使う側としては簡単なのですが、残念ながら使うにはもう少し長い構文が必要になります。

(何も考えず乱数を使いたい人にはかなりマニアックな話題だと思います。C++11の実装の話と乱数の話を行ったり来たりします。)

結論だけ書くと、以下のように乱数myrandを作ることができます。

#include <random>
#include <functional>
#include <ctime>

auto myrand = std::bind(std::uniform_int_distribution<int>(0, 99), std::mt19937(static_cast<unsigned int>(time(nullptr)));

例によってコンパイル時に-std=c++11 オプションをつけて下さい。

続きを読む


現れては議論になるあの確率の問題を愚直にやってみた


今回の話題はこれです。

ジョーカーを除いたトランプ52枚の中から1枚のカードを抜き出し、
表を見ないで箱の中にしまった。
そして、残りのカードをよく切ってから3枚抜き出したところ、
3枚ともダイヤであった。
このとき、箱の中のカードがダイヤである確率はいくらか。
答えが1/4ってのは納得出来ない!
10/49だろ!!

定期的にあちこちで話題になる確率の問題です。

調べると2chまとめサイトなどでも話題にされていますし、考察しているブログなども多数見つかります。
Yahoo!知恵袋では早稲田大学の過去問だという方がいました。

論調もいろいろで、1/4だよ派と10/49だよ派だけに限らず、本文の解釈の仕方で違うだの、この問題は単純な確率の問題ではないだのと様々な意見が出されています。

実際には数学的にきちんと議論できて正解も出せるのですが、それでは納得できない人は大勢います。数式で考えるというのは抽象化のレベルが相当高いので、計算上はともかく問題文を本当に反映できているのか?という疑問が起きるのは不思議なことではありません。

あれこれ議論する前に、実際にやってみればいいんですね。

今回はその結果の話と、結果の「正しさ」の扱いについて少し書いておきます。

続きを読む