この記事は何
shellgei160を通じて言語習得 Advent Calendar 2023に参加しています。
書籍「シェル芸ワンライナー160本ノック」の例題をRubyで解いてみて、Rubyの学習に役立てようとするものです。
例題はこちらのリポジトリで公開されているものに限ります。
https://github.com/shellgei/shellgei160
実行環境など
- Docker image: ruby:3.0.2
- 上記リポジトリをクローンした上で、リポジトリのルートディレクトリ直下に
answer-ruby
ディレクトリを作り、その中に解答となるファイルを作成していきます。
今回のテーマ
$ cat kakeibo.txt | awk '{tax=($1<"20191001"||$2~"^*") ? 1.08 : 1.1; print $0,tax}' | awk '{print int($3*$4)}' | numsum
日付やその他条件から消費税を決定し、消費税をかけた後の家計簿上の合計金額を出す処理。
解
ワンライナー感は狙わず、分かりやすく書いてみる。せっかくなのでarray.reduceとかも使ってみよう。
def food?(item_name)
item_name.start_with?('*')
end
def tax_rate(date, item_name)
return 0.08 if date < '20191001'
food?(item_name) ? 0.08 : 0.1
end
def taxed_price(date, item_name, price)
price = price&.to_i
tax = (price * tax_rate(date, item_name)).floor
price + tax
end
lines = File.open('qdata/7/kakeibo.txt').readlines
total_price = lines.reduce(0) do |sum, line|
fields = line.split(' ')
raise 'invalid record' if fields.size != 3
sum + taxed_price(*fields)
end
puts total_price
所感
- reduce(0)の0は初期値
- sum + taxed_price(*record)の
*
は配列を引数へと展開しているよ。(覚え書き)