atCoderやpaizaの問題をClojureで解くために read-line を再現する

2023-08-24

ときどき、4Clojureをやっているけど、たまに他のサイトをつかってみようと思って、Clojureが使えるAtCoderpaiza の問題もやってみました。

基本的な内容は、read-lineで文字列を読み込んで、加工や計算をして、printlnで出力するというもの。

AtCoderにもpaizaにも オンライン実行環境があり、入力データを設定できるので簡単に read-line を使えます。他の言語なら、これで十分かと思いますが、カッコが命のClojure ではParEditができないので使いにくいです。

しかし、vscodeでread-lineを使うと、呼び出しごとに入力フォームが表示され、そこに一行ずつ入力しないといけないので、めんどうです。

なので、 擬似的に read-lineの動きをする関数を作ってみました。

①atom に 入力文字列が入ったキューを設定

②キューの先頭の値を返し

③atom を、先頭を除いたキューで更新。

(defn make-input [lines]
  (let [s  (->> lines
                (clojure.string/split-lines)
                (map #(clojure.string/trim %)))
        q (atom (into clojure.lang.PersistentQueue/EMPTY s))] ①
    (fn []
      (let [r (peek @q)]   ②
        (swap! q pop)    ③
        r))))

(def read-line (make-input "1 2
                            abc
                            def"))

(read-line)  ;=> "1 2"
(read-line)  ;=> "abc"
(read-line)  ;=> "def"
(read-line)  ;=> nil

(def read-line (make-input "1 2 3
                            4 5 6
                            xyz"))
(read-line)  ;=> "1 2 3"
(read-line)  ;=> "4 5 6"
(read-line)  ;=> "xyz"
(read-line)  ;=> nil