एक NFA का अनुकरण करें


15

एक nondeterministic परिमित ऑटोमेटन एक परिमित राज्य मशीन है जहाँ एक tuple को कई राज्यों में मैप किया जाता है। अर्थात। हम हमेशा की तरह बदलने के δ : क्यू × Σ क्यू एक के संक्रमण समारोह DFA एक और समारोह के साथ Δ : क्यू × Σ पी ( क्यू )(state,symbol)δ:Q×Σक्यू Δ:Q×ΣP(Q)

यदि आप जानते हैं कि एनएफए क्या है तो आप अगले भाग को छोड़ना चाहते हैं।

औपचारिक परिभाषा

एनएफए को विशिष्ट रूप से वर्णित किया गया है

  • राज्यों का एक समुच्चय हैQ
  • Σ प्रतीकों में से एक परिमित सेट
  • संक्रमण समारोहΔ:Q×ΣP(Q)
  • प्रारंभिक अवस्थाq0Q
  • अंतिम राज्यों का एक सेटFQ

मशीन में बाहर शुरू होता है और प्रतीकों की एक निश्चित स्ट्रिंग पढ़ता डब्ल्यू Σ *q0wΣ , हरेक प्रतीक के लिए यह एक साथ एक वर्तमान स्थिति से संक्रमण समारोह समारोह लागू करते हैं और वर्तमान राज्यों के सेट करने के लिए राज्यों में से प्रत्येक नया सेट जोड़ देगा।

चुनौती

इस चुनौती के लिए हम इसे सरल बनाने के लिए को अनदेखा करेंगे , इसके अलावा वर्णमाला हमेशा z के लिए a (निचला मामला) अक्षर होगा और राज्यों का सेट कुछ गैर-नकारात्मक पूर्णांक N के लिए { 0 N } होगा । प्रारंभिक अवस्था हमेशा 0 होगी ।F a z {0N}एन0

एक शब्द को देखते हुए और NFA का विवरण, अपने कार्य को सभी अंतिम राज्यों निर्धारित करने के लिए है।w{az}

उदाहरण

स्ट्रिंग और निम्नलिखित विवरण पर विचार करें :abaab

state, symbol, new-states
0, 'a', [1]
1, 'a', [0]
1, 'b', [1,2]

मशीन में शुरू होगी :q0=0

  1. एक पढ़ा नए राज्यों: { 1 }a{1}
  2. एक पढ़ें : नए राज्य { b{1,2}
  3. एक पढ़ा : नए राज्योंa{0}
  4. एक पढ़ा : नए राज्योंa{1}
  5. एक पढ़ें : नए राज्य { 1 ,b{1,2}

तो अंतिम स्थिति और इस प्रकार आउटपुट {1,2}

नोट: स्टेप (2) स्टेट मैप्स के ट्रांज़िशन को विवरण के रूप में itions केवल गैर-खाली सेटों में संक्रमण शामिल करता है।2

नियम

इनपुट में एक स्ट्रिंग और NFA के कुछ प्रकार के विवरण होंगे ( -transitions के बिना ):ϵ

  • इनपुट स्ट्रिंग हमेशा के तत्व हो जाएगा {...z}*
  • मान्य इनपुट्स (तक सीमित नहीं):
    • tuples / सूचियों की सूची / सरणी
    • नई लाइन अलग इनपुट
  • एनएफए के विवरण में केवल परिणाम के रूप में गैर-खाली सेट के साथ संक्रमण शामिल होंगे
    • यदि आप समान परिणाम वाले नियमों को संक्षिप्त कर सकते हैं, यदि उनका परिणाम समान है (उदाहरण के नियम) 0,'a',[1,2]और 0,'b',[1,2]उनके साथ संक्षिप्त किया जा सकता है0,"ab",[1,2]
    • आप प्रत्येक नियम को अलग कर सकते हैं (जैसे। नियम 0,'a',[1,2]हो सकता है 0,'a',[1]और 0,'a',[2])
  • यदि आप चाहें तो आप ऊपरी मामलों के पत्र चुन सकते हैं
  • आप इनपुट के रूप में राज्यों की संख्या ले सकते हैं
  • आप इनपुट के आदेश के कुछ प्रकार मान सकते हैं (जैसे राज्य या प्रतीकों द्वारा आदेश दिया गया)

आउटपुट अंतिम राज्यों की सूची / सेट / नई-लाइन से अलग आउटपुट आदि होगा

  • आदेश मायने नहीं रखता
  • कोई डुप्लिकेट नहीं (जैसा कि यह एक सेट है)

परीक्षण के मामलों

ये उदाहरण उस प्रारूप में होंगे description word -> statesजहां descriptionट्यूपल्स की सूची है (state,symbol,new-states):

[]  "x" -> []
[]  "" -> [0]
[(0,'a',[1]),(1,'a',[0]),(1,'b',[1,2])]  "abaab" -> [1,2]
[(0,'a',[1]),(1,'a',[0]),(1,'b',[1,2])]  "abc" -> []
[(0,'p',[0,1]),(0,'g',[2]),(1,'c',[1]),(1,'g',[4]),(1,'p',[2]),(2,'c',[0])]  "ppcg" -> [2,4]
[(0,'f',[1]),(1,'o',[1,2]),(2,'b',[3]),(3,'a',[4]),(4,'r',[0,4])]  "foobar" -> [0,4]
[(0,'f',[1]),(1,'o',[1,2]),(2,'b',[3]),(3,'a',[4]),(4,'r',[0,4])]  "fooooooobar" -> [0,4]
[(0,'f',[1]),(1,'o',[1,2]),(2,'b',[3]),(3,'a',[4]),(4,'r',[0,4])]  "fobarfo" -> [1,2]
[(0,'f',[1]),(1,'o',[1,2]),(2,'b',[3]),(3,'a',[4]),(4,'r',[0,4])]  "foobarrf" -> [1]
[(0,'d',[1,2]),(1,'u',[2]),(2,'u',[2,3]),(2,'p',[3]),(3,'p',[3])]  "dup" -> [3]
[(0,'a',[0,2]),(0,'b',[3]),(1,'a',[1]),(1,'b',[1]),(2,'b',[1,4]),(4,'b',[2])]  "aab" -> [3,1,4]
[(0,'a',[0,2]),(0,'b',[3]),(1,'a',[1]),(1,'b',[1]),(2,'b',[1,4]),(4,'b',[2])]  "abb" -> [1,2]


3
यह मेरे ऑटोमेटन पाठ्यक्रम से डरावनी यादें वापस लाता है।
डॉन थाउजेंड

क्या हम प्रत्येक नए राज्य के लिए अलग-अलग लाइनों के साथ इनपुट ले सकते हैं, उदाहरण के लिए यह काम किया है?
ovs

@ नोव्स: ज़रूर आगे बढ़ो!
14

जवाबों:


7

हास्केल , 66 बाइट्स

import Data.List
f d=foldl(\s c->nub[r|(y,r)<-d,g<-s,(g,c)==y])[0]

इसे ऑनलाइन आज़माएं!


आप आयात से छुटकारा पा सकते हैं nubयदि आप राज्यों को मानते हैं [Int], तो आप प्रत्येक चेक का उपयोग कर सकते हैं [0..]जो परिमित है: 60 बाइट्स
tes

@BWO सब कुछ खत्म हो यह दोहराता Intरों और सभी मौजूदा राज्यों में है और इसलिए अभी भी डुप्लिकेट राज्यों पैदा करता है। उदाहरण (बदल [0..]करने के [0..3]प्रयोजनों के परीक्षण के लिए है, लेकिन यह सही एक फर्क नहीं करना चाहिए,?)
OVS

हाँ, यह निश्चित नहीं है कि मैं क्या सोच रहा था .. कोई बात नहीं ..
'

4

ब्रेकीलॉग , 42 बाइट्स

,0{hẸ&t|∋₁B∋IhJ&tJ&hhC∧I∋₁C∧It∋S&hb;B,S↰}ᵘ

इनपुट के रूप में [स्ट्रिंग, एनएएफए] जहां एनएफए राज्य संक्रमणों की एक सूची है [प्रारंभिक राज्य, पत्र, सूची के रूप में नए राज्य]

व्याख्या

,0                                              # Append 0 to the input (initial state)
  {                                      }ᵘ     # Find all unique outputs
   h                                            # if first element (string)
    Ẹ                                           #   is empty
     &t                                         #   then: return last element (current state)
       |                                        #   else:
        ∋₁B                                     #       save the state transitions in "B"
           ∋I                                   #       take one of these transitions, save in "I"
             hJ                                 #       take the initial state requirement, store in "J"
               &tJ                              #       make sure "J" is actually the current state
                  &hhC                          #       Save first char of string in C
                      ∧I∋₁C                     #       make sure the char requirement for the state transition is the current char
                           ∧It∋S                #       Make "S" equal to one of the new states
                                &hb             #       Behead the string (remove first char)
                                   ;B,S         #       Add B (the state transitions) and S (the new state)
                                       ↰        #       recur this function

इसे ऑनलाइन आज़माएं!


4

ब्रेकीलॉग v2, 31 बाइट्स

{b,Ȯ,Ȯ\c↔,0↔ġ₃kH&hg;Hz{∋ᵈ}ᵐtt}ᵘ

इसे ऑनलाइन आज़माएं! ( या अधिक जटिल उदाहरण के साथ )

Brachylog वास्तव में इस तरह की समस्या पर अच्छा है, और वास्तव में उन समस्याओं पर बुरा है जिनके लिए दो अलग-अलग इनपुट और आउटपुट की आवश्यकता होती है। इस कार्यक्रम के लगभग सभी प्लंबिंग हैं।

इनपुट प्रारूप एक सूची है जिसमें दो तत्व होते हैं: पहला है राज्य परिवर्तन की सूची ([oldState, symbol, newState] ) की सूची है, और दूसरा प्रतीकों की सूची है। मैंने मूल रूप से प्रतीकों के लिए चरित्र कोड के साथ काम करने के लिए इस कार्यक्रम की योजना बनाई (क्योंकि ब्रेकीलॉग की स्ट्रिंग हैंडलिंग कभी-कभी थोड़ी अजीब हो सकती है), लेकिन यह पता चलता है कि वर्ण भी काम करते हैं (हालांकि आपको इनपुट स्ट्रिंग को वर्णों की सूची के रूप में लिखना है, जैसे कि नहीं। एक स्ट्रिंग)। यदि एक राज्य-प्रतीक जोड़ी कई अलग-अलग राज्यों में संक्रमण कर सकती है, तो आप उससे निपटने के लिए कई संक्रमण लिखते हैं।

व्याख्या

{b,Ȯ,Ȯ\c↔,0↔ġ₃kH&hg;Hz{∋ᵈ}ᵐtt}ᵘ
{                            }ᵘ   Find all distinct outputs that can result from:
 b                                  taking the input minus its first element,
  ,Ȯ                                appending a singleton list (i.e. an element)
    ,Ȯ                              then appending that same element again
      \                             and transposing;
       c                            then concatenating the resulting lists,
        ↔,0↔                        prepending a 0,
            ġ₃                      grouping into blocks of 3 elements
              k                       (and discarding the last, incomplete, block),
               H&                   storing that while we
                 h                  take the first input element,
                  g  z              pair a copy of it with each element of
                   ;H                 the stored value,
                      {  }ᵐ         assert that for each resulting element
                       ∋ᵈ             its first element contains the second,
                        ᵈ ᵐ           returning the list of second elements,
                            t       then taking the last element of
                           t          the last element.

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

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]

हम इस कार्यक्रम के कुछ उपसर्गों के आउटपुट का निरीक्षण कर सकते हैं:

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]b,Ȯ,Ȯ
[[97,98,97,97,98],L,L]

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]b,Ȯ,Ȯ\
[[97,A,A],[98,B,B],[97,C,C],[97,D,D],[98,E,E]]

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]b,Ȯ,Ȯ\c↔,0↔
[0,97,A,A,98,B,B,97,C,C,97,D,D,98,E,E]

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]b,Ȯ,Ȯ\c↔,0↔ġ₃k
[[0,97,A],[A,98,B],[B,97,C],[C,97,D],[D,98,E]]

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]b,Ȯ,Ȯ\c↔,0↔ġ₃kH&hg;Hz
[[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[0,97,A]],
 [[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[A,98,B]],
 [[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[B,97,C]],
 [[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[C,97,D]],
 [[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[D,98,E]]]

[[[0,97,1],[1,97,0],[1,98,1],[1,98,2]],[97,98,97,97,98]]b,Ȯ,Ȯ\c↔,0↔ġ₃kH&hg;Hz{∋ᵈ}ᵐ
e.g. [[0,97,1],[1,98,1],[1,97,0],[0,97,1],[1,98,1]]

यहां पहले उदाहरण के लिए, Lशुरू में एक अज्ञात तत्व है, लेकिन जब हम इसके माध्यम से स्थानांतरित करते हैं\ , तो ब्रैचीलॉग को पता चलता है कि एकमात्र संभावना इनपुट के समान लंबाई वाली एक सूची है। यहां अंतिम उदाहरण नोंडेटेर्मिनिस्टिक है; हम NFAeterminism को NFAeterminism का उपयोग करके Brachylog में ही मॉडलिंग कर रहे हैं।

संभव सुधार

यहाँ कुछ सिंटैक्स, जैसे ↔,0↔और विशेष रूप से गड़बड़ H&hg;Hz{…ᵈ}ᵐ, काफी क्लंकी है। यह मुझे आश्चर्यचकित नहीं करेगा अगर इसको टटोलने का कोई कठिन तरीका हो।

{∋ᵈ}ᵐअपने आप में एक काफी संदिग्ध संरचना है - आप केवल लिखने में सक्षम होने की उम्मीद करेंगे ∋ᵈᵐ- लेकिन यह किसी कारण से पार्स नहीं करता है।


∋ᵈᵐपार्स नहीं करता क्योंकि इसे ऐसे लागू किया जाता है कि सिद्धांत में बहु-चरित्र मेटा-प्रेडिकेट नाम का उपयोग किया जा सकता है (यदि हम एकल-प्रतीक संभावनाओं से बाहर भाग गए)। वर्तमान में इसका उपयोग नहीं किया जाता है।
6

3

पायथन 3, 103 80 बाइट्स

@BWO को धन्यवाद

w=lambda n,f,a={0}:w(n,f[1:],{y for(x,c,y)in n if c==f[0]and{x}&a})if''<f else a

TIO

पिछली "सुरुचिपूर्ण" सूची समझ (103 बाइट्स):

def w(a,b):
    q=[0]
    for c in b:q=[j for s in q for i in a if s in i if i[1]==c for j in i[2]]
    return q

शर्म reduceआती है कि पायथन 3 का अभाव है .. लेकिन पुनरावृत्ति और वास्तविक सेट का उपयोग करना अभी भी आपको 80 बाइट्स तक ले आता है
ბიმო

@ अच्छा, धन्यवाद, हाहा btw ऊपर मेरे नए पसंदीदा उदाहरण अजगर कोड दिखाने के लिए है ... एक लाइन की विशाल सूची
समझाना

मुझे लगता है कि आप की जगह 2 बाइट्स बचा सकता है if''<fके साथ if f
चास ब्राउन

@ चास ब्राउन जो विफल हो जाता है अगर f एक फाल्सी वैल्यू है जैसे कि खाली स्ट्रिंग
क्विंटेक

दरअसल, मैं जो कह रहा हूं, उसे अनदेखा करें
क्विंट सेक

3

जावास्क्रिप्ट (ईएस 6), 99 बाइट्स

के रूप में इनपुट लेता है (nfa)(string)। एक सेट लौटाता है।

a=>g=([c,...b],s=[0])=>c?g(b,a.reduce((p,[x,y,z])=>s.includes(x)&y==c?[...p,...z]:p,[])):new Set(s)

इसे ऑनलाइन आज़माएं!


3

आर , 81 बाइट्स

function(a,b,e,s)Reduce(function(A,x)unique(e[a%in%A&b==x]),el(strsplit(s,"")),0)

इसे ऑनलाइन आज़माएं!

उपयोग कर सीधा उत्तर Reducestate, symbol, new-statesबुलाया के तीन वैक्टर के रूप में नियम लेता है a,b,e

नियम अलग हैं (जैसे। नियम 0,'a',[1,2]है 0,'a',1और 0,'a',2)।



2

क्लीन , 68 बाइट्स

ओव्स हास्केल समाधान पर आधारित यह एक मेरे प्रारंभिक दृष्टिकोण की तुलना में थोड़ा कम है।

अब एक परीक्षण हार्नेस भी शामिल है

import StdEnv
?d=foldl(\s c=removeDup[r\\(y,r)<-d,g<-s|(g,c)==y])[0]

इसे ऑनलाइन आज़माएं!


1
@BWO टेस्ट दोहन जोड़ा
Οurous

1

चारकोल , 44 बाइट्स

⊞υ⁰Fη«≔υζ≔⟦⟧υFζFθ¿∧⁼§λ⁰κ⁼§λ¹ιF§λ²¿¬№υμ⊞υμ»Iυ

इसे ऑनलाइन आज़माएं! लिंक कोड के वर्बोज़ संस्करण के लिए है। स्पष्टीकरण:

⊞υ⁰

0Inital राज्य को सेट करने के लिए पूर्वनिर्धारित रिक्त सूची में पुश करें{0}

Fη«

इनपुट पर लूप।

≔υζ

राज्य की प्रतिलिपि बनाएँ।

≔⟦⟧υ

राज्य को रीसेट करें।

Fζ

राज्य की नकल पर लूप।

Fθ

एनएफए प्रविष्टियों पर लूप।

¿∧⁼§λ⁰κ⁼§λ¹ι

यदि प्रविष्टि मेल खाती है, तो ...

F§λ²

... नए राज्यों पर लूप ...

¿¬№υμ

.... यदि वे पहले से सूची में नहीं हैं ...

⊞υμ»

... उन्हें सूची में जोड़ें।

Iυ

अलग-अलग लाइनों पर निहित आउटपुट के लिए राज्यों की सूची कास्ट करें।



1

जाप , 31 बाइट्स

W=[W]c;Ê?ßUÅVVf!øW føUg)mÌc):Wâ

कोशिश करो!

Japt की क्षमता के बेहतर उपयोग के साथ 2 बाइट्स को निहित करने के लिए कुछ निविष्टियों से एक फ़ंक्शन बनाने के लिए

स्पष्टीकरण:

W=[W]c;                            Initialize the state set to [0] on the first run
       Ê?                   :Wâ    If the input is empty return the unique states; else...
             Vf!øW                 Get the transitions valid for one of the current states
                   føUg)           Of those, get the ones valid for the current character
                        mÌc)       Merge the states of the remaining transitions
         ßUÅV                      Repeat with the remaining characters as input

नया "इनिशियलाइज़ स्टेट्स" कोड थोड़ा अधिक विवरण का उपयोग कर सकता है। Wयदि 3 से कम इनपुट हैं, तो Japt 0 को इनिशियलाइज़ करता है, इसलिए पहली बार रन [W]होता है [0], और cएक एरे "flattens" होता है। [0]यह पहले से ही फ्लैट के रूप में है क्योंकि यह हो जाता है, इसलिए इसे बदला नहीं गया है। Wउदाहरण के लिए बाद के रनों का एक अलग मूल्य है [1,2]। उस मामले में [W]हो जाता है [[1,2]], एक एकल तत्व सरणी जहां उस तत्व एक सरणी है। इस बार cवह सामने आया और वापस आ गया [1,2]। इस प्रकार, पहले रन पर यह W=[0]और बाद में रन पर है W=W

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.