4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

回文基数 in Clojure

Last updated at Posted at 2014-05-23

問題と他の方の解答

問題: 回文基数 〜 横へな 2014.1.10 参考問題
他の方の解答: 第17回オフラインリアルタイムどう書くの参考問題

私の解答 in Clojure

(ns ord17ref
  (:require [clojure.test :refer (deftest are run-tests)]))

(defn- columns [b]
  (fn f [i]
    (if (zero? i) '()
      (cons (mod i b) (f (quot i b))))))

(defn solve [s]
  (let [i (read-string s)
        bs (for [b (range 2 i)
                 :let [cs ((columns b) i)]
                 :when (= cs (reverse cs))]
               b)]
    (if (empty? bs) "-" (apply str (interpose "," bs)))))

(deftest solve-test
  (are [i o] (= (solve i) o)
    "17301" "5,38,100,218,236,5766,17300"    
    "2" "-"    
    "1" "-"    
    "3" "2"    
    "4" "3"    
    "5" "2,4"    
    "6" "5"    
    "10" "3,4,9"    
    "101" "10,100"    
    "1001" "10,25,76,90,142,1000"    
    "10001" "10,24,30,42,80,100,136,10000"    
    "1212" "22,100,201,302,403,605,1211"    
    "123412" "62,100,205,215,30852,61705,123411"    
    "5179" "5178"    
    "4919" "4918"    
    "5791" "5790"    
    "5498" "2748,5497"    
    "453" "150,452"    
    "134" "66,133"    
    "8489" "27,652,8488"    
    "1234" "22,616,1233"    
    "5497" "41,238,5496"    
    "4763" "19,35,432,4762"    
    "3974" "17,27,1986,3973"    
    "3521" "44,55,502,3520"    
    "5513" "20,38,53,148,5512"    
    "8042" "23,29,60,4020,8041"    
    "7442" "37,60,121,3720,7441"    
    "4857" "25,1618,4856"    
    "22843" "49,69,91,141,430,22842"    
    "194823" "84,121,21646,64940,194822"    
    "435697" "160,169,235,626,1822,435696"    
    "142" "3,7,70,141"    
    "886" "5,14,442,885"    
    "3102" "7,65,93,140,281,516,1033,1550,3101"    
    "17326" "11,28,99,105,8662,17325"    
    "32982" "13,72,238,477,716,1433,5496,10993,16490,32981"    
    "36" "5,8,11,17,35"    
    "37" "6,36"    
    "251" "8,250"    
    "252" "5,10,17,20,27,35,41,62,83,125,251"    
    "253" "12,14,22,252"    
    "6643" "2,3,9,81,90,510,948,6642"    
    "5040" "71,79,83,89,104,111,119,125,139,143,167,179,209,239,251,279,314,335,359,419,503,559,629,719,839,1007,1259,1679,2519,5039"    
    "9240" "23,38,62,104,109,119,131,139,153,164,167,209,219,230,263,279,307,329,384,419,439,461,615,659,769,839,923,1154,1319,1539,1847,2309,3079,4619,9239"))

テスト実行結果

Clojure 1.6.0
user=> (ns ord17ref)
nil
ord17ref=> (require 'ord17ref :reload-all)
nil
ord17ref=> (run-tests)

Testing ord17ref

Ran 1 tests containing 45 assertions.
0 failures, 0 errors.
{:type :summary, :fail 0, :error 0, :pass 45, :test 1}

解説

(defn- columns [b]
  (fn f [i]
    (if (zero? i) '()
      (cons (mod i b) (f (quot i b))))))

columns は, 基数 b を与えると「整数 i を与えると, i を基数 b で表した場合の, 各桁の数値をシーケンスで返す関数」を返します.

関数 f は, 数値 i を与えると「ib で割った商を, 自身 f に与えて得られるシーケンス」の先頭に「ib で割った余り」を付加します. i が 0 の時は空リストを返します.
これで基数 b の場合の各桁を下位から並べたシーケンスが得られます.

利用例です.

ord17ref=> ((columns 2) 10)
(0 1 0 1)
ord17ref=> ((columns 3) 10)
(1 0 1)
ord17ref=> ((columns 4) 10)
(2 2)
ord17ref=> ((columns 5) 10)
(0 2)

(defn solve [s]
  (let [i (read-string s)
        bs (for [b (range 2 i)
                 :let [cs ((columns b) i)]
                 :when (= cs (reverse cs))]
               b)]
    (if (empty? bs) "-" (apply str (interpose "," bs)))))

文字列で与えられた数字列 s(read-string ...) で数値にし, i とします.
基数 b を 2 から i - 1 の範囲で変化させ, その場合の i の各桁を下位から並べたシーケンスを cs とします.
cs(reverse cs) が一致する場合は, 基数 b を抽出します.
抽出した基数のシーケンスを bs とします.
bs が空なら "-" を返し, そうでなければ, (interpose "," ...)"," を間に挟んで,
(apply str ...) で文字列化します.

各部分は以下の例のように機能します.

ord17ref=> (read-string "17301")
17301

ord17ref=> (for [b (range 2 17301) :let [cs ((columns b) 17301)] :when (= cs (reverse cs))] b)
(5 38 100 218 236 5766 17300)

ord17ref=> (interpose "," '(5 38 100 218 236 5766 17300))
(5 "," 38 "," 100 "," 218 "," 236 "," 5766 "," 17300)

ord17ref=> (apply str '(5 "," 38 "," 100 "," 218 "," 236 "," 5766 "," 17300))
"5,38,100,218,236,5766,17300"
4
4
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
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?