抹殺世界
問題文要約
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
コードの書き方は、「今はこれが精一杯」ということですが、何か間違いあればご指摘ください
見てくれてありがとう!