1st STEP 回答と解説
人工無脳バトルへのたくさんの
エントリーありがとうございました!
1st Stepの問題の解説と、
みなさんからいただいた中で最も優秀だった
解答をご紹介します!
では、まず問題から。
【問題】
以下の暗号を解読し、任意の入力値に対して暗号文を解読するプログラムを作成しなさい。
【例】
m , VGEF → JUST
md, MWAN → ATOK
qk, FSJKZYR → ????
※ 入力値は a-zの1文字以上の小文字と、A-Zの1文字以上の大文字
※ 入力値に対するバリデートは考慮しなくてよい


【解答言語】
Java / C++
Question 1
【問題】
以下の入力値の法則性を解読し、任意の入力値に対して正しい答えを出すプログラムを作成しなさい。

【例】
a, a → 0、a, b → 1、ab, ba → 3、ba, ba → 4、bbb, aaa → 7
※ 入力値は aまたはbを任意個含む文字列が2つ
※ 入力値に対するバリデートは考慮しなくてよい


【解答言語】
Java / C++
Question 2
解説します。
Question 1
【問題】
以下の暗号を解読し、任意の入力値に対して暗号文を解読するプログラムを作成しなさい。
m , VGEF → JUST
md, MWAN → ATOK
qk, FSJKZYR → ????


【解説】
暗号の答えはPITAJOB。ヴィジュネル暗号(というかほぼシーザー暗号)となっており、1つめの入力値のアルファベットの順番だけ、
2つめのアルファベットをずらせばOK。つまり、キーがqk、暗号化文字列が FSJKZYR なので、 Fを16文字、Sを10文字、Jを16文字、Kを10文字・・・
とそれぞれずらしていくと、 ”PITAJOB” が得られる。

なお、アルファベットを戻すときに進める方向を逆にしてしまうと、答えがPITAJOBにならず、意味のない文字列になるのでご注意を・・・。

プログラミングとしては、char型がint型に変換できることを利用してずらし、アルファベットの範囲外に出たものを剰余などを使って補正したあと、
再度アルファベットに戻せばよい。あとは、この戻し方をどうやって実装するかが腕の見せ所!

・・・ちなみに、「ピタジョブ」はジャストシステムが始めた求人・転職サイトです。
【正答率】 47%
public class Question1 {
public static String decrypt(String key, String word) {
String answer = null;
//---- ここから下が解答箇所
char[] shiftArray = key.toCharArray();
char[] wordArray = word.toCharArray();
StringBuilder builder = new StringBuilder();
for(int i = 0; i < wordArray.length; i++) {
int key1 = wordArray[i];
int key2 = shiftArray[ i % shiftArray.length] - 'a';
int num = (key1 - key2 + 'A') % 26 + 'A';
builder.append((char)num);
}
answer = builder.toString();
// --- ここから上が解答箇所 ----
return answer;
}
public static void main(String[] args) {
System.out.println(decrypt("m", "VGEF"));
System.out.println(decrypt("md", "MWAN"));
System.out.println(decrypt("qk", "FSJKZYR"));
}
}
(回答例:Java)
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
string decrypt(const char* key, const char* word){
string answer(word);
// ここに回答を記載してください。
size_t key_len = strlen(key);
for(size_t i = 0; i < answer.size(); i++) {
answer[i] = answer[i] - key[i % key_len] + 'a';
if(answer[i] < 'A') answer[i] += 26;
}
return answer;
}
int main(void){
cout << decrypt("m", "VGEF") << endl;
cout << decrypt("md", "MWAN") << endl;
cout << decrypt("qk", "FSJKZYR") << endl;
}
(受験者の秀逸な回答:C++)
Question 2
【問題】
以下の入力値の法則性を解読し、任意の入力値に対して正しい答えを出すプログラムを作成しなさい。
a, a → 0、 a, b → 1、 ab, ba → 3、 ba, ba → 4、bbb, aaa → 7
【解説】
 aが0、bが1としたときの2進数で、この和を10進数表記したものが答え。
 ab, ba → 01, 10 → 1 + 2 = 3
 プログラミングとしては、文字列を2進数に変換、2進数を10進数に変換という2つを行った上で、
 足し算すればよい。もちろん、2進数のまま足し算して10進数にしてもOK。
【正答率】 60%
public class Question2 {
public static int question(String input1, String input2) {
int ans = 0;

//--- ここから下が解答 ----
char[] input1_char = input1.toCharArray();
char[] input2_char = input2.toCharArray();
for(int i = 0 ; i < input1_char.length; i++) {
ans += Math.pow(2, input1_char.length - i - 1) * (input1_char[i] - 'a');
}
for(int i = 0 ; i < input2_char.length; i++) {
ans += Math.pow(2, input2_char.length - i - 1) * (input2_char[i] - 'a');
}
//--- 解答ここまで -----
return ans;
}
public static void main(String[] args) {
System.out.println(question("a", "a"));//0
System.out.println(question("a", "b"));//1
System.out.println(question("ab", "ba"));//3
System.out.println(question("ba", "ba"));//4
System.out.println(question("bbb", "aaa"));//7
System.out.println(question("bbb", "b"));//8
}
}
(回答例:Java)
#include <string>
#include <iostream>
using namespace std;
// 'a'を0、'b'を1として2進数とし、数値に変換する
int to_number(const char *s) {
int ret = 0;
for(const char *it = s; *it; it++) {
ret = ret * 2 + *it - 'a';
}
return ret;
}
int question(const char* input1, const char* input2){
return to_number(input1) + to_number(input2);
}
int main(void){
cout << question("a", "a") << endl;//0
cout << question("a", "b") << endl;//1
cout << question("ab", "ba") << endl;//3
cout << question("ba", "ba") << endl;//4
cout << question("bbb", "aaa") << endl;//7
return 0;
}
(受験者の秀逸な回答:C++)
いかがでしたか?
1st Stepをクリアした猛者の手によって
本戦で誕生する人工無脳はTwitterで公開されます。
みなさんの応援が勝敗を分けます!
この機会にフォローして活躍にご注目ください!
詳しくはこちらから!

http://www.justsystems.com/jp/employ/int/
おまけ
おまけ1
若手社員によるマニアックな解答
(もしかすると、バトル対戦相手かも?)
import java.util.function.Function;
import java.util.stream.IntStream;
public class Question1 {
public static String decrypt(String key, String word) {
String answer = null;
// --- ここから下に解答を記載して下さい ----
Function<String, Function<Character, Function<Integer, Character>>> decoder =
k -> c -> pos ->
(char) (Math.floorMod(c - 'A' + 'a' - (k.charAt(pos % k.length())), 26) + 'A');
  answer = IntStream.range(0, word.length())
.mapToObj(pos -> decoder.apply(key).apply(word.charAt(pos)).apply(pos))
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString();
// --- ここから上に解答を記載して下さい ----
return answer;
}
}
(Question1:Java)
public class Question2 {
public static int question(String input1, String input2) {
int ans = 0;
// --- ここから下に解答を記載して下さい ----
Function<String, Integer> decoder = t -> t.chars().map(c -> c - 'a').reduce((a, b) -> b + a * 2).orElse(0);
ans = decoder.apply(input1) + decoder.apply(input2);
// --- ここから上に解答を記載して下さい ----
return ans;
}
}
(Question2:Java)
おまけ2
※ 課題を社内公開したら、swiftで解答ができてました。
(解答として選択できる言語じゃないです・・・)
extension String {
var length: Int {
return count(self)
}
var unicode: UInt32 {
return first(self.unicodeScalars)!.value
}
func subString(startIndex: Int, length: Int) -> String {
let start = advance(self.startIndex, startIndex)
let end = advance(self.startIndex, startIndex + length)
return self.substringWithRange(Range<String.Index>(start: start, end: end))
}
}
※ 次のページに続く
(Question1:Swift)
※ 前のページからの続き
class Question1 {
func decrypt(#key: String, word: String) -> String {
var answer = ""
for (index, decodeWord) in enumerate(word) {
let decodeKey = key.subString(index % key.length, length: 1).unicode - "a".unicode
let num = (String(decodeWord).unicode - decodeKey + "A".unicode) % 26 + "A".unicode
answer += String(UnicodeScalar(num))
}
return answer
}
func run() {
println(decrypt(key: "m", word: "VGEF"))
println(decrypt(key: "md", word: "MWAN"))
println(decrypt(key: "qk", word: "FSJKZYR"))
}
}
class Question2 {
func question(#input1: String, input2: String) -> Int {
var answer = 0
for input in [input1, input2] {
for (index, inputChar) in enumerate(input) {
let shift = count(input) - index - 1
let bits = inputChar == "a" ? 0 : 1
answer += bits << shift
}
}
return answer
}
func run() {
println(question(input1: "a", input2: "a"))
println(question(input1: "a", input2: "b"))
println(question(input1: "ab", input2: "ba"))
println(question(input1: "ba", input2: "ba"))
println(question(input1: "bbb", input2: "aaa"))
}
}
Question2().run()
(Question2:Swift)
みなさんの回答と比べていかがでしたか!?
本戦で公開される人工無脳にもご期待ください!
人工無脳バトル 1st STEP 回答と解説

人工無脳バトル 1st STEP 回答と解説