あなたが文字列としてあなたの数を持っているとき(またはあなたがあなたの数字を整数として持っているなら、#to_s
それだけで文字列を取得する)、そしてあなたはそこから簡単に数字を抽出することができます:
number_string[idx].to_i
またはRuby1.8を使用している場合
number_string[idx..idx].to_i
#to_i
それを整数に変換するので、他の人に追加することができます。次に、提供された手順に進んで番号を計算します。
idx
それを実装するためにあなたがしなければならないのは、数値の文字列表現のインデックス位置に命令で提供された位置を正しくマップすることです。頭を数えて紙の上でそれを行うか、Rubyで負のidx(文字列の終わりから数える)を使用してください。
編集:
解決策は次のようになります。
bar_code_data = "961102098765431234567C"
digits_with_position = bar_code_data.reverse[1..14].split(//).map(&:to_i).zip(2..1/0.0)
これは次のようになります。
reverse
-文字列を逆にするので、逆ではなく左から右に数えることができます
[1..14]
-関心のある文字のサブストリッグを選択します(Rubyは0からカウントします)
split(//)
-1つの文字列を長さ1文字のサブ文字列に分割します。つまり、数字を区切ります。
map(&:to_i)
-配列のすべての要素で#to_iを呼び出す、つまり整数に変換する
zip(2..1/0.0)
-すべての要素に、2から無限大までの位置を追加します
これで、次のようなものが必要になります。
[[7、2]、[6、3]、[5、4]、[4、5]、[3、6]、[2、7]、[1、8]、[3、9]、[ 4、10]、[5、11]、[6、12]、[7、13]、[8、14]、[9、15]]
sum = digits_with_position.map{|i| i[0] * (i[1].even? ? 3 : 1)}.reduce(+:)
アルゴリズムにはほとんど変更を加えていませんが、従うのは難しいことではありません。
それ以外の:
sum = (in[2] + in[4] + in[6] + ...)*3 + (in[3] + in[5] + in[7] + ...)
私たちが作った:
sum = in[2]*3 + in[3]*1 + in[4]*3 + in[5]*1 + in[6]*3 + in[7]*1 + ...
これは同じ結果ですが、操作の順序が変更されています。
また:
map {|i| ... }
-リストのすべての値をマップします。この場合、iはタプルであり、[digit、pos]のペアです。
i[1].even?
-位置が偶数かどうかを確認します
i[1].even? ? 3 : 1
-偶数位置の場合は3を使用し、反対(奇数)の場合は1のみを使用します
reduce(:+)
-+演算を使用して、結果の配列を単一の値に減らします(すべての結果を追加します)
今楽しい部分:-)
check_code = 10 - (sum % 10)
sum % 10
-合計値のモジュール10、10による除算の合計のリマインダーを返します。この場合は最後の桁です
10 - (sum % 10)
-10の最小倍ではない最も近いものを補完する
結果に130がある場合、次に大きい10の倍数は140であり、差は10であるため、説明にエラーがあります。これは、数字の正しい結果ではありません(おそらく0である必要があります)。
他のより高速なソリューションは次のようになります(すべてのループを展開し、すべてをハードコーディングするだけです):
d = "961102098765431234567C".split(//) # avoid having to use [-2..-2] in Ruby 1.8
sum_even = d[-2].to_i + d[-4].to_i + d[-6].to_i + d[-8].to_i + d[-10].to_i + d[-12].to_i + d[-14].to_i
sum_odd = d[-3].to_i + d[-5].to_i + d[-7].to_i + d[-9].to_i + d[-11].to_i + d[-13].to_i + d[-15].to_i
sum = sum_even * 3 + sum_odd
check_code = 10 - sum % 10
誰かがそれを求めない限り、それは説明する価値のない、完全に単純な解決策です