Skip to content

Instantly share code, notes, and snippets.

@yoshida-eth0
Last active January 6, 2022 13:35
Show Gist options
  • Save yoshida-eth0/c8fede2946dd15c6008a9dc9cf8159d5 to your computer and use it in GitHub Desktop.
Save yoshida-eth0/c8fede2946dd15c6008a9dc9cf8159d5 to your computer and use it in GitHub Desktop.
ビールの仕込み配合から比重を計算してアルコール度数を予想する
class Ingredient
attr_reader :original_gravity
# @param original_gravity [Float] 初期比重
# @param suger_content [Float] 糖度
def initialize(original_gravity: nil, suger_content: nil)
if original_gravity
@original_gravity = original_gravity
else
@original_gravity = suger_content * SUGER.original_gravity
end
end
WATER = new(original_gravity: 0.0)
MOLT_EXTRACT = new(original_gravity: 0.30800000459)
SUGER = new(original_gravity: 0.385)
end
class Wort
attr_reader :total
attr_reader :gravity
attr_reader :fermentation_rate
# @param fermentation_rate [Float] 発酵率
def initialize(fermentation_rate=0.75)
@total = 0.0
@gravity = 0.0
@fermentation_rate = fermentation_rate
end
# 原料追加
#
# @param weight [Float] 重量(g)
# @param ingredient [Ingredient] 原材料
def add(weight, ingredient)
@total += weight
@gravity += ingredient.original_gravity * weight
self
end
# 比率を保ったまま総容量を変更
#
# @param to_total [Float] 変更後総容量
def scale(to_total)
to_total = to_total.to_f
@gravity = gravity * to_total / total
@total = to_total
self
end
# 水を入れて総容量を合わせる
#
# @param to_total [Float] 変更後総容量
def fit(to_total)
diff = to_total - total
add(diff, Ingredient::WATER)
end
# 指定容量を減らして新たなWortオブジェクトを返す
# タンクの分割など
#
# @param subtotal [Float] 取り出す容量
def shift(subtotal)
sub = dup.scale(subtotal)
remove(subtotal)
sub
end
# 指定容量を減らす
# 澱引きや試飲など
#
# @param subtotal [Float] 取り除く容量
def remove(subtotal)
scale(total - subtotal)
end
# 初期比重
def original_gravity
gravity / total + 1
end
alias_method :og, :original_gravity
# 最終比重
def final_gravity
original_gravity - (original_gravity - 1) * fermentation_rate
end
alias_method :fg, :final_gravity
# 予想アルコール度数
def alcohol_by_volume
(original_gravity - final_gravity) / 0.738
end
alias_method :abv, :alcohol_by_volume
end
# モルトエキス1.7Lを用いて10Lのウォートを作る
# 1L澱引きする
# 70gのプライミングシュガーを120mlのお湯に溶かして追加
# 2.8Lはペールエールとして瓶詰め
# 残りはオレンジジュース200mlを足してオレンジエールとして瓶詰め
require_relative 'beer'
wort = Wort.new
.add(1_700, Ingredient::MOLT_EXTRACT)
.fit(10_000)
.remove(1_000)
.add(70, Ingredient::SUGER)
.add(120, Ingredient::WATER)
pale_ale = wort
.shift(2_800)
orange_juice = Ingredient.new(suger_content: 0.125)
orange_ale = wort
.add(200, orange_juice)
{"ペールエール": pale_ale, "オレンジエール": orange_ale}.each {|a,b|
puts <<~EOF
<#{a}>
総容量 #{b.total}ml
発酵率 #{b.fermentation_rate*100}%
初期比重 #{b.original_gravity}
最終比重 #{b.final_gravity}
予想アルコール度数 #{b.alcohol_by_volume*100}%
----------
EOF
}
__END__
% ruby example.rb
<ペールエール>
総容量 2800.0ml
発酵率 75.0%
初期比重 1.0542100116455604
最終比重 1.01355250291139
予想アルコール度数 5.509147524955324%
----------
<オレンジエール>
総容量 6590.0ml
発酵率 75.0%
初期比重 1.0540253375440258
最終比重 1.0135063343860065
予想アルコール度数 5.490379831709942%
----------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment