RubyWorld Conferenceで斬新なお菓子神社を運営してきた話

どうも。エンジニアライダーです。

先日SpeeeがRubyスポンサーとして協賛させていただいた
RubyWorld Conference 2015に行ってきました!!

今回、Speeeがイベントブースを出展させていただき
お菓子神社を運営してきましたので、2日間のレポートを写真と共にお届けしたいと思います。

お菓子神社とは

チーム開発 - 3年くらいお菓子神社運営してきた - Qiita

会社内にお菓子を置くことで人が集まり、そこでコミュニケーションが生まれるというモノです。 システムとしては賽銭箱にお金を入れ、好きなお菓子をもっていっていいという形をとっています。 特にお菓子には値段はつけず、性善説に基いて運用しています。 他社ではおやつ神社と呼称されることがありますが、社内ではお菓子神社の名前で定着しました

Rails Girls Kyoto 3rdにようこそ! ~女性の、女性による、女性のためのイベントで素敵にプログラミング!~ - さくらのナレッジ

ワークショップの合間にはお菓子を食べてちょっと休憩。かわいいお菓子に参加者もコーチも、みんなテンションが上がりました。会場の真ん中に配置された、通称「お菓子神社」には自然と人が集まり、さまざまな交流が生まれました。

お菓子神社の発端はわからなかったのですが
現在では

での取り組みが有名なのではないでしょうか。

Speeeではエンジニアが働くデスクの近くにお菓子神社を設置しているのですが
今回は出張 お菓子神社と銘打って、島根は松江にSpeeeの神主出張のもとブースを出展して参りました。

出張 お菓子神社の特別な参拝方法

普段のお菓子神社は善意を寄付し、その見返りとして
お菓子をもらうシステムなのですが、
さすがにイベントブースで善意(金銭)のやりとりをするわけにはいかないので、
今回はおみくじを導入させていただきました。

斬新なおみくじシステム

神社にはMacが設置されており

omikuji = %w( 大吉 吉 凶 ) 

というrubyのプログラムが入力されたエディタを用意しました。
エンジニアの参拝者にはこのomikuji変数を利用し、ランダムにおみくじを引くプログラムを書いていただきます。

がもらえる仕組みです。

このおみくじのポイントは
参拝者が書いたおみくじ実装をよしとするかどうかのジャッジが神主の独断だったことです。

ある程度のランダム性や驚きの実装がされていれば神主OKが出るため
「絶対に大吉を出す」と意気込んで、何度もロジックを考えなおして再挑戦する参拝者が続出しました。

お菓子神社の様子

開場直後のまだ落ち着いた神社

お昼休みが近づくにつれ徐々に人が集まる

地元、松江の学生さんたち学校でRubyを教わるそうです。うらやましい。
※このあと男子2人が無事におみくじ実装を完成させ、女子にもお菓子が行き渡りました。

matzも参拝

なんとセッションの合間にブースを見学されていたmatzさんにも
お菓子神社に参拝していただきました。

大吉を引くmatz

神主も驚きのおみくじ実装例を掲載しておきますので
ぜひご覧になってください。

お菓子神社 神主も驚きのおみくじ実装例

まずはシンプルに

Arrayの中からランダムに取り出す系実装です。

omikuji = %w( 大吉 吉 凶 )

omikuji.sample
omikuji.shuffle.first
omikuji[rand(0..2)]
omikuji[rand(100) % omikuji.size]

頑張った実装例

omikuji = %w(大吉 吉 凶)

puts omikuji[
  (0..300000).lazy.map{ |_|
    rand(omikuji.count).to_i
  }.detect{|t| t == 0}
]
require 'timeout'
omikuji = %w(大吉 吉 凶)

`stty -icanon`
c = nil
Timeout.timeout(3) do
  loop do
    c = STDIN.readchar
  end
end rescue nil
  `stty sane`
puts omikuji[c.ord%omikuji.size]
omikuji = %w(大吉 吉 凶)

m = omikuji.public_methods.detect {|m|
  rs = 10.times.map { omikuji.dup.send(m) rescue nil }
  rs.all? {|r| r.is_a?(String)} && rs.drop(1).any? {|r| rs[0] != r}
}
puts omikuji.send(m)

大吉の確率を上げる

「ランダムに引いていればOK」というレギュレーションに乗っ取り
大吉の確率を上げる実装例です。

omikuji = %w( 大吉 吉 凶 )

999.times{ omikuji.push '大吉' }
omikuji[rand(omikuji.size)]

プログラム実行直前には
「逆に大吉以外を引いたらすごい」という謎の緊張が走りました。

意地でも大吉を引きたい

omikuji = %w( 大吉 吉 凶 )

s = 0
nil until (s = omikuji.sample) == omikuji.first
puts s

この実装をしてくださったのは、外国人エンジニアの方だったのですが
神主が「おみくじ」を説明するのに苦労したそうです。

下記が当時のslackの様子です。

hirokazu.nishioka [2:38 PM] 
だれか、「おみくじ」の説明を英語でたのむw

taisuke.miyake [2:39 PM] 
fortune

hira [2:39 PM] 
@hirokazu.nishioka: Japanese lottery

hira ​[2:39 PM]
大吉 = Happy
吉 = Good
凶 = Bad

hirokazu.nishioka [2:40 PM] 
If you get 大吉, Japanese God says "You are Lucky".
とか言ってたw

hira [2:40 PM] 
Japanese godわろた

taisuke.miyake [2:40 PM] 
ばっちりですね

別言語実装

scala実装

弊社のアルゴリズムの探求者によるscala実装です。

import scala.util.Random

trait Sampling[M[_]] {
  def size[A](m: M[A]): Int
  def element[A](m: M[A], i: Int): A
  def sample[A](m: M[A]): A =
    element(m, Random.nextInt(size(m)))
}

implicit class SamplingOps[A, M[A]](val self: M[A]) {
  def sample(implicit F: Sampling[M]): A = F.sample(self)
}

implicit val ListSampling = new Sampling[List] {
  override def size[A](m: List[A]): Int = m.size
  override def element[A](m: List[A], i: Int): A = m(i)
}

val omikuji = List("大吉", "吉", "凶")
println(omikuji.sample)

perl実装

こちらはお髭の錬金術士によるperl実装。

#!/usr/bin/perl -w

use strict;
use warnings;

my @omikuji = qw/大吉
吉
凶
/;

print $omikuji[(rand(100) % @omikuji)];

まとめ

RubyWorld Conferece初参加だったので、ブースの雰囲気などわからないことだらけで
お菓子神社をいろんな方に楽しんでいただけるか非常に不安だったのですが
ブースは大盛況で2日間にわたり多くの参拝者にお菓子神社でおみくじを引いていただくことができました。

印象的だったのはパインアメが「凶」の景品だったことに異議を唱える人の多さです。
関西出身の方から多数「パインアメが凶の景品なのは納得がいかない」と猛烈な反発を受けました。
配慮不足に反省しており、次回開催の際には改善いたします。

またRubyWorld Conference自体、非常に魅力的なセッションが多く
また1日目の立食パーティーでは豪華な食事や、スペシャルゲストしまねっこの登場に
弊社の神主も大興奮でした。

弊社もスポンサーセッションで、Rubyに対する取り組みについて発表させていただきました。
そのお話はまた別の記事で。

島根最高!!!

2泊3日と短い間でしたが、松江城に観光に行けたりと非常に楽しめたイベントでした!
ありがとうございました!!