Skip to content

Instantly share code, notes, and snippets.

@sohsatoh
Created December 8, 2020 17:54
Show Gist options
  • Save sohsatoh/8ed3bd1808e3f51a317405a346ea80e5 to your computer and use it in GitHub Desktop.
Save sohsatoh/8ed3bd1808e3f51a317405a346ea80e5 to your computer and use it in GitHub Desktop.
エンジニア課題解法 - dely, Inc.

新卒エンジニア課題解法 - dely, Inc

概要

まず、私が課題を解くにあたって使用した言語は Javascript である。 理由としては、

  • ブラウザで動作すること
  • ある程度慣れている言語であること

が挙げられる。

使用したツール

使用したツールは特にないが、スクリプトを書くにあたり、以下の StackOverflow の回答例を参考にした。

https://stackoverflow.com/questions/10834796/validate-that-a-string-is-a-positive-integer

https://stackoverflow.com/questions/57294167/how-to-process-negative-shifts-in-caesars-cipher-javascript

なぜこの解き方を選んだか

設計

まず最初のヒントである、"a0b1d3f5 : aaaa"を見た時には単純なシーザー暗号だと考え、それに沿うように設計を考えた。

しかし、二番目のヒントが違うロジックで暗号化されていることに気づき、また、程なくして英字の次の数字が偶数の場合は正の値、奇数の場合は負の値で文字がスライドしていることに気づいたため、そのようにコードを実装した。

実装

ロジックのわかり易さを優先し、また他のシーザー暗号にも使用できるように caesar 関数を実装した。

この部分では

"const alphabet = "abc..."

とし、それをスライドさせる、という解法も思いついたが、記述ミスをへらすためにも charCodeAt()を使用した。

またエンジニア向けの課題ということで、英語部分とスライドさせる数字部分を自動的に判別するような実装が必要だと考え、一度 array に入れるような処理にしている。

その他の部分の実装に関しては、以下のコードにコメントとして記載した。

"use strict";
const caesar = (char, shift) => {
// Ref: https://stackoverflow.com/questions/57294167/how-to-process-negative-shifts-in-caesars-cipher-javascript
const aCode = "a".charCodeAt();
const zCode = "z".charCodeAt();
const aToZ = zCode - aCode + 1;
if (shift < 0) {
shift = aToZ + (shift % aToZ);
} else if (shift > aToZ) {
shift = shift % aToZ;
}
let shiftedCode = char.charCodeAt() + shift;
if (shiftedCode > zCode) {
// shiftedCode is greater than zCode
shiftedCode = aCode - 1 + (shiftedCode % zCode);
} else if (shiftedCode < aCode) {
// shiftedCode is less than aCode
shiftedCode = aCode - 1 + (-shiftedCode % aCode);
}
const shiftedChar = String.fromCharCode(shiftedCode);
return shiftedChar;
};
const isNumeric = (str) => {
//Ref: https://stackoverflow.com/questions/10834796/validate-that-a-string-is-a-positive-integer
return /^\d+$/.test(str);
};
let array = [];
const cipherText = "k46927595597b23999455421q67482438962k54959663593t66323632674o97789468516j64445937397y88486785969s72835486740c83666964247g32493592926i57254538568g24323636572x76885739897v32752784694f49994245441b25742799753";
for (let i = 0, len = cipherText.length; i < len; i++) {
const char = cipherText[i];
const prevChar = array[array.length - 1];
if (i == 0 || !(isNumeric(prevChar) && isNumeric(char))) {
// The character is the first letter of the cipherText or the first character of number
array.push(char);
continue;
}
array.pop();
array.push(prevChar + char);
}
console.log(array);
let decipherText = "";
for (let i = 0, len = array.length; i < len; i = i + 2) {
if (array[i + 1] % 2 == 0) decipherText += caesar(array[i], Number(array[i + 1])); // The number is even
else decipherText += caesar(array[i], Number(-array[i + 1])); // The number is odd
}
console.log("decipherText= ", decipherText);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment