2
0

力こそパワー

いい感じの公式だったりアルゴリズムが思いつかない時に大事なのは?

そうだね、筋肉だね!!

面倒くさいので画面パタメータをListでもらった後のFunctionだけ

ちなみに引数のListを作ってる箇所はこっちの記事に書いてあるYO!!

nameCard.js
// [問題文(原文)]
// あなたはこれまでに出会った人たちの名刺を集めています。
// 名刺は、複数枚のファイルを閉じることができるバインダーに保存されています。
// 
// 1枚のファイルには、n個のポケットが横に並んでおり、表と裏の両面から名刺を眺めることができます。
// このため、1つのポケットには、2枚の名刺が背中合わせに入っています。
// 
// 各名刺には1から順に通し番号が付いているため、この番号の順に名刺を眺めることができるようにポケットに入っています。
// 1番からn番の名刺は、1枚目のファイルの表面から見たときに左詰めに並んでおり、
// n+1番から2n番の名刺は、1枚目のファイルの裏面から見たときに左詰めに並んでいます。
// 2枚目以降のファイルにも同様に名刺が並んでいます。
// 上の図はn=3のときのバインダーの様子を表しています。
// 各ポケットの数字はそのポケットで眺めることができる名刺の番号で、
// 括弧で表される数字はそのポケットを反対の面から見たときに眺めることができる名刺の番号です。
// 
// 名刺の番号mが与えられるので、その名刺の裏側の名刺の番号を表示するプログラムを作成してください。
// ただし、番号mの名刺の裏面には必ず名刺が存在するものとしてください。
function nameCard(lines) {
  // 入力は以下のフォーマットで与えられます。
  // n m

  // 入力チェック面倒くさいので正常系のみ対応するよ
  const [col, target] = lines[0].split(" ").map(v => Number(v));
  // 対象の数が見つかるまでループする力技
  let page = 1;
  let output = 0;
  rootLoop: while(true){
    // 1ページの表と裏を一気に求める
    const frontEnd = page * col;
    for(let i = 0;i < col; i++){
      const frontBack = [frontEnd - i, frontEnd + i + 1];
      if(frontBack[0] === target){
        output = frontBack[1];
        break rootLoop; 
      } else if(frontBack[1] === target){
        output = frontBack[0];
        break rootLoop; 
      }
    }
    // 1回のループで2ページ分の値を求めるため、2ページ進むようなループにする
    page += 2;
  }

  // m番の名刺の裏側の番号
  console.log(output);
}

module.exports = {
  nameCard
};

とりあえず分かる情報としては

  • 右側ページの最後は横の枚数 * ページで求められる
  • 上で求めた数字の裏側(左側ページ)は+1した数字
  • 右側ページは最後から-1していけば左に行く
  • 左側ページは上に比例して増えていく

ってことなので、1,3,5...奇数ページ(右側ページ)を求めれば、
必然的にその裏側となる偶数ページ(左側ページ)も分かるよねってことで、
指定の数字が見つかるまでループをぶん回すという力技で問題を解決!!

普段、頭の良さそうなIT屋のイメージを、
キレイサッパリ払拭するくらいの脳筋プレイでもどうにかなるので、
こんなレベルでもイケるんだと自信を持ってくれたら幸いです。

2
0
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
2
0