Недетерминирован конечный автомат является конечным автоматом , где кортеж отображаются в нескольких штатов. То есть. мы заменяем обычную функцию перехода DFA другой функцией .
Если вы знаете, что такое NFA, вы можете пропустить следующий раздел.
Формальное определение
НФА однозначно описывается
- конечный набор состояний
- конечный набор символов
- функция перехода
- начальное состояние
- a set of final states
The machine starts out in and reads a finite string of symbols , for each symbol it will simultaneously apply the transition function function with a current state and add each new set of states to the set of current states.
Challenge
For this challenge we will ignore to simplify it, furthermore the alphabet will always be the (lower-case) letters to and the set of states will be for some non-negative integer . The initial state will always be .
Given a word and a description of the NFA, your task is to determine all the final states.
Example
Consider the string and the following description:
state, symbol, new-states
0, 'a', [1]
1, 'a', [0]
1, 'b', [1,2]
The machine will start in :
- read an : new states
- read a : new states
- read an : new states
- read an : new states
- read a : new states
So the final states and thus the output would be .
Note: In step (2) the transition of state maps to as the description only includes transitions to non-empty sets.
Rules
The input will consist of a string and some kind of description of the NFA (without -transitions):
- the input string will always be element of
- valid inputs (not limited to):
- list/array of tuples/lists
- new-line separated input
- the description of the NFA will only contain transitions with non-empty sets as result
- you may abbreviate rules with the same characters if their result is the same (eg. rules
0,'a',[1,2]
and0,'b',[1,2]
could be abbreviated with0,"ab",[1,2]
- you may take each rule separate (eg. rule
0,'a',[1,2]
can be0,'a',[1]
and0,'a',[2]
)
- you may abbreviate rules with the same characters if their result is the same (eg. rules
- you may choose upper-case letters if you want
- you may take the number of states as input
- you may assume some kind of ordering of the inputs (eg. ordered by state or symbols)
The output will be a list/set/new-line separated output etc. of the final states
- order doesn't matter
- no duplicates (as it's a set)
Test cases
These examples will be in the format description word -> states
where description
is a list of tuples (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]
Ответы:
Haskell, 66 bytes
Try it online!
источник
nub
if you assume the states to be[Int]
, then you can use check each[0..]
which is finite: 60 bytesInt
s and over all current states and therefore still produces duplicate states. Example (changed[0..]
to[0..3]
for testing purposes, but this should not make a difference, right?)Brachylog, 42 bytes
input as [string, nfa] where nfa is a list of state transitions [ initial state, letter, new states as list ]
Explanation
Try it online!
источник
Brachylog v2, 31 bytes
Try it online! (or with a more complex example)
Brachylog is really good at this sort of problem, and really bad at problems that require two separate inputs and an output. Almost all of this program is just plumbing.
Input format is a list containing two elements: the first is the list of state transitions (
[oldState, symbol, newState]
), and the second is the list of symbols. I originally planned this program to work with character codes for symbols (because Brachylog's string handling can be a bit weird sometimes), but it turns out that characters work too (although you have to write the input string as a list of characters, not as a string). If a state-symbol pair can transition to multiple different states, you write multiple transitions to deal with that.Explanation
It's probably easier to follow this by looking at what some partial versions of the program would produce. Using the following input each time:
we can observe the outputs of some prefixes of this program:
For the first example here,
L
is initially an unknown element, but when we transpose it via\
, Brachylog realises that the only possibility is a list with the same length as the input. The last example here is nondeterministic; we're modelling nondeterminism in the NFA using the nondeterminism in Brachylog itself.Possible improvements
Some of the syntax here, like
↔,0↔
and especially the mess withH&hg;Hz{…ᵈ}ᵐ
, is fairly clunky. It wouldn't surprise me if there were a terser way to phrse this.{∋ᵈ}ᵐ
is in its own right a fairly suspicious structure – you'd expect to just be able to write∋ᵈᵐ
– but it doesn't parse for some reason.источник
∋ᵈᵐ
doesn't parse because it is implemented such that multi-character meta-predicate names could in theory be used (if we ran out of single-symbol possibilities). In practice it's not currently used.Python 3,
10380 bytesthanks to @BWO
TIO
Previous "elegant" list comprehension(103 bytes):
источник
reduce
.. But using recursion and actual sets still brings you down to 80 bytes.if''<f
withif f
.JavaScript (ES6), 99 bytes
Takes input as
(nfa)(string)
. Returns a Set.Try it online!
источник
R, 81 bytes
Try it online!
Straightforward answer using
Reduce
. Takes rules as three vectors ofstate, symbol, new-states
calleda,b,e
.Rules are separate (eg. rule
0,'a',[1,2]
is0,'a',1
and0,'a',2
).источник
Coconut, 64 bytes
Try it online!
источник
Clean, 68 bytes
This one based on ovs's Haskell solution is a bit shorter than my initial approach was.
now includes a test harness
Try it online!
источник
Charcoal, 44 bytes
Try it online! Link is to verbose version of code. Explanation:
Push{0} .
0
to the predefined empty list to set the inital state toLoop over the input.
Copy the state.
Reset the state.
Loop over the copy of the state.
Loop over the NFA entries.
If the entry matches, then...
... loop over the new states...
.... if they are not already in the list...
... add them to the list.
Cast the list of states to string for implicit output on separate lines.
источник
Perl 6,
6154 bytesTry it online!
Takes a list of state transitions and an input string as list of characters.
источник
Japt, 31 bytes
Try it!
Saved 2 bytes with better use of Japt's ability to implicitly form a function out of some inputs
Explanation:
The new "initialize states" code could use a bit more detail. Japt initializes
W
to 0 if there are fewer than 3 inputs, so on the first run[W]
is[0]
, andc
"flattens" an array.[0]
is already as flat as it gets, so it isn't changed. On subsequent runsW
has a different value, for example[1,2]
. In that case[W]
becomes[[1,2]]
, a single-element array where that element is an array. This timec
unwraps that and gets back to[1,2]
. Thus, on the first run it'sW=[0]
and on subsequent runs it'sW=W
.источник