确定性有限状态机是一种简单的计算模型,广泛用于基础CS课程中自动机理论的介绍。它是一个简单的模型,相当于正则表达式,它确定某个输入字符串 Accepted 或 Rejected 。 Leaving some formalities aside,有限状态机的运行由:
组成机器上的运行从启动状态开始。读取输入字符串的每个字母;如果当前状态与对应于该字母的另一个状态之间存在转换,则当前状态将更改为新状态。在读取最后一个字母后,如果当前状态是接受状态,则接受输入字符串。如果最后一个状态不是接受状态,或者一个字母在运行期间没有来自状态的相应拱门,则拒绝输入字符串。
注意:这种短暂的破坏远不是FSM的完整,正式的定义; Wikipedia's fine article是对该主题的精彩介绍。
例如,以下机器会告知从左到右读取的二进制数是否具有偶数个0
s:
{0,1}
。(S1, 0) -> S2
,(S1, 1) -> S1
,(S2, 0) -> S1
和(S2, 1) -> S2
。使用您选择的语言实施FSM。
FSM应接受以下输入:
<States> List of state, separated by space mark.
The first state in the list is the start state.
Accepting states begin with a capital letter.
<transitions> One or more lines.
Each line is a three-tuple:
origin state, letter, destination state)
<input word> Zero or more characters, followed by a newline.
例如,上述带有1001010
作为输入字符串的机器将写为:
S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
1001010
FSM的运行,写为<State> <letter> -> <state>
,然后是最终状态。示例输入的输出将是:
S1 1 -> S1
S1 0 -> s2
s2 0 -> S1
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
s2 0 -> S1
ACCEPT
对于空输入''
:
S1
ACCEPT
注意:根据您的评论,S1
行(显示第一个状态)可能会被省略,并且以下输出也可以接受:
ACCEPT
101
:
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
REJECT
'10X'
:
S1 1 -> S1
S1 0 -> s2
s2 X
REJECT
最短的解决方案将获得250个代表奖金。
可以使用参考Python实现here。请注意,空字符串输入已放宽输出要求。
根据大众需求,空输入字符串也可接受以下输出:
ACCEPT
或
REJECT
没有上一行写的第一个状态。
有效的州名是一个英文字母,后跟任意数量的字母_
和数字,很像变量名,例如State1
,state0
,STATE_0
。
与大多数代码高尔夫球一样,您可以假设输入正确。
sed
137 solution是最短的,ruby 145是#2。目前,我无法使用sed解决方案:
cat test.fsm | sed -r solution.sed
sed -r solution.sed test.fsm
都给了我:
sed: -e expression #1, char 12: unterminated `s' command
所以,除非有澄清,否则赏金将归入红宝石解决方案。
答案 0 :(得分:23)
PS。问题放松后(无需在空输入上输出状态行),这里的新代码明显更短。如果您使用的是版本<2.7,则没有字典理解,因此代替{c+o:s for o,c,s in i[1:-1]}
尝试dict((c+o,s)for o,c,s in i[1:-1])
,价格为+5。
import sys
i=map(str.split,sys.stdin)
s=i[0][0]
for c in''.join(i[-1]):
if s:o=s;s={c+o:s for o,c,s in i[1:-1]}.get(c+s,());print o,c,'->',s
print'ARCECJEEPCTT'[s>'Z'::2]
其测试输出:
# for empty input
ACCEPT
# for input '1001010'
S1 1 -> S1
S1 0 -> s2
s2 0 -> S1
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
s2 0 -> S1
ACCEPT
# for input '101'
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
REJECT
# for input '10X'
S1 1 -> S1
S1 0 -> s2
s2 X -> ()
REJECT
# for input 'X10'
S1 X -> ()
REJECT
之前的条目(len 201):
import sys
i=list(sys.stdin)
s=i[0].split()[0]
t={}
for r in i[1:-1]:a,b,c=r.split();t[a,b]=c
try:
for c in i[-1]:print s,c.strip(),;s=t[s,c];print' ->',s
except:print('ACCEPT','REJECT')[s>'Z'or' '<c]
我想在有人抨击我之前道歉:代码行为与原始规范略有不同 - 每个问题 - 评论讨论。这是我讨论的例子。
PS。虽然我喜欢与最终状态在同一行上的ACCEPT / REJECT分辨率,但我可以通过添加{{1来移动到孤独(例如想象结果由愚蠢的脚本解析,只关心最后一行接受或拒绝) (+ 5个字符)到最后'\n'+
的价格为+5个字符。
示例输出:
print
答案 1 :(得分:21)
我今天感觉很复古,我这个任务的首选语言是IBM Enterprise Cobol - 字数<24> 4078(对不起,从屏幕导向的设备粘贴,尾随空间是一个悲剧性的副作用):
Identification Division.
Program-ID. FSM.
Environment Division.
Data Division.
Working-Storage Section.
01 FSM-Storage.
*> The current state
05 Start-State Pic X(2).
05 Next-State Pic X(2).
*> List of valid states
05 FSM-State-Cnt Pic 9.
05 FSM-States Occurs 9
Pic X(2).
*> List of valid transitions
05 FSM-Trans-Cnt Pic 999.
05 FSM-Trans Occurs 999.
10 Trans-Start Pic X(2).
10 Trans-Char Pic X.
10 Trans-End Pic X(2).
*> Input
05 In-Buff Pic X(72).
*> Some work fields
05 II Pic s9(8) binary.
05 JJ Pic s9(8) binary.
05 Wk-Start Pic X(2).
05 Wk-Char Pic X.
05 Wk-End Pic X(2).
05 Wk-Cnt Pic 999.
05 Pic X value ' '.
88 Valid-Input value 'V'.
05 Pic X value ' '.
88 Valid-State value 'V'.
05 Pic X value ' '.
88 End-Of-States value 'E'.
05 Pic X value ' '.
88 Trans-Not-Found value ' '.
88 Trans-Found value 'T'.
Linkage Section.
01 The-Char-Area.
05 The-Char Pic X.
88 End-Of-Input value x'13'.
05 The-Next-Char Pic X.
Procedure Division.
Perform Load-States
Perform Load-Transitions
Perform Load-Input
Perform Process-Input
Goback.
*> Run the machine...
Process-Input.
Move FSM-States (1) to Start-State
Set address of The-Char-Area to address of In-Buff
Perform until End-Of-Input
Perform Get-Next-State
Set address of The-Char-Area to address of The-Next-Char
Move Next-State to Start-State
End-Perform
If Start-State (1:1) is Alphabetic-Lower
Display 'REJECT'
Else
Display 'ACCEPT'
End-If
Exit.
*> Look up the first valid transition...
Get-Next-State.
Set Trans-Not-Found to true
Perform varying II from 1 by 1
until (II > FSM-State-Cnt)
or Trans-Found
If Start-State = Trans-Start (II)
and The-Char = Trans-Char (II)
Move Trans-End (II) to Next-State
Set Trans-Found to true
End-If
End-Perform
Display Start-State ' ' The-Char ' -> ' Next-State
Exit.
*> Read the states in...
Load-States.
Move low-values to In-Buff
Accept In-Buff from SYSIN
Move 0 to FSM-State-Cnt
Unstring In-Buff
delimited by ' '
into FSM-States (1) FSM-States (2) FSM-States (3)
FSM-States (4) FSM-States (5) FSM-States (6)
FSM-States (7) FSM-States (8) FSM-States (9)
count in FSM-State-Cnt
End-Unstring
Exit.
*> Read the transitions in...
Load-Transitions.
Move low-values to In-Buff
Accept In-Buff from SYSIN
Perform varying II from 1 by 1
until End-Of-States
Move 0 to Wk-Cnt
Unstring In-Buff
delimited by ' '
into Wk-Start Wk-Char Wk-End
count in Wk-Cnt
End-Unstring
If Wk-Cnt = 3
Add 1 to FSM-Trans-Cnt
Move Wk-Start to Trans-Start (FSM-Trans-Cnt)
Move Wk-Char to Trans-Char (FSM-Trans-Cnt)
Move Wk-End to Trans-End (FSM-Trans-Cnt)
Move low-values to In-Buff
Accept In-Buff from SYSIN
Else
Set End-Of-States to true
End-If
End-Perform
Exit.
*> Fix input so it has newlines...the joys of mainframes
Load-Input.
Perform varying II from length of In-Buff by -1
until Valid-Input
If In-Buff (II:1) = ' ' or In-Buff (II:1) = low-values
Move x'13' to In-Buff (II:1)
Else
Set Valid-Input to true
End-If
End-Perform
Exit.
End Program FSM.
答案 2 :(得分:19)
这是使用-r标志(+3),总共134 + 3 = 137个字符。
$!{H;D}
/:/!{G;s/(\S*)..(\S*)/\2 \1:/}
s/(.* .)(.*\n\1 (\S*))/\1 -> \3\n\3 \2/
/-/{P;D}
/^[A-Z].* :/cACCEPT
s/( .).*/\1/
/:/!P
cREJECT
这应该处理没有正确转换的输入...希望它现在完全符合规范......
答案 3 :(得分:8)
h={}
o=s=p
$<.map{|l|o,b,c=l.split;h[[o,b]]=c;s||=o}
o.chars{|c|puts s+' '+c+((s=h[[s,c]])?' -> '+s :'')}rescue 0
puts s&&s<'['?:ACCEPT: :REJECT
[
"S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
1001010",
"S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
101",
"S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
",
"S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
10X"
].each do |b|
puts "------"
puts "Input:"
puts b
puts
puts "Output:"
puts `echo "#{b}" | ruby fsm-golf.rb`
puts "------"
end
所有输入均以:
开头S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
Input: '1001010'
Output:
S1 1 -> S1
S1 0 -> s2
s2 0 -> S1
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
s2 0 -> S1
ACCEPT
Input: '101'
Output:
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
REJECT
Input: 'X10'
Output:
S1 X
REJECT
Input: ''
Output:
ACCEPT
Input: '10X'
Output:
S1 1 -> S1
S1 0 -> s2
s2 X
REJECT
答案 4 :(得分:5)
Adam提供了一个参考实现。我在制作之前没有看到它,但逻辑是相似的:
编辑:这是Python 2.6代码。我没有尽量减少长度;我只是试着让它在概念上变得简单。
import sys
a = sys.stdin.read().split('\n')
states = a[0].split()
transitions = a[1:-2]
input = a[-2]
statelist = {}
for state in states:
statelist[state] = {}
for start, char, end in [x.split() for x in transitions]:
statelist[start][char] = end
state = states[0]
for char in input:
if char not in statelist[state]:
print state,char
print "REJECT"
exit()
newstate = statelist[state][char]
print state, char, '->', newstate
state = newstate
if state[0].upper() == state[0]:
print "ACCEPT"
else:
print "REJECT"
答案 5 :(得分:4)
(排除所有新行的计数,这是可选的。)
($s)=split' ',<>;$\=$/;
while(<>){chomp;$r{$_[1].$_[0]}=$_[2]if split>2;$t=$_}
$_=$t;
1 while$s&&s/(.)(.*)/print"$s $1",($s=$r{$1.$s})?" -> $s":"";$2/e;
print$s=~/^[A-Z]/?"ACCEPT":"REJECT"
此外,这个155个字符的程序不实现中间输出,而是完全执行机器作为整个FSM定义的重复替换(更改开始状态和输入字符串)。它的灵感来自于sed
解决方案,但并非来自(?:...)
解决方案。通过将(...)
转换为$/="";$_=<>;
1 while s/\A(\S+)(?: +\S+)*\n(.*\n)?\1 +(.) +(.+)\n(.*\n)?\3([^\n]*)\n\z/$4\n$2$1 $3 $4\n$5$6\n/s;
print/\A[A-Z].*\n\n\z/s?"ACCEPT\n":"REJECT\n"
并根据需要重新编号,可以缩短2个字符。
{{1}}
答案 6 :(得分:4)
ORIG 3910
A ALF ACCEP
ALF T
ORIG 3940
R ALF REJEC
ALF T
ORIG 3970
O CON 0
ALF ->
ORIG 3000
S ENT6 0
T IN 0,6(19)
INC6 14
JBUS *(19)
LDA -14,6
JANZ T
LDA -28,6(9)
DECA 30
JAZ C
DECA 1
JANZ B
C LD2 0(10)
ENT4 -28,6
ENT5 9
D JMP G
ENT3 0
F INC3 14
LD1 0,3(10)
DEC2 0,1
J2Z M
INC2 0,1
DEC3 -28,6
J3NN U
INC3 -28,6
JMP F
M INC2 0,1
LD1 0,3(36)
DECA 0,1
JAZ H
INCA 0,1
JMP F
H INCA 0,1
ST2 O(10)
LD2 1,3(10)
STA O(36)
ST2 O+1(37)
OUT O(18)
JBUS *(18)
JMP D
HLT
E LD1 0(10)
DEC1 0,2
J1Z B
U OUT R(18)
JBUS *(18)
HLT
B OUT A(18)
JBUS *(18)
HLT
G STJ K
ST5 *+1(36)
LDA 0,4
JAZ E
DECA 30
JAZ I
DECA 1
JANZ W
INCA 1
I INCA 30
DEC5 45
J5NN J
INC5 54
JMP K
J INC4 1
ENT5 9
K JMP *
W ST2 O(10)
INCA 31
STA O(36)
STZ O+1
OUT O(18)
JBUS *(18)
JMP B
END S
答案 7 :(得分:4)
输出格式似乎有点难以适应。
import sys
L=[i.split()for i in sys.stdin]
N,P=L[0][0],print
for c in L[-1]and L[-1][-1]:
if N:O,N=N,{(i[0],i[1]):i[2]for i in L[1:-1]}.get((N,c),'');P(O,c,N and'-> '+N)
P(('REJECT','ACCEPT')[''<N<'_'])
答案 8 :(得分:4)
s%(c:d,t)=s++' ':c:maybe('\n':x)(\[u]->" -> "++u++'\n':u%(d,t))(lookup[s,[c]]t)
s%_|s<"["="ACCEPT\n"|1<3=x
x="REJECT\n"
p(i:j)=(words i!!0)%(last j,map(splitAt 2.words)j)
main=interact$p.lines
符合输出规范。
Ungolf'd版本:
type State = String
type Transition = ((State, Char), State)
run :: [Transition] -> State -> String -> [String]
run ts s (c:cs) = maybe notFound found $ lookup (s,c) ts
where
notFound = stateText : ["REJECT"]
found u = (stateText ++ " -> " ++ u) : run ts u cs
stateText = s ++ " " ++ [c]
run _ (s:_) "" | s >= 'A' && s <= 'Z' = ["ACCEPT"]
| otherwise = ["REJECT"]
prepAndRun :: [String] -> [String]
prepAndRun (l0:ls) = run ts s0 input
where
s0 = head $ words l0
input = last ls
ts = map (makeEntry . words) $ init ls
makeEntry [s,(c:_),t] = ((s,c),t)
main' = interact $ unlines . prepAndRun . lines
一个很好的谜题是高尔夫版本中不需要init
的原因!除此之外,休息都是标准的Haskell高尔夫技术。
答案 9 :(得分:4)
import sys
T=sys.stdin.read()
P=T.split()
S=P[0]
n="\n"
for L in P[-1]if T[-2]!=n else"":
i=T.find(n+S+" "+L)
if i<0:print S,L;S=n;break
S=T[i:].split()[2];print S,L,"->",S
print ("REJECT","ACCEPT")[S[0].isupper()]
答案 10 :(得分:3)
main=interact$r.lines
r f=g t z$last f where{(z:_):t=map words f;g _ s""|s<"["="ACCEPT\n";g([q,j,p]:_)s(i:k)|i:s==j++q=s++' ':i:" -> "++p++'\n':g t p k;g(_:y)s i=g y s i;g _ _ _="REJECT\n"}
编辑:没有正确实现无转换拒绝的输出。
换行版本和变量指南:
-- r: run FSM
-- f: fsm definition as lines
-- z: initial state
-- g: loop function
-- t: transition table
-- s: current state
-- i: current input
-- k: rest of input
-- q: transition table match state
-- j: transition table match input
-- p: transition table next state
-- y: tail of transition table
main=interact$r.lines;
r f=g t z$last f where{
(z:_):t=map words f;
g _ s""|s<"["="ACCEPT\n";
g([q,j,p]:_)s(i:k)|i:s==j++q=s++' ':i:" -> "++p++'\n':g t p k;
g(_:y)s i=g y s i;
g _ _ _="REJECT\n"}
我从MtnViewMark的解决方案中获得了s<"["
技术;其余的是我自己的设计。显着特征:
答案 11 :(得分:3)
Common Lisp - 725
(defun split (string)
(loop for i = 0 then (1+ j)
as j = (position #\Space string :start i)
collect (subseq string i j)
while j))
(defun do-fsm ()
(let* ((lines (loop for l = (read-line *standard-input* nil)
until (not l)
collect (split l)))
(cur (caar lines))
(transitions (subseq lines 1 (- (length lines) 1))))
(if (or (loop for c across (caar (last lines))
do (format t "~a ~a" cur c)
when (not (loop for tr in transitions
when (and (equal cur (car tr))
(equal c (char (cadr tr) 0)))
return (progn (format t " -> ~a~%"
(setq cur (caddr tr)))
t)
))
return t)
(lower-case-p (char cur 0)))
(format t "~%REJECT~%")
(format t "ACCEPT~%"))))
没有真正尝试最小化代码 - Common Lisp在所需的输入处理中付出了沉重的代价,因此我认为此解决方案获胜的可能性不大:-)
答案 12 :(得分:2)
(这个答案经过了一些编辑,因为我最初发布的一些代码是为了普遍感兴趣,然后决定实际发布一个真正的解决方案)
这是一个Rexx版本,让人们领略那种鲜为人知的语言。 Rexx http://en.wikipedia.org/wiki/REXX是IBM的VM / CMS大型机操作系统中使用的解释语言,后来又在IBM OS / 2中使用(我相信有一个Amiga变体)。它是一种非常富有表现力的语言,是一种令人惊叹的通用/“脚本”语言。
Parse pull i .
d.='~'
Do until l='';Parse pull o l d.o.l;End
Do j=1 to LENGTH(o)
t=SUBSTR(o,j,1);p=i t;i=d.i.t
If i=d. then Do;Say p;Leave;End
Say p '->' i
End
Say WORD('ACCEPT REJECT',c2d(left(i,1))%32-1)
这可以使用Regina Rexx解释器运行。
使用其唯一输出处理不正确的转换方案并且还测试大写有点贵。
对于对Rexx语法感兴趣的人,下面的一些旧编辑的代码,那些不是100%符合输出要求但功能正常(此答案中的所有代码都适用于我粘贴在下面的示例,但上面的代码处理其他必要的角落):
较旧的简短版本:
Parse pull i .
Do until l = ""; Parse pull o l d; t.o.l = d; End
Do j=1 to LENGTH(o); t=substr(o,j,1); Say i t "->" t.i.t; i=t.i.t; End
If LEFT(i,1)='S' then Say 'ACCEPT'; else say 'REJECT'
更长的版本:
Parse pull initial . /* Rexx has a powerful built in string parser, this takes the first word into initial */
Do until letter = "" /* This style of do loops is a bit unusual, note how it doesn't matter that letter isn't defined yet */
Parse pull origin letter destination /* Here we parse the inpt line into three words */
transition.origin.letter = destination /* Rexx has a very powerful notion of associative containers/dictionaries, many years pre-Python */
End
/* Now we take the last line and iterate over the transitions */
Do i = 1 to LENGTH(origin)
t = substr(origin, i, 1) /* This is the actual letter using Rexx's string functions */
Say initial t "->" transition.initial.t /* Say is like print */
initial = transition.initial.t /* Perform the transition */
End
/* check for uppercase in the current state */
if left(initial, 1) = 'S' then Say 'ACCEPT'; else say 'REJECT'
样品进/出:
S1 s2
S1 0 s2
0
S1 0 -> s2
REJECT
S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
1001010
S1 1 -> S1
S1 0 -> s2
s2 0 -> S1
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
s2 0 -> S1
ACCEPT
答案 13 :(得分:2)
h={}
r=$<.read
t=s=r.split[0]
i=r[-1]=="
"?"":r.split[-1]
r.scan(/(\S+) (.) (.+)/){|a,b,c|h[[a,b]]=c}
i.chars{|c|puts s+" #{c} -> #{s=h[[s,c]]}"}
puts s&&s[/^[A-Z]/]?"ACCEPT":"REJECT"
真的,奇怪的输出规格。我的作品如何:http://ideone.com/cxweL
答案 14 :(得分:2)
Lua,356
为状态采用任何非空格字符,为过渡字母采用任何非空格字符。虽然看起来不是最短的,但我会以任何方式发布。 可以保存25个字符打印标签而不是空格。
可读版本:
i=io.read
p=print
S={}
i():gsub("(%S+)",function (a) f=f or a S[a]={} end )
l=i"*a"
for a,t,d in l:gmatch"(%S+) (%S) (%S+)"do
S[a][t]=d
end
I=l:match"(%S+)%s$"or"" -- fixes empty input
function F(a,i)
t=I:sub(i,i)
if t==""then
p"ACCEPT"
elseif S[a][t] then
p(("%s %s -> %s"):format(a,t, S[a][t]))
return F( S[a][t],i+1)
else
if t~=""then p(a.." "..t)end p'REJECT'
end
end
F(f,1)
高尔夫版+输出。
i=io.read p=print S={}i():gsub('(%S+)',function(a)f=f or a S[a]={}end)l=i'*a'for a,t,d in l:gmatch"(%S+) (%S) (%S+)"do S[a][t]=d end I=l:match'(%S+)%s$'or''function F(a,i)t=I:sub(i,i)if t==""and a:match'^%u'then p'ACCEPT'elseif S[a][t]then p(('%s %s -> %s'):format(a,t,S[a][t]))return F(S[a][t],i+1)else if t~=''then p(a.." "..t)end p'REJECT'end end F(f,1)
-- input --
A B C
A B B
A C C
A A A
B A A
B B B
B C C
C A A
C B B
C C C
AABCCBCBAX
-- output --
A A -> A
A A -> A
A B -> B
B C -> C
C C -> C
C B -> B
B C -> C
C B -> B
B A -> A
REJECT
答案 15 :(得分:2)
declare -A a read s x while read f m t&&[ $m ];do a[$f $m]=$t;done for((i=0;i-${#f};i++))do b="$s ${f:i:1}";s=${a[$b]};echo $b -\> $s;done [ "$s" = "${s,}" ]&&echo REJECT||echo ACCEPT
请注意,这实际上需要bash - POSIX sh没有关联数组或C语言的语法(并且可能没有使用所有参数扩展,虽然我没有检查过)。
编辑:或者,对于完全相同的长度,
declare -A a read s x while read f m t&&[ $m ];do a[$f $m]=$t;done while [ $f ];do b="$s ${f:i:1}";f=${f:1};s=${a[$b]};echo $b -\> $s;done [ "$s" = "${s,}" ]&&echo REJECT||echo ACCEPT
答案 16 :(得分:0)
r=...
p=print
M={}
s=r:match('(%a%d)')
for i,n,o in r:gmatch('(%a%d)%s(%d)%s(%a%d)')do
M[i]=M[i]or{}
M[i][n]=o
end
for c in r:match('%d%d+'):gmatch('(%d)')do
z=s
s=M[z][c]
p(z,c,'->',s)
end
p(s==s:upper()and'ACCEPT'or'REJECT')
上的正在运行的版本
答案 17 :(得分:0)
C# - 453 375 353 345个字符
这不会赢(不是任何人都应该期待的),但无论如何写它很有趣。我保留了可读性的主要空间和换行符:
using System;
class P
{
static void Main()
{
string c,k="";
var t=new string[99999][];
int p=-1,n;
while((c=Console.ReadLine())!="")
t[++p]=c.Split(' ');
c=t[0][0];
foreach(var d in t[p][0]){
k+=c+' '+d;
for(n=1;n<p;n++)
if(c==t[n][0]&&d==t[n][1][0])
{
c=t[n][2];
k+=" -> "+c;
break;
}
k+="\n";
if(n==p){
c="~";
break;
}
}
Console.Write(k+(c[0]>'Z'?"REJECT":"ACCEPT"));
}
}
在我的上一次更新中,通过假设输入行数(即99,999)的实际限制,我能够保存22个字符。在最坏的情况下,你需要将其增加到最大值为2,147,483,647的Int32,这将增加5个字符。虽然我的机器不喜欢阵列的想法......
执行的一个例子:
>FSM.exe
S1 s2
S1 0 s2
S1 1 S1
s2 0 S1
s2 1 s2
1001010
S1 1 -> S1
S1 0 -> s2
s2 0 -> S1
S1 1 -> S1
S1 0 -> s2
s2 1 -> s2
s2 0 -> S1
ACCEPT
答案 18 :(得分:0)
我认为对于不变的高尔夫来说并不坏。我今天在课程上做得不是很好。
open System
let f,p,a=Array.fold,printf,Map.add
let l=Console.In.ReadToEnd().Split '\n'
let e,s=l.Length,l.[0].Split ' '
let t,w=Map.ofList[for q in s->q,Map.empty],[|"ACCEPT";"REJECT"|]
let m=f(fun t (r:String)->let s=r.Split ' 'in a s.[0](t.[s.[0]]|>a s.[1].[0]s.[2])t)t l.[1..e-2]
try let r=l.[e-1].ToCharArray()|>f(fun s c->p"%s %c "s c;let n=m.[s].[c]in p"-> %s\n"n;n)s.[0]in p"%s"w.[int r.[0]/97]with|_->p"%s"w.[1]
未打高尔夫的F#33行。在我打完高尔夫球之后,我会再次更新。
open System
let input = Console.In.ReadToEnd()
//let input = "S1 s2\nS1 0 s2\nS1 1 S1\ns2 0 S1\ns2 1 s2\n1001010"
let lines = input.Split '\n'
let length = lines.Length
let states = lines.[0].Split ' '
let stateMap = Map.ofList [for state in states -> (state, Map.empty)]
let folder stateMap (line:String) =
let s = line.Split ' '
stateMap |> Map.add s.[0] (stateMap.[s.[0]] |> Map.add s.[1].[0] s.[2])
let machine = Array.fold folder stateMap lines.[1 .. (length-2)]
let stateMachine state char =
printf "%s %c " state char
let newState = machine.[state].[char]
printfn "-> %s" newState
newState
try
let result =
lines.[length-1].ToCharArray()
|> Array.fold stateMachine states.[0]
if Char.IsUpper result.[0] then
printf "ACCEPT"
else
printf "REJECT"
with
| _ -> printf "REJECT"
答案 19 :(得分:0)
可能还有改进的余地,暗示欢迎。 处理我认为的规格。
import sys;a=sys.stdin.readlines();b=a[0].split()
f=b[0];d=dict((x,{})for x in b);s=''
for x,y,z in map(str.split,a[1:-1]):d[x][y]=z
for g in a[-1]:
try:s+=f+' '+g;f=d[f][g];s+=' -> '+f+'\n'
except:s+='\n';break
print s+("REJECT","ACCEPT")[ord(f[0])<90 and g in d[f]]