【JavaScript】3Dプリンタ (paizaランク B 相当) やってみたのと図で解説

これのやつです。

https://qiita.com/official-events/9ab96aa95d62fe3cbdd7

# 問題
https://paiza.jp/works/mondai/b_rank_skillcheck_archive/3d_printer

# 考え方
問題を見た時に「????」てなりませんでしたか？
自分はなりました。入力値がよく分からなかったです。
一緒に見ていきましょうか。

> ```
> <入力される値>
> 入力は以下のフォーマットで与えられます。
> X Y Z
> (1,1,1) (1,2,1) ... (1,Y,1)
> (2,1,1) (2,2,1) ... (2,Y,1)
> ...
> (X,1,1) (X,2,1) ... (X,Y,1)
> --
> (1,1,2) (1,2,2) ... (1,Y,2)
> (2,1,2) (2,2,2) ... (2,Y,2)
> ...
> (X,1,2) (X,2,2) ... (X,Y,2)
> --
> ...
> --
> (1,1,Z) (1,2,Z) ... (1,Y,Z)
> (2,1,Z) (2,2,Z) ... (2,Y,Z)
> ...
> (X,1,Z) (X,2,Z) ... (X,Y,Z)
> --
> ```

一行の「X Y Z」の数字は下記を表します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/b3a605c9-0362-ab95-81a8-256946d57f21.png" width=450>

「X Y Z」の次の行
>```
> (1,1,1) (1,2,1) ... (1,Y,1)
>```
がどこを表すか考えてみましょうか。

問題文の図から下記の部分に当たります。
![1111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/a53624e2-e71b-ea42-7d74-7f3aa7706b92.png)


そのまま見ていくと初めの部分は下記になります
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/d347c677-3d64-9c21-114d-15716db8d600.png" width=400> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/8ef741a0-d045-3c42-b8dc-8ed7630c1f90.png" width=400>

`--`で区切られている2個目の段落を見てみましょう

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/dabd9d7b-4b1e-e19a-186c-a1c3021af6ea.png" width=400> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/f25b289b-7c12-5a56-b158-f12991f9f549.png" width=400>

3Dプリンタのように下から層をなすように入力値が渡されているのがわかります。

内容のイメージが湧きましたら、これをX方向から見た時の形を考えてコードを書いていきます。



# 解答コード
```javascript
process.stdin.resume();
process.stdin.setEncoding('utf8');
// 自分の得意な言語で
// Let's チャレンジ！！
var lines = [];
var reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});
reader.on('line', (line) => {
  lines.push(line);
});
reader.on('close', () => {
  const [x, y, z] = lines[0].split(' ').map(item => Number(item));
  const result = new Array(z);
  
  let i = 1;
  for(let tempZ=0; tempZ<z; tempZ++){
      result[z - tempZ - 1] = new Array(y).fill('.');
      
      for(let tempX=0; tempX<x; tempX++){
          for(let tempY=0; tempY<y; tempY++){
              if(lines[i][tempY] === '#'){
                  result[z - tempZ - 1][tempY] = '#';
              }
          }
          i++;
      }
      i++;
  }
  result.map(item => console.log(item.join('')));
});
```

# 解説

実際に書いたところは`reader.on('close', () => {`以下のところです
```javascript
  const [x, y, z] = lines[0].split(' ').map(item => Number(item));
  const result = new Array(z);
  
  let i = 1;
  for(let tempZ=0; tempZ<z; tempZ++){
      result[z - tempZ - 1] = new Array(y).fill('.');
      
      for(let tempX=0; tempX<x; tempX++){
          for(let tempY=0; tempY<y; tempY++){
              if(lines[i][tempY] === '#'){
                  result[z - tempZ - 1][tempY] = '#';
              }
          }
          i++;
      }
      i++;
  }
  result.map(item => console.log(item.join('')));
```

コメントを書くと下記になります
```javascript
  // 入力値 x y z を取得しています
  const [x, y, z] = lines[0].split(' ').map(item => Number(item));

  // 結果の配列を入れる変数を定義しています
  const result = new Array(z);
  
  let i = 1; // iは入力値のラインの行です
  for(let tempZ=0; tempZ<z; tempZ++){
      // 下から1層目、二層目...と対応する結果配列の初期値を定義しています
      result[z - tempZ - 1] = new Array(y).fill('.');
      
      for(let tempX=0; tempX<x; tempX++){
          for(let tempY=0; tempY<y; tempY++){
              
              // 1個でも'#'があれば結果は'#'になります 
              if(lines[i][tempY] === '#'){
                  result[z - tempZ - 1][tempY] = '#';
              }
          }
          i++; // 次の行に移ります
      }
      i++; // 「---」の行を飛ばしています
  }

  // 結果の出力です
  result.map(item => console.log(item.join('')));
```

考え方として下記の考え方をしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435274/9afc9d03-3585-7b3d-40d9-c17240b471f8.png" width=400>


# 感想
読んでいただきありがとうございます！