日記帳

プログラミングのことをつぶやく日記です。

競技プログラミングを解くときにsplitやchompを削ると実行時間が速くなる

今日、やっとAtCoder Beginners Selectionの問題を全部解き終えた。感想はACになったときにアドレナリンが出るということと、人の解法が勉強になるということだった。

すべての提出 - AtCoder Beginners Selection

だいたいこんな感じ、各問題の初回のACは実力で、2回目以降は他の人の解法を眺めながらやった。そこでコード量はたいして変わらないのに、実行時間が違うんだーということがあった。見つけたのはこの問題を解いているときであった。

ABC086C - Traveling

最初の僕のコードはこちら。

Submission #7131569 - AtCoder Beginners Selection

def init
  $n = $stdin.gets.chomp.split(" ").map(&:to_i)
  $line = %w()
  while line = gets
    $line.push(line.chomp.split(' ').map(&:to_i))
  end
end

init

def plan
  $line.each do |l|
    return if l[0] < l[1] + l[2] 
    return unless ((l[0] - (l[1] + l[2])) % 2).zero?
  end
  true
end

puts plan ? 'Yes' : 'No'

結構速い実行時間のでは?とか思っていたけど 210 ms で、あれ?意外と遅くない?とか思った。ただRubyに限定した話をすれば最速は 154 ms であった。(他人のコードなので、このブログには転載しない、またRuby言語以外だと20ms台の実行時間もあるので、Ruby自体がこの問題では僕が想像していた速いタイムにはならない。)

Submission #6047015 - AtCoder Beginners Selection

なるほどーgetsをしながらループをすれば読み込みと実際の処理を一緒にできて速くなるなーと思い真似してみた。すると 172 ms になり、速くはなったが150ms台にならない。なぜだろうと思った。

n = gets.chomp.to_i
n.times do
  t, x, y = gets.chomp.split(' ').map(&:to_i)
  distance = x + y
  if t < distance || (distance - t).odd?
    puts 'No'
    exit
  end
end

puts 'Yes'

見比べてみると、Ruby最速コードにはsplitは引数を与えないと空白文字で分割してくれる。早速試してみるとわずかだが速くなり170 ms になった。

split (String) - Rubyリファレンス

Submission #7132131 - AtCoder Beginners Selection

さらに見ていくとchompメソッドもない。あれ?改行マーク取り除かなくても大丈夫?と思ったがto_iでNumericに変換しているので改行マークは外れるようだ。chmodメソッドを削除してみると152 ms になり満足する結果になった。

Submission #7132148 - AtCoder Beginners Selection

n = gets.to_i
n.times do
  t, x, y = gets.split.map(&:to_i)
  distance = x + y
  if t < distance || (distance - t).odd?
    puts 'No'
    exit
  end
end

puts 'Yes'

なるほどーchmopsplitも何回も繰り返すと実行時間が延びるので、入力を読む時点で実行時間を気にして書けばいいのかーと勉強になった。結構前のコードのコピペになりやすいのでこういう発見ができてよかった。

MacからUbuntuに移行したときの作業メモ

leokun0210.hatenablog.com

MacからUbuntuに移行しようといろいろ試行錯誤している。最初の設定でやったことをまとめておく

USキーボードを使用できるようにして、altで英字/かなのトグルができるようにする

Ubuntu18.04 USキーボードで日本語切り替えをaltキーで行う - Qiita

Fcitxをインストールする。FcitxとはLinuxに環境非依存の言語サポートを提供するインプットメソッドフレームワークらしい。

Fcitx - ArchWiki

Fcitxをパッケージからインストールする。 im-config というのは、マニュアルを見る限り、X Window Systemのインプットメソッドの設定を行うツールと書いてある。 -n オプションはインプットメソッドネームを指定するオプション。完了したら一旦再起動、 sudo reboot でも再起動できる。

sudo apt install -y fcitx fcitx-mozc
sudo im-config -n fcitx

fcitx設定を開く。入力メソッドには最初から英字キーボードが認識されていた。アプリケーションから言語サポートを開いて、キーボード入力に使うIMシステムがfcitxになっていることを確認する。fcitx設定に戻って、全体の設定タブに切り替える。入力メソッドのオンオフで左右のaltのキーを割り当てる。

CapsLockをCtrlに割り当てる

Ubuntu 16.04 CapsLockをControlに置換する方法 - Qiita

マニュアルを見る限りキーボードの設定ファイルらしい。

マウスの速度調整

マウスとタッチパッドを開く。

プリンター

Windowsで設定したプリンターが引き継がれていた。

windows10とUbuntuのデュアルブート環境を作った

大学のテストが終わって時間ができたので、以前からやろうとしていたメインマシンをLinuxにしようと作業していた。その作業メモである。ディストリビューションは、楽に入るUbuntuにした。

参考にしたサイト

Windows 10でUbuntuのインストール用USBメモリを作成 | 普段使いのArch Linux

UbuntuとWindowsのDualboot環境を構築する | UnFlexFlex

Ubuntu Desktop 日本語 Remixのダウンロード | Ubuntu Japanese Team

起動ディスクの作成 - Ubuntu 18.04 LTS デスクトップガイド改

推奨するBIOSの入り方 - ThinkPad, ThinkCentre, ThinkStation - CO

作業環境

作業手順

Ubuntuの起動ディスクの作成

19.04を入れることにした。 Ubuntu Desktop 日本語 Remixのダウンロード | Ubuntu Japanese Team よりダウンロードする。そのあとRufusUSBメモリに記録する。選択でisoファイルを選択して、記録媒体を選択するといい感じに項目をセットしてくれる。FPT UEFIコンピュータ用のパーティション構成を選択して、ファイルシステムFAT32 にしておく。

UEFIを設定する

  • ThinkpadのF2キーを押して、 ThinkPad Setup を開く(F1でもいいらしいけど試していない)
  • Boot Priority Orderの順位をWindows Boot ManagerよりUSB HDDを上にする。

    Windows10側の作業

  • UbuntuとWindowsのDualboot環境を構築する | UnFlexFlex これ通りに作業した。

  • 高速スタートアップを無効にする
  • Windowsのドライブを縮小した。とりあえず20GBぐらい確保した。(今考えたら80GBぐらいでもよさそうだった。)

Ubuntuのインストール作業

再起動して、bootするOSを決める。

  • UbuntuのBoot menuがたちあがるので、UbuntuWindows、立ち上げたいOSを選択する。

感想

  • ちょっと最初の容量の割り当てをミスった感じがするので、もう一度インストール頑張ってみるかも
  • 所要時間は調べもの込みで5時間くらい。結構疲れた。
  • 本格的にUbuntuを使うには、まだまだいろいろソフトウェアを入れなければならないが、もうMacは高いので卒業する予定なので頑張る。

すでにLinuxイメージを焼いていたUSBメモリを初期化する

半年前にLinuxのイメージを焼いたUSBメモリを初期化しようと思ったが、Windowsエクスプローラに現れないので困った。

環境:Windows10

ここを参考にして解決した。

Linuxインストールに使ったUSBメモリを元に戻す(Windows10) - 名古屋のとなり

やったことは、コマンドプロンプトdiskpart を実行、すると別ウィンドウでディスク管理ツールのcliが開く。そこで以下のコマンドを実行した。

list disk
select disk [ディスク番号]
clean
create partition primary

これでフォーマットする前のUSBメモリになる。再び使用するためにはフォーマットすることになる。

中古のスマートランプを買ったら、Alexaとの連携で接続不良を起こした

ベッドにいながら電気を消したいと思い、このTP-LINKのスマートランプを中古で買った。

そしたらスマートランプとTP-LINKのマネージャーアプリ「kasa」とのリンクはうまくいくのだが、「kasa」とAmazonのアカウントを紐づけようとすると「このデバイスはすでに他のユーザーに紐づいています。」と表示されてAmazonアカウントとの連携ができない。スマートランプを初期化しても、kasaアプリから表示は消えるものの、再度接続設定をしても同じ結果になる。これはまさか初期化というのは、スマートデバイスのユニークIDとkasaのサーバーの紐づけデータは消さないのでは?と推測した。だから前の持ち主とランプが紐づいているのかも。なので中古のやつを返品して新品を買ってつないだら、普通にAmazonアカウントと紐づけすることができた。皆さんはスマートランプは新品で買いましょう。絶対中古に手を出してはいけません。