2012-07-17 20 views
5

मैं docjure का उपयोग कर रहा हूं और इसे अपने चयन-कॉलम फ़ंक्शन के लिए कॉलम मानचित्र की आवश्यकता है। मैं अपने सभी कॉलम मैन्युअल रूप से निर्दिष्ट किए बिना पकड़ना चाहता हूं। मैं आलसी अनंत वेक्टर अनुक्रम के रूप में निम्नलिखित कैसे उत्पन्न करूं [: ए: बी: सी: डी: ई ...: एए: एबी: एसी ....: जेडजेड ...: एक्सएफडी]?समझ के लिए क्लोजर उदाहरण

+1

वैक्टर हालांकि आलसी नहीं हैं। – Gert

+0

क्या इसे 3 पर रोकना है या यह हमेशा के लिए जारी रह सकता है? –

+0

@Gert यह एक वेक्टर होने की जरूरत नहीं है। – KobbyPemson

उत्तर

6

आपका प्रश्न करने पर निर्भर करता: "कैसे मैं एक आधार पर किसी संख्या परिवर्तित -26 स्ट्रिंग वर्णमाला AZ के साथ? "।

ऐसा करने का एक तरीका यहां है - शायद सबसे संक्षिप्त तरीका नहीं है, लेकिन इसे और अधिक सुरुचिपूर्ण बनाने के लिए पाठक के लिए अभ्यास के रूप में छोड़ा गया है :)।

मान लें कि संख्या 0-25 मानचित्र 'ए' - 'जेड', 26 मानचित्र 'एए', इत्यादि। सबसे पहले हम एक फ़ंक्शन to-col परिभाषित करते हैं जो एक पूर्णांक को कॉलम कीवर्ड में परिवर्तित करता है। आप एक अनंत अनुक्रम उत्पन्न करने के लिए उस फ़ंक्शन का उपयोग कर सकते हैं।

(defn to-col [num] 
    (loop [n num s()] 
    (if (> n 25) 
     (let [r (mod n 26)] 
     (recur (dec (/ (- n r) 26)) (cons (char (+ 65 r)) s))) 
     (keyword (apply str (cons (char (+ 65 n)) s)))))) 

है कि आप एक तरह से कॉलम में उन कीवर्ड की एक अनंत अनुक्रम उत्पन्न करने के लिए देता है:

(take 100 (map to-col (range))) 
;; => (:A :B :C :D :E :F :G :H :I :J :K :L :M :N :O :P :Q :R :S :T :U :V :W 
;; :X :Y :Z :AA :AB :AC :AD :AE :AF :AG :AH :AI :AJ :AK :AL :AM :AN :AO :AP 
;; :AQ :AR :AS :AT :AU :AV :AW :AX :AY :AZ :BA :BB :BC :BD :BE :BF :BG :BH 
;; :BI :BJ :BK :BL :BM :BN :BO :BP :BQ :BR :BS :BT :BU :BV :BW :BX :BY :BZ 
;; :CA :CB :CC :CD :CE :CF :CG :CH :CI :CJ :CK :CL :CM :CN :CO :CP :CQ :CR 
;; :CS :CT :CU :CV) 
+0

यह समाधान आलसी नहीं है। –

0

शायद वहाँ दोहराव "के लिए" को दूर करने के लिए एक रास्ता है, लेकिन यहाँ कुछ है कि मेरे लिए काम करता है:

(def all-letters (map char (range 65 90))) 
(defn kw [& args] (keyword (apply str args))) 
(concat 
    (for [l all-letters] (kw l)) 
    (for [l all-letters l2 all-letters] (kw l l2)) 
    (for [l all-letters l2 all-letters l3 all-letters] (kw l l2 l3))) 
+0

(नक्शा चार (रेंज 65 9 0) पर्याप्त होता है) अक्षर \ A से \ Y उत्पन्न करता है, और आपका समाधान अनंत नहीं है। – Gert

2

यह जवाब गलत है; उम्मीद है कि एक शैक्षणिक तरीके से।

गणितीय रूप से आप जो पूछ रहे हैं वह वर्णमाला के अनंत अनुक्रम के सभी सबसेट का आलसी अनुक्रम है।

(take 40 (map #(keyword (apply str %)) 
      (rest (combinatorics/subsets "ABCDEFGHIJKLMNOPQRSTUVWXYZ")))) 
(:A :B :C :D :E :F :G :H :I :J :K :L :M :N 
:O :P :Q :R :S :T :U :V :W :X :Y :Z :AB :AC 
:AD :AE :AF :AG :AH :AI :AJ :AK :AL :AM :AN :AO) 

foo.core> (nth (map #(keyword (apply str %)) 
       (rest (combinatorics/subsets "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) 
       40000) 
:BLOUZ 

project.clj:

(defproject foo "1.0.0-SNAPSHOT" 
    :description "FIXME: write description" 
    :dependencies [[org.clojure/clojure "1.3.0"] 
       [ org.clojure/math.combinatorics "0.0.3"]] 
    :dev-dependencies [[swank-clojure/swank-clojure "1.4.0"]]) ; swank) 

का उपयोग कर math.combanatorics:

(ns foo.core 
    (:require [clojure.math.combinatorics :as combinatorics])) 
+0

(बाकी ...) यह खाली सबसेट को हटाने के लिए है जिसे हम –

+0

पर ध्यान नहीं देते हैं, अस्थिर पाठक यह नोटिस करेगा कि यह अनुक्रम वास्तव में अनंत नहीं है ... ;-) लेकिन सूर्य पहले जला देगा। –

+0

ओह, यह गलत है, यह उल्टी है: एए, चलो देखते हैं कि इसे –

1

मैं इस बात की तरह आप (यदि नहीं, ठीक है, देख रहे थे पर हो सकता है लगता है कम से कम यह है कि मैंने सोचा कि "सही" जवाब होना चाहिए; ओ)।

(defn stream [seed] 
    (defn helper [slow] 
    (concat (map #(str (first slow) %) seed) (lazy-seq (helper (rest slow))))) 
    (declare delayed) 
    (let [slow (cons "" (lazy-seq delayed))] 
    (def delayed (helper slow)) 
    delayed)) 

(take 25 (stream ["a" "b" "c"])) 
("a" "b" "c" "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc" "aaa" "aab" "aac" "aba" "abb" "abc" "aca" "acb" "acc" "baa" "bab" "bac" "bba") 

Code in git। मुझे संदेह है कि मैं def का दुरुपयोग कर रहा हूं, लेकिन यह काम करता है।

विचार बहुत आसान है: मैं अनुक्रम से आउटपुट लेता हूं और इसे वापस खिलाता हूं। आउटपुट में प्रत्येक मान के लिए (जो इनपुट भी है), मैं बीज अनुक्रम में प्रत्येक अक्षर को जोड़कर एक नया आउटपुट उत्पन्न करता हूं। चूंकि यह परिपत्र है, यह अभी भी जारी रहता है (इनपुट प्रारंभिक "है जो इनपुट में है, लेकिन आउटपुट नहीं, जो कुछ भी नहीं बनाने से बचने में मदद करता है)।

इनपुट में आउटपुट को खिलाने की प्रक्रिया को हास्केल के लिए एक प्रसिद्ध मशहूर पेपर में "गाँठ बांधना" कहा जाता है। लेकिन क्लोजर में करना मुश्किल है क्योंकि यह एक उत्सुक भाषा है (और यहां तक ​​कि आलसी अनुक्रम "आलसी पर्याप्त" नहीं हैं) - मुझे लगता है कि एकमात्र समाधान def के साथ गड़बड़ था (मुझे संदेह है कि कोई delay और force के साथ बेहतर कर सकता है, लेकिन मुझे कोई भाग्य नहीं था)।

और शायद इसे मानचित्र के रूप में भी लिखा जा सकता है?

Tying the knot in Clojure: circular references without (explicit, ugly) mutation? पर एक जवाब (यह jneira के जवाब के रूप में ही विचार है) में

संबंधित प्रश्न [अधिक कॉम्पैक्ट कोड के साथ 2012-07-19 अद्यतन] काफी बेहतर कोड के साथ।

पूर्णता के लिए, यहाँ का उपयोग कर अंतिम संस्करण है iterate:

(defn stream [seed] 
    (defn helper [slow] (mapcat (fn [c] (map #(str c %) seed)) slow)) 
    (apply concat (iterate helper seed))) 
+0

क्लोजर में इसे फॉर्म डीफ़ का उपयोग करने और शीर्ष स्तर के अलावा कहीं भी डिफने के लिए बुरी शैली माना जाता है। धारा के अंदर कॉलिंग (असफ़ल सहायक ...) के साथ समस्या यह है कि यह एक अपरिवर्तनीय var को फिर से परिभाषित करने के पक्ष में प्रभाव डाल रहा है। आपको सहायक के साथ परिभाषित करना चाहिए (चलो [सहायक [एफएन [धीमी] ...)] ...) या इसके बजाय letfn का उपयोग करें। –

4

corecursion के लिए आवश्यक clojure समारोह (? और "गांठ बांधने" इसके बारे में, कोई है) पुनरावृति है:

(def abc (map (comp str char) (range 65 91))) 
(defn cols [seed] 
    (let [next #(for [x %] (for [y seed] (str x y)))] 
    (->> (iterate #(apply concat (next %)) seed) 
     (mapcat identity)))) 

(time (first (drop 475254 (cols abc)))) 
"Elapsed time: 356.879148 msecs" 
"AAAAA" 

(doc iterate) 
------------------------- 
clojure.core/iterate 
([f x]) 
    Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects 

संपादित करें: फ़ंक्शन का सामान्यीकरण एक सेट के "आदेशित" सबसेट को वापस करने के लिए

(defn ordered-combinations [seed] 
    (->> (map list seed) 
     (iterate #(for [x % y seed] (concat x [y]))) 
     (mapcat identity))) 

(def cols 
    (let [abc (map char (range 65 91))] 
    (map #(apply str %) (ordered-combinations abc)))) 

user> (take 30 (map #(apply str %) cols)) 
("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "AA" "AB" "AC" "AD") 
user> (take 28 (ordered-combinations [0 1])) 
((0) (1) (0 0) (0 1) (1 0) (1 1) (0 0 0) (0 0 1) (0 1 0) (0 1 1) (1 0 0) (1 0 1) (1 1 0) (1 1 1) (0 0 0 0) (0 0 0 1) (0 0 1 0) (0 0 1 1) (0 1 0 0) (0 1 0 1) (0 1 1 0) (0 1 1 1) (1 0 0 0) (1 0 0 1) (1 0 1 0) (1 0 1 1) (1 1 0 0) (1 1 0 1)) 
-1
#include<stdio.h> 
int main() 
{ 
int n=703; 

char arr[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; 

while(n){ 
printf("%c ",arr[(n)%26]); 
n=(n)/26; 

} 
return 0; 
} 

लोग इस तरह के रूप में सरल हैं या मैं कुछ याद कर रहा हूं .... बेशक उपरोक्त प्रोग्राम रिवर्स में आवश्यक एंगिंग प्रिंट करता है, हम इसे रिकर्सन का उपयोग करके या इसे उलटने के लिए स्ट्रिंग में स्टोर करके बच सकते हैं। ..

+0

आपका समाधान क्लोजर – KobbyPemson

+0

@KobbyPemson में नहीं है क्या आप समझ सकते हैं कि क्या मतलब है .. मैं तुम्हें नहीं मिला .. –

2

जैसा कि जनीरा इटारेट द्वारा उल्लेख किया गया है, ऐसा करने का सही तरीका लगता है।

यहां उनके कार्य में एक सुधार है जो समझने के लिए स्पष्ट होना चाहिए क्योंकि इसमें कम मध्यवर्ती प्रकार शामिल हैं। यह चारों ओर पाश/पुनरावृत्ति होना आधारित अन्य समाधान के विपरीत पूरी तरह से आलसी है:

(defn column-names-seq [alphabet] 
    (->> (map str alphabet) 
    (iterate (fn [chars] 
       (for [x chars 
         y alphabet] 
        (str x y)))) 
    (apply concat))) 

उपयोग करने के लिए यह सिर्फ एक वर्णमाला स्ट्रिंग उदाहरण के साथ यह प्रदान करते हैं:

(take 30 (column-names-seq "ABCDEFGHIJKLMNOPQRSTUVWXYZ")) ;; => ("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "AA" "AB" "AC" "AD") 
संबंधित मुद्दे