0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

paiza 抹殺世界C問題「機械の総合病院 」をテストコード

Last updated at Posted at 2019-02-06

抹殺世界

問題文要約

PAIZA病院の、パスワードの条件として三つ決められた
・長さが 6 以上
・英字と数字の両方を含む必要がある。文字列は半角英字あるいは半角数字で構成された文字列である。
・同じ文字を 3 つ以上連続で使用することはできない。なお、英字の大文字と小文字は区別する必要はない。

与えられたパスワードは正しいかどうかを調べたい

大枠

テストコード

spec/paiza_lebel_C_spec.rb
require 'spec_helper'

RSpec.describe Lebel_C do
    it "文字列の長さが6以上" do
      result = Lebel_C.new.pass_check1(word: "DjZGrduN8Mj4") 
      expect(result).to eq true 
    
      false_pass = Lebel_C.new(word: "aaaaa")
      expect(false_pass.pass_check1).to eq false
    end
end

テストされるコード

lib/paiza_lebel_C.rb
class Lebel_C
    def pass_check1(word:)
      # 中身
    end
end

メソッドの中身

条件1:長さが6以上

lib/paiza_lebel_C.rb
class Lebel_C
    def pass_check1(word:)
        word.size >= 6
    end
end
$ bundle exec rspec
1 example, 0 failures

条件1クリア

条件2: 文字列は英字と数字の両方を含む

文字列として渡されるがその中に0~9の数値の形がある。それらと、英字があるかどうかを判定したい。数値の形をしているかを調べたいだけで、integerクラスである必要はないので文字列ママの比較

lib/paiza_lebel_C.rb

    def pass_check1(word:)
        word.size >= 6
    end

    def pass_check2(word:)
        pass = word.split("")    //文字列にeach使えないので分割して配列にする
        int = false                  // 0~9の数字があるか判定させる
        str = false                  //a~zの英字があるかを判定させる
        pass.each do |p|
            if %W(1 2 3 4 5 6 7 8 9 0).include?(p)
              int = true
            else
              str = true
            end
        end
        if int == true && str == true
            true
        else
            false
        end
    end

テストコード

spec/paiza_lebel_C_spec.rb
require 'spec_helper'

RSpec.describe Lebel_C do
    it "文字列の長さが6以上か?" do
      result = Lebel_C.new.pass_check1(word: "DjZGrduN8Mj4") 
      expect(result).to eq true  

      false_pass = Lebel_C.new(word: "aaaaa")
      expect(false_pass.pass_check1).to eq false
    end

    it "文字列に数字と英字が含まれているか?" do
        false_pass = Lebel_C.new(word: "abcdefg")
        expect(false_pass.pass_check2).to eq false

        false_pass = Lebel_C.new(word: "12456789")
        expect(false_pass.pass_check2).to eq false

        expect(password.pass_check2).to eq true
    end
end
$ bundle exec rspec
2 example, 0 failures

条件2もクリア

条件3: 大文字小文字の区別なく、同じ文字を3回連続で使用することはできない

lib/paiza_lebel_C.rb
    def pass_check1(password:)
        password.size >= 6
    end

    def pass_check2(word:)
        pass = word.split("")    
        int = false                 
        str = false                  
        pass.each do |p|
            if %W(1 2 3 4 5 6 7 8 9 0).include?(p)
              int = true
            else
              str = true
            end
        end
        if int == true && str == true
            true
        else
            false
        end
    end

    def pass_check3(word:)
        pass = word.split("")
        the_same = 0             //同じ文字が続いた回数を数える
        before_word = ""         //一つ前の文字を入れて比較させる
        pass.each do |p|
            if before_word == p
                the_same += 1
            elsif before_word.casecmp(p) == 0 //同じなら0が帰ってくる
                the_same += 1
            else
                the_same = 0
            end
            before_word = p
            break if the_same == 2           //同じ文字が三回続いたらeachを抜ける
        end
        the_same < 2
     end

リファレンスcasecmp (String)
https://ref.xaio.jp/ruby/classes/string/casecmp

テストコード

spec/paiza_lebel_C_spec.rb
require 'spec_helper'

RSpec.describe Lebel_C do
    it "文字列の長さが6以上か?" do
      result = Lebel_C.new.pass_check1(word: "DjZGrduN8Mj4") 
      expect(result).to eq true  

      false_pass = Lebel_C.new(word: "aaaaa")
      expect(false_pass.pass_check1).to eq false
    end

    it "文字列に数字と英字が含まれているか?" do
        false_pass = Lebel_C.new(word: "abcdefg")
        expect(false_pass.pass_check2).to eq false

        false_pass = Lebel_C.new(word: "12456789")
        expect(false_pass.pass_check2).to eq false

        expect(password.pass_check2).to eq true
    end

    it "三回同じ文字が続いていないか?" do
        false_pass = Lebel_C.new(word: "aAaAa")
        expect(false_pass.pass_check3).to eq false

        false_pass = Lebel_C.new(word: "a11111a")
        expect(false_pass.pass_check3).to eq false

        expect(password.pass_check3).to eq true
    end
end
$ bundle exec rspec
3 example, 0 failures

終了

リファクタリング

最終コード(見やすくなったか?)

lib/paiza_lebel_C.rb
class Lebel_C

    def initialize(word:)
      @password = word
    end
    
    def pass_check1
        @password.size >= 6
    end

    def pass_check2
        pass = @password.split("")
        int = false
        str = false
        pass.each do |p|
            if %W(1 2 3 4 5 6 7 8 9 0).include?(p)
              int = true
            else
              str = true
            end
        end
        if int == true && str == true
            true
        else
            false
        end
    end

    def pass_check3
        pass = @password.split("")
        the_same = 0
        before_word = ""
        pass.each do |p|
            if before_word.casecmp(p) == 0
                the_same += 1
            elsif before_word == p
                the_same += 1
            else
                the_same = 0
            end
            before_word = p
            break if the_same == 2
        end
        the_same < 2
    end
end
spec/paiza_lebel_C_spec.rb
require 'spec_helper'

RSpec.describe Lebel_C do
  let(:password) { Lebel_C.new(word: "DjZGrduN8Mj4") }

  describe '文字列の長さ' do
    it "6以上" do
        expect(password.pass_check1).to eq true
    end

    it "6以下" do
        false_pass = Lebel_C.new(word: "abc")
        expect(false_pass.pass_check1).to eq false
    end
  end

  describe '文字列に数字と英字の両方が含まれているか?' do
    it "含まれている" do
        expect(password.pass_check2).to eq true
    end

    it "含まれていない" do
        false_pass = Lebel_C.new(word: "abcdefg")
        expect(false_pass.pass_check2).to eq false

        false_pass = Lebel_C.new(word: "12456789")
        expect(false_pass.pass_check2).to eq false
    end
  end

  describe '同じ文字が3回続いている?' do
    it "続いている" do
        false_pass = Lebel_C.new(word: "aAaAa")
        expect(false_pass.pass_check3).to eq false

        false_pass = Lebel_C.new(word: "a11111a")
        expect(false_pass.pass_check3).to eq false
    end

    it "続いていない" do
        expect(password.pass_check3).to eq true
    end
  end
end

コードの書き方は、「今はこれが精一杯」ということですが、何か間違いあればご指摘ください

見てくれてありがとう!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?