2022/11/30

お知らせ

~マイナビエンジニアからの挑戦状 vol.4~の解説を公開します!

この記事の目次

    概要

    こんにちは!AIシステム部のS.KとO.Tです。

    競プロが趣味の私たちが作成した、オリジナル問題をクリアされた方には、開発エンジニア向けのインターンシップに招待させていただく企画を開催しました。

    たくさんのご回答ありがとうございました!!
    11/24をもちまして、回答受付は締め切らせていただきました。
    本記事では、解説を載せていきたいと思います。

    問1:暗号解読

    次の問いに答えよ。
    ※回答は日本語でお願いします

    ZlexaDwxlirePisjsyvgRqtDrcalHrmWaDwjsXQhih?

    解読ヒント:

    • Pcrezm → Mynavi
    • mSlsri → iPhone
    • Drhvsmh → Android

    問題1の解説

    シーザー暗号を使った暗号文になっている。
    ヒントを見ると、

    • 大文字は3つ前のアルファベット
    • 小文字は4つ前のアルファベット

    に戻す処理を行えばいいことが分かる。

    • 最初の文を複合すると…

    「WhatwAsthenaMeofourcOmpAnywhEniTwAsfoUNded?」

    • 全て小文字にすると…
      「whatwasthenameofourcompanywhenitwasfounded?」
    • 単語で区切ると…
      「what was the name of our company when it was founded?」
    • 和訳すると…
      「我々の会社の創業した時の名前はなんでしょう?」

    答え:「毎日コミュニケーションズ」「株式会社毎日コミュニケーションズ」など

    問題作者からのコメント

    正解は「毎日コミュニケーションズ」です。※「株式会社」が入っていても正解です
    マイナビは、元々は毎日新聞社の関連会社として設立されました!現在も本社が毎日新聞社と同じパレスサイドにあるほか、健康保険組合なども同じです。

    マイナビの歴史はこちら

    問2:虫食いパズル

    まいなび君は宿題で4桁×4桁の筆算に取り組んでいた。
    しかし、宿題の途中でノートに飲み物をこぼしてしまい、ほとんどの数字が分からなくなってしまった。残った数字から、元の筆算で何を計算していたのかを特定したい。
    筆算が成り立つように以下の空欄に0~9の数字を入れて、

    「①②③④⑤⑥⑦⑧」に当てはまる数字を答えよ。

    問題2の解説

    この筆算がxとyの積を求めている問題であるとして、全ての条件を満たすようなxとyを全探索により求めることができる。空白となっている桁は合計で5桁であり、書き込む数字の候補は0~9の10通りであるから、この問題は長くとも$\mathcal{O}(10^5)$時間で解くことができる。

    そしてxとyが満たすべき条件は以下である。

    • 「x」と「yの一の位」の積における、「百の位」が2である。
    • 「x」と「yの十の位」の積における、「千の位」が4である。
    • 「x」と「yの千の位」の積における、「一の位」が5である。
    • 「x」と「y」の積における、「十の位」が9であり、「百万の位」が8である。

    条件を満たすxとyは15475236であり、下図の通りに数字を書き込むと式が成り立つ。

    クイズの答えは「19730815」である。

    ※追記:これは「株式会社毎日コミュニケーションズ」が設立された年月日である。

    サンプルコード

    各桁ごとに全探索を記述するとコードが分かりにくくなると考え、xとyをそれぞれ1000から9999の間で全探索することとした。これでも$\mathcal{O}(10^8)$時間で済むことから、それほど多くの計算時間はかからない。

    def one_digit(x):
        return x % 10
    
    def ten_digit(x):
        y = x // 10
        return y % 10
    
    def hundred_digit(x):
        y = x // 100
        return y % 10
    
    def thousand_digit(x):
        y = x // 1000
        return y % 10
    
    def milion_digit(x):
        y = x // 1000000
        return y % 10
    
    for x in range(1000,10000):
        if ten_digit(x) != 4:
            continue
        for y in range(1000,10000):
            if hundred_digit(y) != 2:
                continue
            if one_digit(y) != 6:
                continue
            xy1 = x * one_digit(y)
            xy10 = x * ten_digit(y)
            xy100 = x * hundred_digit(y)
            xy1000 = x * thousand_digit(y)
    
            if hundred_digit(xy1) != 2:
                continue
            if thousand_digit(xy10) != 4:
                continue
            if one_digit(xy1000) != 5:
                continue
            ans = x * y
            # print(ans)
            if milion_digit(ans) != 8:
                continue
            if ten_digit(ans) != 9:
                continue
            print(x,y,xy1,xy10,xy100,xy1000,ans)
    
            # 出力:1547 5236 9282 4641 3094 7735 8100092

    問題作者からのコメント

    正解は「19730815」です。
    マイナビの創業は1973年8月15日です。皆さまのお陰で50年の間、安定して事業を続けることができました!これからも期待に応え続けるよう頑張っていきたいと思います。

    マイナビの歴史はこちら

    ※本記事は2022年11月時点の情報です。

    著者:マイナビエンジニアブログ編集部