yuuki blog

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

Ruby 1次方程式の計算

簡単な1次方程式を計算するプログラムです。

このような式のx を求める計算です
a + b = c (+には +,-,*,/ のいずれが入ります。)
条件は以下の通りです
  1. a,b,cはいずれも整数です。
  2. a,b,cのうちいずれかをxにします。
#入力例
2 * 3 = x
#出力例
6
int = gets.chomp.split.map(&:to_s)    #値を1次配列の文字列で入力します。
a = int[0].to_i           #a,b,cを数列に直します。
s = int[1]
b = int[2].to_i
c = int[4].to_i
if a == 0             #文字列から数列にしたため、xには0が入っています。            # sに代入されている符号と参照し、計算しています。
  if s == "+"
    x = c - b
  elsif s == "-"
    x = c + b
  elsif s == "*"
    x = c / b
  elsif s == "/"
    x = c * b
  else
  end
elsif b == 0
  if s == "+"
    x = c - a
  elsif s == "-"
    x = a - c
  elsif s == "*"
    x = c / a
  elsif s == "/"
    x = a / c
  else
  end
elsif c == 0
  if s == "+"
    x =  a + b
  elsif s == "-"
    x = a - b
  elsif s == "*"
    x = a * b
  elsif s == "/"
    x = a / b
  else
  end
else
end
puts x
配列に入っている符号を演算式に使えたら、コンパクトに記述できたのですが、やり方がわかりませんでした。

Ruby 複数の文字を削除する方法

ローマ字を入力して、子音のみを出力します。

  • ここではローマ字は小文字のみとします。

出力例

文字を入力してください
hatena
子音はhtnです
n =0
puts "文字を入力してください"
s = gets.chomp
str = ["k","s","t","n","h","m","y","r","w","g","z","d","b","c","j","p","v","f","l"]
19.times do
  s = s.delete(str[n])
  n += 1
end
puts "子音は#{s}です"
入力した文字をstrの配列の中身と一つづつ参照していき、合致した文字を削除しています。
  • delete_if や reject を 使用すると簡単にかけるみたいですが、うまくいかなかったので、timeメソッドを使用しました。

Ruby 簡単な四則計算機

2つの変数が用意されていて、入力した命令に対して、以下の動作を行います。

  • set i a : 変数 i に値 a(b) を代入する (変数a = 1, 変数b= 2)
  • add a :「変数 a の値 + a」を計算し、計算結果を変数 b に代入する
  • sub a :「変数 a の値 - a」を計算し、計算結果を変数 b に代入する
  • mul a :「変数 a の値 * a」を計算し、計算結果を変数 b に代入する
  • div a :「変数 a の値 / a」を計算し、計算結果を変数 b に代入する

初めの条件は以下の通りです。

  1. 変数a = 0
  2. 変数b = 0
  3. 何回計算するか入力する。
入力例
何回計算しますか?  
3  
命令、値を入力してください  
set 1 10   
命令、値を入力してください  
set 2 20  
命令、値を入力してください  
add 40  
puts "何回計算しますか?"
n = gets.to_i
a = 0
b = 0
n.times do
  puts "命令、値を入力してください"
  s_i = gets.chomp.split.map(&:to_s)
  if s_i[0] == "set"
    i = s_i[1].to_i
    if i == 1
    a = s_i[2].to_i
    else i == 2
    b = s_i[2].to_i
    end
  elsif s_i[0] == "add"
    b = a + s_i[1].to_i
  elsif s_i[0] == "sub"
    b = a - s_i[1].to_i
  elsif s_i[0] == "mul"
    b = a * s_i[1].to_i
  else s_i[0] == "div"
    b = a / s_i[1].to_i
  end
end
puts "a=#{a}, b=#{b}"

Ruby 完全数を判別する

完全数とは

  • 自分自身を除く正の約数の和に等しくなる自然数のことです。
  • 完全数の最初の3個は 6 (= 1 + 2 + 3)、28 (= 1 + 2 + 4 + 7 + 14)、496 (= 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248) です。

  • たとえば、N = 28 のとき、28 の約数は 1, 2, 4, 7, 14, 28 なので、S = 1+2+4+7+14 = 28 となります。従って、28 は完全数です。 また、N = 16 のときには S = 1+2+4+8 = 15 となるので、16 はほぼ完全数です。

完全数の解き方

  • 約数を探す
  • 約数をすべて足し合わせる
  • 与えられた数字と比較する
puts "何回数えますか?"
n = gets.to_i
sum = 0

n.times do
  puts "値を入力してください"
  number = gets.to_i
  for i in 1..number - 1 do
    if number % i == 0
    sum += i
    end
  end
    if number == sum
      puts "完全数"
    elsif (number - sum).abs == 1
      puts  "ほぼ完全数"
    else 
      puts   "完全数ではない"
    end
    sum = 0
end

Ruby ポイント付与(支払い)問題

問題

プリペイドカードのポイント問題です。条件式は下記の通りです。

  • 初めにプリペイドカードの残高と支払い回数を記述します。
  • プリペイドカードの残額を使うと、 10 % が ポイントとしてたまります。(1ポイント=1円)
  • 支払う金額以上のポイントがある場合は、ポイントが優先的に使われます。
point_sum = 0
puts "残高"
remainder = gets.to_i
puts "支払い回数"
m = gets.to_i
m.times do
puts "支払い金額"
pay = gets.to_i
  if pay <= point_sum
    point_sum -= pay
    puts "残高#{remainder} ポイント数#{point_sum}"
  else
    remainder -= pay
    point = pay / 10
    point_sum += point
    puts "残高#{remainder} ポイント数#{point_sum}"
  end
end

m回支払いの処理をして、 pay <= point_sumならばポイントを使う処理をしています。

Ruby 文章のサイズを変更する

My#name#
is#haten
a#I#like
#program
ming#ver
y#much.#

を下記のように変更する方法です。

My#nam
e#is#h
atena#
I#like
#progr
amming
#very#
much.#
n,m = gets.chomp.split.map(&:to_i)
str = n.times.map{gets.chomp.split.map(&:to_s)}
s = str.flatten!.join
v = s.chars.each_slice(m).map(&:join)
puts v

まずn,m = gets.chomp.split.map(&:to_i)で、一列に複数の数値が入力値として与えられている場合で、それらを別々に取得します。

  • chomp メソッドは文字列末尾の改行文字を削除してくれるメソッドです。これがないと半角スペースによって先頭1文字しか取得できなくなります。
  • split メソッドは文字列を分割してくれるメソッドです。
  • map(&:to_i) は繰り返しメソッドで、(&:to_i) とすることで各数値をinteger型で取得できます。
  • ここではnは変更前に何行あるか、mは変更後に1行の中に、何文字あるかを記述します。

str = n.times.map{gets.chomp.split.map(&:to_s)}で、2次元の入力を行います。

  • map メソッドで {} の中をn回繰り返すという処理になります。
  • {} 内の処理は「一列で数値が複数与えられる場合」と同じものになります
  • 今の段階では[["My#name#"], ["is#haten"], ["a#I#like"], ["#program"], ["ming#ver"], ["y#much.#"]]と2次元配列になっています

s = str.flatten!.joinで2次元配列を文字列に変換しています。

*flatten!で2次元配列を1次元配列に変換しています。 * joinで1次元配列を文字列に変換しています。 "My#name#is#hatena#I#like#programming#very#much.#"

v = s.chars.each_slice(m).map(&:join)で、mの文字数ごとに1次元配列に変換します。

  • chars.で文字列の各文字を文字列の配列で返します。(.each_char)と同じ
  • each_sliceでは、m要素ずつブロックにて繰り返します。

Ruby n進数の表示方法

n進数から10進数へ変換

puts "値は?"
int = gets.chomp
puts "何進数?"
n = gets.to_i
puts int.to_i(n)

String.to_i(基数)と引数に基数を指定すると、n進数の文字列も数値に変換することができます

n進数から10進数へ変換

puts "値は?"
int = gets.to_i
puts "何進数に変換?"
m = gets.to_i
puts int.to_s(m)

Integer.to_s(基数)と引数に基数を指定すると、n進数から10進数に変換することができます