NaaN日記

やったこと、覚えたことを発信する場

attr_reader, attr_writerの確認(Ruby)

なんとなく理解できるようになったとはいえ、「理解できました」というにはまだ遠い。
ということで、attr_writerはこうやって動くんだなーということを確認。

class Name
  attr_reader :user_name
  def initialize
    @user_name = "Tom"
  end
end

class Greet < Name
  attr_writer :user_name
end

a = Greet.new
p a.user_name # "Tom"
p a.user_name = "Thomas" # "Thomas"
class Name
  attr_reader :user_name
  def initialize
    @user_name = "Tom"
  end
end

class Hello < Name
  attr_writer :user_name
  def hello
    @user_name = "Ken"
    puts "Hello, #{@user_name}"
  end
end

b = Hello.new
b.hello # Hello, Ken
p b.user_name # "Ken"
p b.user_name = "Bob" # "Bob"
attr_reader, attr_writerを使わずに書くとこうなる
class Name
  def initialize
    @user_name = "Tom"
  end
  
  def user_name
    @user_name
  end
  
  def user_name=(name)
    @user_name = name
  end
end

class Hello < Name
  def hello
    @user_name = "Ken"
    puts "Hello, #{user_name}"
  end
end

b = Hello.new
b.hello # Hello, Ken
p b.user_name # "Ken"
p b.user_name = "Bob" # "Bob"

もうちょっと使いこなせるようになったらまたメモしにくる

case文(Ruby)

やっぱりcase文ってどの言語においてもなんとなく好きなんですよね。
Rubyのcase文って、JavaScriptだとかC言語だとかのswitch文とは違うな~と。
defaultじゃなくてelseだったり。

case文
case 比較したいオブジェクト
when1 then
  処理
when2 then
  処理
~~
else
  処理
end

thenは省略できる

caseを使ってじゃんけんをしてみた
puts "グー: 1, チョキ: 2, パー: 3, おわり: 4"
list = [1, 2, 3]
loop do
  hand1 = gets.to_i
  hand2 = rand(1..3) # 1, 2, 3の中からランダムに
  result = (hand1 - hand2)
  if hand1 == 4
    break
  elsif list.count(hand1) == 0 #入力がlist(123)以外だったら次に行く
    next
  else
    puts hand2
    case result
    when -2
      puts "負け"
    when 0
      puts "あいこ"
    when 1
      puts "負け"
    else
      puts "勝ち"
    end
  end
end
===

値と一致するかどうかは「===」演算子を使って判定
左辺が数値や文字列 のときは「==」と同じ意味
正規表現の場合はマッチしたかどうか、クラスの場合はクラスのインスタンスかどうかを判定する

やってて気づいたこと

"\n"の入力はto_iを使うと0になってしまう

取り除いたりする その2(Ruby)

○引数で指定した文字を文字列から削除する

delete
delete!
>> moji = "chocolate"
=> "chocolate"
>> moji.delete("c")
=> "hoolate"

○ 文字列中の部分文字列を削除

slice!
>> moji
=> "cooperate"
>> moji.slice!(1) # moji[1]を削除
=> "o"
>> moji
=> "coperate"
>> moji.slice!(0, 1) # moji[0]から1つ削除
=> "c"
>> moji
=> "operate"
>> moji.slice!(5..6) # moji[5]からmoji[6]までを削除
=> "te"
>> moji
=> "opera"
>> moji.slice!("op") # 文字列"op"を削除
=> "op"
>> moji
=> "era"

○文字列を置換する

gsub
gsub!

正規表現が関わってくるので後々詳しくやりたい

>> moji = "cooperate"
>> moji.gsub("co", "") #"co" を""に置換(削除)
=> "operate"

○同じ文字が連続しているとき、一つにまとめる

squeeze
squeeze!

引数を指定すると、指定した文字のみまとめる

>> moji = "cooperate"
=> "cooperate"
>> moji.squeeze()
=> "coperate"

取り除いたりする(Ruby)

取り除くで!!という感じのものをまとめた

○末尾の改行文字(\n, \r)を取り除く

chomp
chomp!

chomp!はレシーバ自身を変更する。
引数に文字列を指定すると、その文字列を改行文字とみなす
末尾に改行文字があればレシーバ自身、ない時はnilを戻り値とする

>> moji = gets #Hello Curryと入力
>> moji
=> "Hello Curry\n"
>> moji.chomp #改行文字を取り除く
=> "Hello Curry"
>> moji
=> "Hello Curry\n"
>> moji.chomp! #レシーバ自身を変更
=> "Hello Curry"
>> moji
=> "Hello Curry"
>> moji.chomp!("y") #文字列を指定
=> "Hello Curr"

○末尾から1文字取り除く

chop
chop!

chop!はレシーバ自身を変更する。
末尾が"\r\n"で終わっている場合は"\r\n"を取り除く
漢字のように2バイト以上の文字でも1文字分消してくれる

>> moji = gets # Hello Curry
=> "Hello Curry\n"
>> moji.chop # 1文字(\n)取り除く
=> "Hello Curry"
>> moji.chop!
=> "Hello Curry"
>> moji
=> "Hello Curry"
>> moji.chop! # 1文字(y)取り除く
=> "Hello Curr"
>> moji
=> "Hello Curr"

○文字列の先頭の空白文字を取り除く

lstrip
lstrip!

lstrip!はレシーバ自身を変更する。

>> moji = gets"    Hello Curry\n"
>> moji.lstrip
=> "Hello Curry\n"
>> moji
=> "    Hello Curry\n"
>> moji.lstrip!
=> "Hello Curry\n"
>> moji
=> "Hello Curry\n"

○文字列の末尾の空白文字を取り除く

rstrip
rstrip!

rstrip!はレシーバ自身を変更する。
半角空白・タブ・復帰・改行・末尾のヌル文字など

>> moji = gets # "Hello Curry    \n"
=> "Hello Curry    \n"
>> moji.rstrip
=> "Hello Curry"
>> p moji
=> "Hello Curry    \n"
>> moji.rstrip!
=> "Hello Curry"
>> moji
=> "Hello Curry"
>> moji
=> "Hello Curry"
>> moji.rstrip! # 末尾が空白文字でないとき
=> nil

○文字の先頭と末尾の空白文字を取り除く

strip
strip!

strip!はレシーバ自身を変更する。

>> moji = gets # "   Hello Curry   \n"
>> moji.strip
=> "Hello Curry"
>> moji
=> "   Hello Curry   \n"
>> moji.strip!
=> "Hello Curry"
>> moji
=> "Hello Curry"

○配列の末尾の要素を削除し要素を返す

pop

レシーバ自身を変更する
空の時はnilを返す

>> list = ["N", "a", "a", "n", "\n"]
>> list.pop
=> "\n" # 末尾の要素
>> list
=> ["N", "a", "a", "n"] # list自身が変更された

○配列の先頭の要素を削除し要素を返す

shift

レシーバ自身を変更する
空の時はnilを返す

>> list = ["K", "a", "n", "p", "a", "n"]
>> list.shift
=> "K" # 先頭の要素
>> list
=> ["a", "n", "p", "a", "n"]

1から与えられた数まで素数かどうか(C)

前回の続きができた。今度は1から与えられた数まで調べる

#include <stdio.h>
#include <math.h>
int main(void){
    int max;//最大値
    int i, j;
    int sosu[100];  //とりあえず100まで。ここが0だったら素数
    double sqr[100];  //それぞれの平方根
    int num[100];  //1から最大値までが入っている
    scanf("%d", &max);
    for(i=1; i<=max; i++){
        sosu[i-1] = 0;
        num[i-1] = i;
        sqr[i-1] = floor(sqrt(num[i-1]));
    }
    if(max>=3){
        printf("1\n");
        printf("2は素数です\n");
        printf("3は素数です\n");
        for(i=3; i<=max; i++){
            for(j=2; j<=sqr[i]; j++){
                if (num[i]%j == 0){
                    sosu[i] = 1;
                }
                if (j == sqr[i]){
                    if (sosu[i] == 0){
                        printf("%dは素数です\n", num[i]);
                    }
                    else{
                        printf("%d\n", num[i]);
                    }
                }
            }
        }
    }
    else if (max == 1){
        printf("1\n");
        }
    else if(max == 2){
        printf("1\n");
        printf("2は素数です\n");
    }
    return 0;
}

やっぱり3以下は直接書いた方が早いという結論に現時点では至っている。
あと、とにかく大きい数を入力したくなる。

与えられた数が素数かどうか(C)

sqrtを使って素数かどうかを判断できるものを作れると知ったので、
入力した数字が素数かどうか判断するものを書いてみた。

#include <stdio.h>
#include <math.h>
int main(void){
    int num, i;
    int sqr;  //平方根
    int sosu = 0;  //ここの値が変わらなかったら素数
    scanf("%d", &num);
    sqr = floor(sqrt(num));
    if(num == 1){
        printf("1です\n");
    }
    if(num == 2){
        printf("2は素数です\n");
    }
    if(num == 3){
        printf("3は素数です\n");
    }
    for(i=2; i<=sqr; i++){
        if(num%i==0){
            sosu = 1;
        }
        if(i==sqr){
            if(sosu==0){
                printf("%dは素数です\n", num);
            }
            else{
                printf("%dは素数ではありません\n", num);
            }
        }
    }
    return 0;
}

1~3までの値をどうするか困ったのでそのまま書いた。
次は1から入力した値までの数を判断させるもの作れたらいいね

math.h その1(C)

math.h、何が何だか忘れそう

コンパイル

GCCコンパイルするためには

gcc hoge.c -lm
平方根・累乗・累乗根
sqrt(x);  //平方根
pow(x,n);  //累乗
pow(x, 1/n);  累乗根
対数関数・指数関数
log(x)  //対数関数
exp(x)  //指数関数
//指数関数は値が大きくなるので理科的表記に
切り上げ・切り捨て・四捨五入
ceil(x)  //切り上げ
floor(x)  //切り捨て
floor(x+0.5)//四捨五入
//返却値は実数
弧度
kodo = (M_PI * kakudo) / 180//M_PIはπ
三角関数
sin(kodo)
cos(kodo)
tan(kodo)
asin(kodo)
acos(kodo)
atan(kodo)//90度に気を付ける
桁数を求める
c = pow(n, p);
p = log10(c) / log10(n);
log10(c) = p * log10(n);//桁数 
ビット数
bit = log2(pow(n, p));
bit = p * log2(n);//ビット数