LoginSignup
3
6

More than 3 years have passed since last update.

【都度更新】JavaScriptでPaizaランクCあたりを解いた際の気づきというか学び。

Last updated at Posted at 2020-09-15

Paizaの問題はさらけ出せないので、テクニックだけメモする記事。
イメージ、DからBに上がるときに必要な事項たち。

意外とド初心者向けに優しく書いた文章って無いなとおもっていて(そして大抵の文章は間違ってることが何故か多い)記事まとめています。

短く書く

For文ではなくforEach

For文で書くとこうなる
for.js

let arr[12,13,5,16,27];

function OutputFunc (){
    for ( i=0 ; i< arr.length ; i++){
         console.log(arr[i]);
     }
}

OutputFunc();
// 12
// 13
// 5
// 16
// 27

解説→ 配列arr[12,13,5,16,27]をconsole.logする処理を考えたとき、
For文で配列[i]を1つ1つ増やしていき、console.logを都度処理しても正解が得られる
一方で。

Foreachとアロー関数で一行で書ける
arrow.js

let arr[12,13,5,16,27];
arr.forEach( i => console.log(i) );

JavaScriptの関数アップデートしておく(es6)

map、forEach

配列を自動で操作する便利なやつら

slice

正規表現

RegExpオブジェクトを使うことで、正規表現の検索文字列自体を変える操作ができるとBに手が届く

split

標準入力の操作に使う
splitの第2引数は多めに入れてもエラーでないため、

arr.split(" ", 10);

スニペット登録しておくのがマスト

三項演算子

アロー関数

indexOf,includeあたりの「含まれてるかチェック」

forEach + 三項演算子 + アロー関数のあわせ技

コードそのままは記載できないので以下の問題
https://paiza.jp/challenges/share/C4EBWdpB9NcDKMRksBEGKApw-n1S2FgnjqtFEQ5Fpts

(注意※ 解答時間: 1652分27秒となっとるのは解き忘れでございます。)

当選番号.js

  const k = 4; //くじの数
  let kuji_numbers = [];
  let counter = 0; 

  //とあるくじの6つの数字をそれぞれ当選番号と照らし合わせる

  //合致した数を返す関数
  const addCounterIfMatched = elm => ( tousenNumbers.includes(elm) ) ? counter++ : "";

  //意味は、引数が、当選番号配列の中にあったら、counterという変数に1足すという意味


  //んで以下と組み合わせる。ここも簡略化できそう。
  for ( let i = 2 ; i <= k + 1 ; i++ ){
      kuji_numbers = lines[i].split(" ",10);
    //   console.log( kuji_numbers);
      kuji_numbers.forEach ( addCounterIfMatched ); //forEach + 三項演算子 + アロー関数
      console.log(counter);
      counter = 0 ;
  }

アルゴリズムやコンピュータサイエンス系の知識

2の累乗判定

普通に「アウトプットが1になるまで2で割って余りがゼロです」みたいなことやろうと思ったんだけど.
実は toString で2進数に変更すると アンド演算子で結果ゼロになるのが2,4,8,16...であるという.
うおーJavaScriptで2進数扱えるのは面白い,興奮した.
詳しい解説 https://kenyu-life.com/2019/01/15/n_ampersamd_n-1equal0/

お作法的な話

こまめに検証しながら進める

なんとなーく、Forを使いすぎずに外に出す感覚がわかってきた(Forで一般化すると考えることが一気に増えるのでまずは特殊条件として限定していいので、1つのパターンのみやってみて、思った通りの動きをするならForやforEachやmapで一般化する)

constとvarとletを使い分ける

おもった以上に const をつかうポイントが多い事に驚いた。
大規模開発したことがないとconstの恩恵には気づけないかも?
→ 定数(変わらないパイプライン)なら、ガンガンconstを使っていく。

関連する変数はオブジェクトでまとめておく

PuttingTogether.js
    const result = {
     numberOfstocks: 0,
        amount: 0
    }

変数をオブジェクトのプロパティとして参照したい時は
result[変数名]
で参照できる

落とし穴系

数字化処理を忘れない事。Number()

intとstrの区別する癖つけること。
str配列から数字を取り出したいときにはナンバーズ処理をかける
strで処理した場合、 10+2=102 となってよくFor文が102回まわる。
丸一日分くらいここでハマった。

CannotReadPro_inForloop.js

  for (let i = 2 ; i <= k + 1 ; i++ ){
    let arr = lines[i].split(" ",10); 
    //TypeError: Cannot read property 'split' of undefined
    //原因 → kが Number 処理されておらず、文字列として31が処理された。
    //       つまり存在しないlines[i]まで見に行っていて「んなもんねーぞ!」となっていた

「合っている筈」のとき

intがオーバーフローしている可能性がある.特にAtCoder

オーバーフローせずに

int型は20億(2 * 10^9)くらいまでと覚えておき、それより大きな値が出てきそうであればint64_t型を使うようにしましょう。

数字に int.length は使わない(使えない,そしてやはり使わない)

  • 数値にlengthを使用した場合、undefinedが返る.

    • よく考えてみれば当たり前の話.
    • 10進数なら10以上ということがつまり2桁,100以上で3桁だ.
  • プログラマーなら可能な限り数値を使おうという話でもあるように思う.

    • ブール演算しなくても変換しなくても処理できるのだ
    • 10進数⇔2進数のみで処理できる

実践

2020/09/02

https://paiza.jp/challenges/share/BJFopRlbQEBkCR9IL40ySi3JTT5QLM2WTZ61hKCyTVA
https://paiza.jp/challenges/share/leL8Ou5jkaG4yBDTNvRiORACUFzr2conkxmYZffr6Vc?source=social 2問間違い。関数化していくつかの数でテストすべき

2020/09/06

https://qiita.com/may88seiji/items/54cd61f8842bdffd5867
split()で文字列を分割//["h", "e", "l", "l", "o"]
reverse()で逆に並べる。//["o", "l", "l", "e", "h"]
join("")で一緒にする。//olleh

速度判定こちらに詳しい→ https://mindcat.hatenadiary.org/entry/20110821/1313946427

2020/09/12

ゾロ目の判定
JavaScriptなら正規表現を使う
正規表現でゾロ目は

ゾロ目の正規表現.js
/^(\d)\1+$/g

記事の補足

競技プログラミングのお供になる書籍

https://amzn.to/31RfBcA
プログラミングコンテストチャレンジブック [第2版] ~問題解決のアルゴリズム活用力とコーディングテクニックを鍛える~

https://amzn.to/2YXfyKe
プログラミングコンテスト攻略のためのアルゴリズムとデータ構造

PaizaのAランクとくと、競技プログラミングには2つの力があるのかなと。

  • 思考力(思考上の、算数的な)
  • 実装力(コード上の、言語的な)

んでこの記事のは、どちらかというと実装力の方で、レベルとしてはJavaScript初心者から中級者になろうみたいな感じ

リーダブルコード
https://amzn.to/332Sr23

レベル感(2020/08/27)

記事を参考にしたい人向けに、私がどれくらいのレベル感かというのを書いておきます:

  • レーティング
    • レーティングだけ気にして1500
    • 変数の命名やら気にすると1450
    • 関数創り分けなどしてると1400

問題ランク別のレベル感

  • PaizaランクD ◎
    • 時間に余裕を持って書けるが、アロー関数使ったり、forEach周りの関数使い分けるなど、気の利いた実装はできない。
  • PaizaランクC ○
    • コードが冗長になるがロジックも実装方法も分かる
  • PaizaランクB △
    • 時間かければ解けるがコンポーネント化やテスト切り分けが下手なのでハマると10時間かかる
  • PaizaランクA ✗
    • アルゴリズムの実装方法、算数的なブレイクダウンはギリギリ分かる、実装方法不明(IFやFORや配列いじっているうちに何がなんだかわからなくなる。足掛け2日考え続けるが明らかに実装力と糖分不足で死ぬレベル)

意外とド初心者向けに優しく書いた文章って無いなとおもっていて(そして大抵の文章は間違ってることが何故か多い)記事まとめています。

wakarann


//変数定義
    const [ a  , originalstr , targetstr ] = lines[0].split(" ");
    const wordLength = Number(a);
    let   ans = 0 , flag = '';
    let nowstr = originalstr;

//関数定義
//先頭の文字を1文字消去して,消去した文字を最後尾にくっつける
    const rotationFunc = str => str.slice(1) + str.slice(0,1);
//一致したら真偽値返す関数
    // const judgeFunc = str => str ? true : false ;
//吐き出す関数
    const output = function(i){
        if ( i >= ( wordLength / 2 ) ) {
            console.log( wordLength - i); 

        }else{ console.log(i) }
    }
//実行
for ( i = 0 ; i < wordLength ; i++ ){
    targetstr === nowstr ? output(i) : '' ;
    if ( targetstr === nowstr ) {
        break;
    }
    nowstr = rotationFunc(nowstr); //ローテーションする
}



以上

3
6
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
3
6