みちのいに!!

自分のメモと、他にもハマる人がいそうなことを書く

Nimをnodejsにコンパイルして競技プログラミングした

こんにちは 最近Nimで競技プログラミングをすることにハマっています.

準備

Nimとは?

プログラミング言語です.Pythonライクな文法で気軽に書けます.C言語を介してバイナリを吐くので実行時間はとても早いです.JavaScriptも吐くことができます.

競技プログラミングとは?

問題をプログラミングで解くコンテストです.国内のコンテストサイトには Atcoder, Aizu Online Judge(AOJ), yukicoder, paizaなどがあります.

背景

  • AOJを解こうとしたらNimが使えなかった.
    • ちなみにAtcoderとyukicoderでは使えます.
  • どうしてもNimで書きたかった.
  • Nimの良さの一つは早いことだがこの際仕方ない.JavaScriptで吐いて提出しよう.

解説

普通に解いてコンパイルして投げるだけと思いきや,JavaScriptに吐くときはstdinが使えません.この点だけ注意します.

AOJ 1000 A + B Problem を例に解説します.問題自体は足すだけです.

1.普通にNimで解く

普通に解きます. ただし,NimのstdinはCのstdio.h由来であるため,JSにコンパイルするときは利用できません.そこで,以下のように入力を受け取るmain函数を作ります. mainの引数には適当にテスト用の文字列でも埋め込んでください.

import strutils, sequtils

proc main(inputLines:string): void=
  var 
    input = inputLines.split('\n')
  for line in input:
    var 
      tmp = line.split.map(parseInt)
      a = tmp[0]
      b = tmp[1]
    echo a+b

main("4 6\n3 1\n2 1")

2. JavaScriptコンパイルする

$ nim js -d:nodejs -o:aoj1000.js aoj1000.nim

aoj1000.jsが出力されます.

3. JavaScriptのファイルを編集する

ファイルを開くとやたら長いコードが出てきますが,一番下までスクロールします. すると,

main_53001(makeNimstrLit("4 6\x0A3 1\x0A2 1"));

という部分が一番下にあります.

この部分を標準入力を読み込むように改変します.

ここでは,http://koturn.hatenablog.com/entry/2016/02/04/050000 を参考にしました.

(function() {
  'use strict';
 
  var lines = [];
  require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
  }).on('line', function(line) {
    lines.push(line);
  });
  process.stdin.on('end', function() {
    main_53001(makeNimstrLit(lines.join("\x0A")));
  });
})();

4 完成

完成です.ファイルを全部コピーして提出します.

http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2961239#1