yuuki blog

プログラミング をアプトプットしています。

Ruby 回文数の計算

解答が回文数になる問題です。

  • 入力した数字の桁を逆から並べ、反転させる。
  • 元の数字と、反転させてできた数字を足し算する。
  • 足し算してできた数字を用いて 1 番目の操作から繰り返す。
  • 12321のように回文数になれば出力する

入力123

  • 123を反転 => 321
  • 123+321 = 444 => 回文数なので出力 (回文数で無い時は繰り返す)
n = gets.chomp
loop {
  r = n.chars.each_slice(1).map(&:join).reverse.join.to_i
  n = n.to_i
  if n == r
    puts r
    break
  else 
    n += r
  end
  n = n.to_s
}

入力を数値ではなく文字列で入力します。 n.chars.each_slice(1).map(&:join).でにと文字ずつの配列にしています。 reverseで配列を逆転させ、joinで文字列に変換し、to_iで数値に変換しています。 loopで反転させても一緒なら出力し、違うならばnとrをたし繰り返しています。

Ruby スペルチェック

英単語を参照するプログラムです。

条件
  • n回調べる
  • 正解と回答を配列で入力する
  • 全一致と1文字間違いのみ出力する
  • 文字の長さ間違い、2文字以上の間違いは出力しない
puts "何回調べますか?"
n = gets.to_i
puts "正解 回答の順で入力してください"
str = n.times.map{gets.chomp.split.map(&:to_s)}
for spell in str do
  i = 0
  u = 0
  if spell[0] == spell[1]
    puts "#{spell[1]}は合っています"
  elsif spell[0].length == spell[1].length
    s = spell[0].chars.each_slice(1).map(&:join)
    t = spell[1].chars.each_slice(1).map(&:join)
    spell[0].length.times do
      unless s[i] == t[i]
        u += 1
      end 
      i += 1
    end
    if u == 1
      puts "#{spell[1]}は一文字間違いです"
    end
  end
end
  • 完全一致ではなければ文字の長さを比べ、合っていれば一文字ずつの配列にする。
  • 1文字ずつ参照し、合っていなければu に1を足します。
  • uが1ならば出力します

Ruby 二つの文字列の順番を揃える

二つの文字列を照合します。片方の文字列を左に一文字づつずらし、二つの文字が何文字で照合するかを出力します。

(例)"tenaha" という文字列を"hatena"にします。 左に2文字ずらすと"hatena"になりますので2を出力します。
入力例

6 hatena tenaha

出力例

2

i = 0
#文字数,照合先の文字列,照合元の文字列を入力します
n,a,b = gets.chomp.split.map(&:to_s)
#文字列を数列に変換します
int = n.to_i
#照合元の文字列を一文字づつの配列に変換します。
bb = b.chars.each_slice(1).map(&:join)
#ループ処理を行い、rotate()で配列を一つづつ左にずらし、.joinで文字列に変換しています。
int.times do
  bbb = bb.rotate(i).join
  if bbb == a
    puts i
    break
  else
    i += 1
  end
end

Ruby 二次元配列の最大値と最小値を求める

下記のようなテーブルがあります。

a b c d ...
1日目 12 25 46 10 20
2日目 27 93 17 39 26
3日目 63 72 53 7 92
4日目 32 54 37 98 6

各カラムの最大値と最小値を求めます。

  • テーブルは配列で入力します。(例)12 25 46 10 20
num = []
max_array = []
low_array = []
max = 0
i = 0
t = 0
puts "何回調べますか?"
n = gets.to_i
puts "何日間調べますか?"
m = gets.to_i
puts "一日ごとに入力してください"
int = n.times.map{gets.chomp.split.map(&:to_i)}
(m - 1).times do
  n.times do
    num << int[i][t]
    max = num.sort
    i += 1
  end
  max_array << max[n-1]
  low_array << max[0]
  num = []
  i = 0
  t += 1
end
puts "何回目を調べますか?"
d = gets.to_i
puts "最小値は#{low_array[d -1]}です"
puts "最大値は#{max_array[d - 1]}です"
  • timesメソッドをネストすることによって、intの二次元配列を1次元配列に変換し、ソートをしてから配列の最大値と最小値を取り出し、最大値の配列と最小値の配列に入れています。
    最後に指定のカラムを出力します。  

Ruby 食事カロリーを計算

複数人の食事のカロリーを計算するプログラムです。

条件

  • 複数人数えることができます。
  • 各料理は100gあたりのカロリーを入力します。
  • 一人づつ各料理の食べた量(g)を順番に入力します。
    • (例)一番目が300g,2番目が400g,3番目が200g =>"300 400 200"
col_sum = 0
food = []
i = 1
puts "何食数えますか?"
n = gets.to_i
puts "何人数えますか?"
m = gets.to_i
n.times do
  puts "#{i}番目のカロリーは?"
#料理のカロリーを順番に配列に格納します
  food << gets.to_i
  i += 1
end
m.times do
  puts "食事量順番に入力してください。"
  col = gets.chomp.split.map(&:to_i)
  l = 0
  n.times do
#1品あたりのカロリーを計算します。
  calorie = food[l] * col[l] / 100
#一人当たりのカロリーを計算します。
  col_sum += calorie
  l += 1
  end
  puts "カロリーは#{col_sum}Calです"
# "col_sum"を0にしないと次の値も足されます。
  col_sum = 0
  m += 1
end

Ruby ポーカーゲーム

ポーカーのルール

  • n回手札を交換できます。
  • ジョーカーを含めない52枚から構成されます。
  • 同じ札は入りません。
  • 以下の順番に役が出力されます。
#カードを交換するために定義します
m = 0
# 乱数で絵柄を指定するために配列に入れます。
mark = ["heart","diamond","spade","club"]
#カードを交換する回数を指定します。
puts "何回交換しますか?"
n = gets.to_i
#手札それぞれをa,b,c,d,eに指定し乱数で、数値を絵柄を取得しています。
a = [rand(1..13),mark[rand(4)]]
b = [rand(1..13),mark[rand(4)]]
c = [rand(1..13),mark[rand(4)]]
d = [rand(1..13),mark[rand(4)]]
e = [rand(1..13),mark[rand(4)]]
#2次元配列に変換し"sort"で、数字の小さい順に並べ直し、"uniq"で重複している配列を削除します。
cards = [a,b,c,d,e].sort.uniq
#最初の回数も入りますので、交換する回数(n)+1で繰り返しています。
(n + 1).times do
#もし重複している配列があれば"cards[4]"(5番目のカード)はnil(無い)になっていますので、while文で配列を追記します。
while cards[4] == nil do
 cards << [rand(1..13),mark[rand(4)]]
end
#2次元配列を"flatten!"で1次元配列に変換しています。
sum = cards.flatten!
  puts "手札"
  puts "#{a},#{b},#{c},#{d},#{e}"
#手札の絵柄が各何枚あるのか数え変数に代入しています。
  hea = sum.count("heart")
  dia = sum.count("diamond")
  spa = sum.count("spade")
  clu = sum.count("club")
#"delete_if"で絵柄を削除しています
  sum.delete_if do |str|
    mark.include?(str)
  end
#同じ値がいくつあるのかカウントしています。
  array = sum.group_by(&:itself).map{ |k, v| [k, v.count] }.to_h
#各絵柄が揃っているかを調べています。
  if hea == 5 || dia == 5 || spa == 5 || clu ==5
#数値が、[1,10,11,12,13]と並んでいるかを調べています。
    if cards[0][0] == 1 && cards[1][0] == 10 && cards[1][0]+3 == cards[4][0]
      puts "loyal_straight_flash"
#数値が最初値+4=最後の値になっているかを調べています。
    elsif cards[0][0]+4 == cards[4][0]
      puts "straight_flash"
    end
  end
#"value?()"で()の中の値が"array"にあるかを調べています。
  if array.value?(4)
    puts "four Card"
  elsif array.value?(3) && array.value?(2)
    puts "full house"
  elsif hea == 5 || dia == 5 || spa == 5 || clu ==5
    puts "flash"
  elsif cards[0][0]+4 == cards[4][0]
    puts "straight"
  elsif array.value?(3)
    puts "three card"
#ツーペアをいうことはarrayの中は[1,2,2]や[2,1,2]などになっています。
#なので配列の1番目か2番目には必ず2が入っており、4番目はnilになっています。
  elsif array.values[0] == 2 || array.values[1] == 2 && array.values[3] == nil
    puts "two pair"
  elsif array.value?(2)
    puts "one pair"
  else
    puts "no pair"
  end
#nの方がmよりも1回多く回すためにここに置いています
  m += 1
  if n >= m
  puts "交換しますか? yes=1 no=0"
  change = gets.to_i
    if change == 1
      puts "どれを交換しますか?"
      puts "a b c d e"
#"a b c"など複数選択できるように配列で定義します
      trade = gets.chomp.split.map(&:to_s)
      if trade.include?("a")
          a = [rand(1..13),mark[rand(4)]]
      end
      if trade.include?("b")
        b = [rand(1..13),mark[rand(4)]]
      end
      if trade.include?("c")
        c = [rand(1..13),mark[rand(4)]]
      end
      if trade.include?("d")
        d = [rand(1..13),mark[rand(4)]]
      end
      if trade.include?("e")
        e = [rand(1..13),mark[rand(4)]]
      end
    else
#交換しなければ終了します。
      break
    end
  end
end

2次元配列のみで出来そうでしたけど、ペアの定義がややこしくなりそうだったので、1次元配列に直してから定義しました。

Ruby 損益分岐点売上高と利益率を求める(P/L)

損益分岐点売上高とは

  • 利益が出る売上金額です。
    (売上高=変動費+固定費になる分岐点)

    売上高とは

  • 事業で得られたお金の全て

    売上高の構成

  • 売上 = 費用+利益
    (費用 = 変動費+固定費 )
    固定費とは(営業の忙しさ、売上にかかわらず毎月かかる金額)
  • 家賃・社員の人件費・光熱費の固定費など
    変動費とは(営業の忙しさ、売上に応じて毎月かかる金額)
  • 原価・アルバイトなどの人件費・使用分の光熱費など

    当期純利益とは

  • 売上高から原価・販管費・営業外費用・特別損失・法人税を引いたものです。
  • またかく順番に引いたものを以下のように言います。
    売上総利益(粗利益)(原価)
    営業利益(販管費)
    経常利益(営業外費用)
    税引前当期利益(特別損失)
    当期純利益(法人税)
puts "売上高"
sal = gets.to_f
puts "固定費"
fix  = gets.to_f
puts "変動費"
var = gets.to_f
puts "当期純利益"
inc = gets.to_f
#変動比率
var_rat = var / sal #変動比率=変動費/売上高
ber_eve = fix / (1 - var_rat) #損益分岐点売上高=固定費/(1-変動比率)
profit = inc / sal #利益率=当期純利益/売上高
puts "損益分岐点売上高"
puts ber_eve.to_i
puts "利益率"
puts "#{profit * 100}%"