0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「ひとりすごろく」を解くために : part2

0
Posted at

今回は paiza の「「ひとりすごろく」を解くために : part2」の問題に挑戦!


問題概要

■ サイコロについて

  • 6 面サイコロが 1 つ与えられる
  • 各面には 1〜6 の数字が 1 つずつ書かれている
  • ただし、数字の配置は通常のサイコロとは異なる
  • ゲーム開始時に、各面の数字配置が入力として与えられる

■ 面の ID(位置の定義)

  • サイコロの各面には以下の ID(位置名) がある
    • T : 上
    • B : 下
    • U : 手前
    • D : 奥
    • L : 左
    • R : 右

■ 初期状態

  • サイコロは以下の向きで置かれている
    • T の面が 上
    • U の面が 手前
  • 入力では
    T B U D L R の順で、各面に書かれている数字が与えられる

■ できる操作(回転)

  • サイコロを 90° 回転させることができる
  • 回転方向は以下の 4 種類
    • 手前
  • 必要であれば 複数回の回転を行ってよい

■ 求めるもの

  • 数字 1〜6 それぞれについて、
    その数字が書かれた面を上にするために必要な回転回数の最小値を求める
  • 出力は 6 行
    i 行目:数字 i を上にするための最小回転回数

■ 入力条件(制約)

  • T, B, U, D, L, R はすべて整数
  • 値はすべて 16
  • 重複なし(必ず 1〜6 がちょうど 1 回ずつ現れる)


入力例:

5 2 3 6 4 1

出力例:

1
2
1
1
0
1






✅OK例:

const rl = require('readline').createInterface({ input: process.stdin });

const lines = [];

rl.on('line', line => lines.push(line));

rl.on('close', () => {
    const [T, B, U, D, L, R] = lines[0].split(' ').map(Number);

    for (let i = 1; i <= 6; i++) {
        if (i === T) {
            console.log(0);
        } else if (i === B) {
            console.log(2);
        } else {
            console.log(1);
        }
    }
});

🔍コードの流れ

  1. 入力を受け取る
    • 1 行目から
      T, B, U, D, L, R を読み込む
    • 初期状態で各 ID の面に書かれている数字を表す
  2. 裏面の対応を記録する配列を作る
    • opposite[i]
      「数字 i が上に来たとき、その裏にある数字」として使う
    • サイコロは必ず「面と裏面」がペアになるため、
    • TB
    • UD
    • LR
      を相互に登録する
  3. 1〜6 の数字について順番に調べる
    • i = 1, 2, …, 6 のループを回す
    • 「数字 i が書かれた面を上にするには何回転必要か」を考える
  4. 回転回数を条件分岐で判定する
    (1) iT と同じ場合
    • すでに上を向いている
    • 回転は不要
    • 0 を出力
      (2) iT の裏面(opposite[T])の場合
    • 上の面の真裏にある
    • 最小でも 2 回転が必要
    • 2 を出力
      (3) それ以外の場合
    • 側面(U, D, L, R のいずれか)
    • どの方向にも 1 回転すれば上にできる
    • 1 を出力




✅OK例 2:

const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on('line', line => {
    const num = line.split(' ').map(Number);

    // num[0] = T, num[1] = B(Tの裏)
    const opposite = num[1];

    for (let i = 1; i <= 6; i++) {
        if (i === num[0]) {
            console.log(0);
        } else if (i === opposite) {
            console.log(2);
        } else {
            console.log(1);
        }
    }

    rl.close();
});






📝まとめ

  • 回転方向は自由なので 常に最小回数を選べる
  • 初めから上の面は 0 回、その裏面は必ず 2 回
  • それ以外は 1 回
  • その判定を、opposite[T] を使って明確にしている。
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?