LoginSignup
1
0

More than 1 year has passed since last update.

paizaラーニング レベルアップ問題集Aランクレベルアップメニュー JavaScript マップの判定・縦

Last updated at Posted at 2022-09-20

マップの判定・縦 (paizaランク C 相当)

JavaScriptで解いてみました。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map(Number);
//盤面
const board = lines.slice(1).map(line => line.split(""));

//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
    //x座標、列について
    for (let j = 0; j < W; j++) {

        //上端のマスの場合は「下のマスが '#'」であれば
        if (i === 0 && board[1][j] === "#") {
            console.log(`${i} ${j}`);
        
        //下端のマスの場合は「上のマスが '#'」であれば
        } else if (i === H - 1 && board[H - 2][j] === "#") {
            console.log(`${i} ${j}`);
       
        //上下のマスがどちらも '#' であれば
        } else if (i !== 0 && 
                   i !== H - 1 && 
                   board[i - 1][j] === "#" &&
                   board[i + 1][j] === "#") {
            console.log(`${i} ${j}`);
        }
        
    } //for j
    
} //for i

解答例(列判定)

上下ではなく、列で調べました。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map((num) => Number(num));
//盤面
const board = [];
for (let i = 1; i <= H; i++) {
    board.push(lines[i]);
}

//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
    //x座標、列について
    for (let j = 0; j < W; j++) {
        
        //列が#か判定
        let colum = false;
        
        //上端のマスの場合は「下のマスが '#'」であれば
        if (i === 0 && board[1][j] === "#") {
            colum = true;
        }
        //下端のマスの場合は「上のマスが '#'」であれば
        if (i === H - 1 && board[H - 2][j] === "#") {
            colum = true;
        }
        
        //上下のマスがどちらも '#' であれば
        if (i !== 0 && 
                   i !== H - 1 && 
                   board[i - 1][j] === "#" &&
                   board[i + 1][j] === "#") {
            colum = true;
        }
        
        //左右上下全て#ならば
        if (row && colum) {
            console.log(`${i} ${j}`);
        }
        
    } //for j
    
} //for i

解答例(python3の場合の模範解答参考)

列で、上側・上端と下側・下端をまとめました。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map((num) => Number(num));
//盤面
const board = lines.slice(1).map(line => line.split(""));

//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
    //x座標、列について
    for (let j = 0; j < W; j++) {
        
        //列について#か判定
        let row = false;
                     
        //列について
        //上側、上端または"#"ならば
        if (i === 0 || board[i - 1][j] === "#") {
            //下側、下端または"#"ならば
            if (i === H - 1 || board[i + 1][j] === "#") {
                colum = true;
            }
        } 
        
        //上下全て#ならば
        if (colum) {
            console.log(i,j);
        }
        
    } //for j
    
} //for i

解答例(C++の場合の模範解答参考)

上下を調べるときに、移動の変化量である [-1,1] を配列 move で持つと、for文+if文1つにできます。
上下の全てで条件を満たすかどうかを判定するために 変数 ok を用います。
盤面内 かつ #でなかったときに、falseにします。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W
const [H,W] = lines[0].split(" ").map((num) => Number(num));
//盤面
const S = Array(H);
for (let i = 0; i < H; i++) {
    S[i] = lines[i + 1];
}
//移動の変化量move
let move = [-1, 1];

//盤面全てのマスについて調べる
//y座標、行について
for (let i = 0; i < H; i++) {
    //x座標、列について
    for (let j = 0; j < W; j++) {
        
        //上下の全てで条件を満たすかどうかを判定
        let ok = true;
        //kはmoveのインデックス,move[k] = -1 または 1
        for (let k = 0; k < 2; k++){
            
            //jは列方向について、move[k] = -1上 または 1下 移動した時
            //盤面内 かつ #でないなら ok=false
            if(0 <= j+move[k] && j+move[k] < W &&
             S[i][j+move[k]] !== '#'){
                ok = false;
                break;
            }
        }
        
        //上下全て#ならば
        if (ok) {
            console.log(i + " " + j);
        }
    } //for j
} //for i

解答例(Rubyの場合の模範解答参考)

forEachを使いました。
上下のマスの文字が # のとき flag_clm を true にします。
端の時は問題に従ってtrueになるようにしています。
flag_clm で上下の全てのマスの文字 # であるかを判定できます。

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 h , 盤面の列数を表す整数 w
const [h, w] = lines[0].split(" ").map((num) => Number(num));
//盤面
const board = lines.slice(1).map(line => line.split(""));

//盤面全てのマスについて調べる
//y座標、行rowについて
board.forEach((row, y) => {
    //x座標、列について
    row.forEach((_, x) => { //第一引数は使わないので_にしています。
        let flag_row = false;
        let flag_clm = false;
        
        //上下のマスの文字が # のとき flag_clm を true にします。
        ////端の時は問題に従ってtrueになるようにしています。
        if (y === 0 || board[y - 1][x] === '#') {
          if (y === h - 1 || board[y + 1][x] === '#') {
            flag_clm = true;
          }
        }
        /*flag_clm で上下左の全てのマスの文字が # であるかを判定できます。*/
        if (flag_row && flag_clm) {
          console.log(y + ' ' + x);
        }    
    }); //forEach _ x
}); //forEach row y
1
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
1
0