前言
A=B
是一種虛構的程式語言(其實是個遊戲)
A=B,意思就是把"A"取代為"B",整個語言圍繞著這個邏輯運轉
這個程式語言,編譯時遵守下列規則:
2.編譯時,跳過前面是 # 字符開頭的行(此為註解)。
執行時,遵守下列規則:
2.當發現到可以成功進行"取代"的程式碼,立刻適用該行程式碼,並取得新字串。
3.回到第一行,繼續由上往下執行。
4.若從第一行,到最後一行,都沒有成功進行"取代",程式結束,輸出最終字串。
5.執行時,跳過前面是 # 字符開頭的行(此為註解)。
原始碼
於VB.NET,開啟新專案 Windows Forms App (.NET Framework)
並將以下程式碼複製貼上到後端,即可執行
(前端不須新增元件)
Public Class Form1
Dim question(99) As String
Dim input(99) As String
Dim exInput(99, 99) As String
Dim output(99) As String
Dim exOutput(99, 99) As String
Dim example(99) As String
Dim num As Integer
Public TextBox1 As New TextBox '宣告前端控制項
Public TextBox2 As New TextBox
Public TextBox3 As New TextBox
Public Button1 As New Button
Public Button2 As New Button
Public Button3 As New Button
Public Label1 As New Label
Public ComboBox1 As New ComboBox
Public CheckBox1 As New CheckBox
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'前端控制項屬性設定
Me.Size = New Size(555, 335)
TextBox1.Name = "TextBox1"
TextBox1.Location = New Point(305, 30)
TextBox1.Size = New Size(220, 225)
TextBox1.Multiline = True
TextBox1.ScrollBars = ScrollBars.Both
Me.Controls.Add(TextBox1)
TextBox2.Name = "TextBox2"
TextBox2.Location = New Point(15, 135)
TextBox2.Size = New Size(220, 120)
TextBox2.Multiline = True
TextBox2.ScrollBars = ScrollBars.Both
TextBox2.ReadOnly = True
Me.Controls.Add(TextBox2)
AddHandler TextBox2.TextChanged, AddressOf TextBox2_TextChanged
TextBox3.Name = "TextBox3"
TextBox3.Location = New Point(15, 10)
TextBox3.Size = New Size(220, 120)
TextBox3.Multiline = True
TextBox3.ScrollBars = ScrollBars.Both
TextBox3.ReadOnly = True
Me.Controls.Add(TextBox3)
Button1.Name = "Button1"
Button1.Text = "執行"
Button1.Location = New Point(380, 260)
Me.Controls.Add(Button1)
AddHandler Button1.Click, AddressOf Button1_Click
Button2.Name = "Button2"
Button2.Text = "上一題"
Button2.Location = New Point(15, 260)
Me.Controls.Add(Button2)
AddHandler Button2.Click, AddressOf Button2_Click
Button3.Name = "Button3"
Button3.Text = "下一題"
Button3.Location = New Point(160, 260)
Me.Controls.Add(Button3)
AddHandler Button3.Click, AddressOf Button3_Click
Label1.Name = "Label1"
Label1.Text = "程式碼:"
Label1.Location = New Point(305, 10)
Me.Controls.Add(Label1)
ComboBox1.Name = "ComboBox1"
ComboBox1.Location = New Point(105, 260)
ComboBox1.Size = New Size(42, 20)
Me.Controls.Add(ComboBox1)
AddHandler ComboBox1.SelectedIndexChanged, AddressOf ComboBox1_SelectedIndexChanged
CheckBox1.Name = "CheckBox1"
CheckBox1.Location = New Point(470, 265)
CheckBox1.Text = "逐步執行"
CheckBox1.Checked = True
Me.Controls.Add(CheckBox1)
'題目
Dim fullQuestion As String = ""
#Region "第一章"
fullQuestion += "將A取代為B,BBBAAABA,BBBBBBBB,#本作中只有A=B 一道指令<br>#意思是用B 去取代A<br><br>#提示:程式會反覆執行<br>#直到找不到任何的A為止<br><br>A=B" + vbNewLine
fullQuestion += "將A移到最前面,BACABBCAA,AAAABCBBC,BA=AB<br>CA=AC" + vbNewLine
fullQuestion += "按照ABC的順序排列字串,BACABBCAA,AAAABBBCC," + vbNewLine
fullQuestion += "將字母改成小寫,ABACCBA,abaccba," + vbNewLine
fullQuestion += "消除全部的A,BAAACAABBCA,BCBBC,#提示:等號左邊留空白 = 刪除<br><br>A=" + vbNewLine
fullQuestion += "合併連續出現的字母,BBAAACBCCCC,BACBC," + vbNewLine
fullQuestion += "消除連續出現的A,BAAACBBCA,BCBBCA," + vbNewLine
fullQuestion += "回傳出現次數最多的字母,AAABBABBAA,A," + vbNewLine
fullQuestion += "回傳A的數量,AAAAAAAAAAAAA,13,#提示:十進位<br><br>A=1<br>1A=2<br>2A=3" + vbNewLine
#End Region
#Region "第二章"
fullQuestion += "回傳Hello World,BBAAB,Hello world,#提示:關鍵字(return)<br>#代表直接回傳這個字串<br>#之後結束程式<br><br>=(return)Hello world" + vbNewLine
fullQuestion += "若字串內包含一個以上A,回傳true,否則回傳false,ABBBAA,true,#提示:若找到A,則return true<br><br>A=(return)true" + vbNewLine
fullQuestion += "若字串內包含三個以上A,回傳true,否則回傳false,ACBBAA,true," + vbNewLine
fullQuestion += "若字串長度剛好等於三,回傳true,否則回傳false,ABC,true," + vbNewLine
fullQuestion += "輸出字串長度除以三的餘數,AABC,1," + vbNewLine
fullQuestion += "若字串中每個字母的數量為'0'或'奇數',回傳true,否則回傳false,ABCCC,true," + vbNewLine
fullQuestion += "若只有一個字母是單獨存在,回傳true,否則回傳false,AAABCCCBB,true," + vbNewLine
fullQuestion += "若ABC字母的數量為C>B>A,回傳true,否則回傳false,ABBCCC,true," + vbNewLine
fullQuestion += "回傳出現次數最多的字母,AAABCC,A," + vbNewLine
fullQuestion += "回傳出現次數最少的字母,AAABCC,B," + vbNewLine
#End Region
Dim fullQuestionArray() As String = Split(fullQuestion, vbNewLine)
For i = 0 To fullQuestionArray.Length - 1
Dim strTemp() As String = Split(fullQuestionArray(i), ",")
If strTemp.Length < 4 Then
Exit For
End If
question(i) = strTemp(0)
input(i) = strTemp(1)
output(i) = strTemp(2)
example(i) = strTemp(3).Replace("<br>", vbNewLine)
ComboBox1.Items.Add(i + 1)
Next
'額外input、output
Dim exStr As String = ""
#Region "第一章"
exStr += "BBBAAABA,BBBBBBBB" + vbNewLine '將A取代為B
exStr += "BACABBCAA,AAAABCBBC" + vbNewLine '將A移到最前面
exStr += "BACABBCAA,AAAABBBCC,CCCAAAACA,AAAAACCCC,BCACB,ABBCC" + vbNewLine '按照ABC的順序排列字串
exStr += "ABACCBA,abaccba" + vbNewLine '將字母改成小寫
exStr += "BAAACAABBCA,BCBBC" + vbNewLine '消除全部的A
exStr += "BBAAACBCCCC,BACBC" + vbNewLine '合併連續出現的字母
exStr += "BAAACBBCA,BCBBCA,BACAAAB,BACB,AAAAAAA,,AAAAAB,B,BAAAAC,BC" + vbNewLine '消除連續出現的A
exStr += "AAABBABBAA,A,BAABBAABBAABA,A,BAABBBAAABBB,B" + vbNewLine '回傳出現次數最多的字母
exStr += "AAAAAAAAAAAAA,13,AAAAA,5,AAAAAAAA,8,AAAAAAAAAAAAAAAAAA,18" + vbNewLine '回傳A的數量
#End Region
#Region "第二章"
exStr += "BBAAB,Hello world" + vbNewLine '回傳Hello World
exStr += "ABBCAA,true,BBCBB,false" + vbNewLine '若字串內包含一個以上A
exStr += "ACBBAA,true,ABAACCA,true,BBBAAC,false,AABBACAA,true" + vbNewLine '若字串內包含三個以上A
exStr += "ABC,true,AABBB,false,A,false,AACCBA,false" + vbNewLine '若字串長度剛好等於三
exStr += "AABC,1,ACAAB,2,ABB,0,CCABB,2" + vbNewLine '輸出字串長度除以三的餘數
exStr += "ABCCC,true,AABCC,false,ABCC,false,ABBCCC,false,AAAB,true" + vbNewLine '若字串中每個字母的數量為'0'或'奇數'
exStr += "AAABCCCBB,true,ABCCC,false,AAABCCA,false,BBCCC,false" + vbNewLine '若只有一個字母是單獨存在
exStr += "ABBCCC,true,BBCCA,false,CBCCCBA,true,AACBCC,false,CCCBB,true" + vbNewLine '若ABC字母的數量為C>B>A
exStr += "AAABCC,A,BBABC,B,ABBCCC,C,CACBC,C" + vbNewLine '回傳出現次數最多的字母
exStr += "AAABCC,B,CACBB,A,BBACA,C,CBBCCA,A" + vbNewLine '回傳出現次數最少的字母
#End Region
Dim exStrArray() As String = Split(exStr, vbNewLine)
For i = 0 To exStrArray.Length - 1
Dim strTemp() As String = Split(exStrArray(i), ",")
Dim exCount As Integer = 0
If strTemp.Length < 2 Then
Exit For
End If
For j = 0 To strTemp.Length - 1 Step 2
exInput(i, exCount) = strTemp(j)
exOutput(i, exCount) = strTemp(j + 1)
exCount += 1
Next
Next
num = 0
setQuestion()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs)
Dim command() As String = TextBox1.Text.Split(vbCrLf) 'user輸入程式碼
Dim outputTemp As String = input(num) '輸出結果暫存
Dim exCount As Integer = 0 'exInputCount
outputTemp = exInput(num, exCount)
Dim timeOut As Integer = 0 '執行步驟上限
Dim delayTime As Integer = 0 '控制逐步執行
TextBox2.Text = ""
If checkCommand() = False Then '偵測語法錯誤
Exit Sub
End If
TextBox2.Text = "計算過程:" + vbNewLine
TextBox2.Text += outputTemp + vbNewLine
If CheckBox1.Checked Then lockButton() '按鈕鎖定
Do
Dim count As Integer = 0 '比對不符合的次數
If CheckBox1.Checked Then
delayTime = 1000
Else
delayTime = 0
End If
For i = 0 To command.Length - 1 '執行程式碼
command(i) = command(i).Replace(vbCr, "").Replace(vbLf, "")
Dim comTemp() As String = Split(command(i), "=")
If comTemp.Length = 1 Then
count += 1
Continue For '跳過空行
ElseIf Mid(comTemp(0), 1, 1) = "#" Then
count += 1
Continue For '跳過註解
End If
Dim flagLeft As String = "" '關鍵字
Dim flagRight As String = ""
If Mid(comTemp(0), 1, 6) = "(once)" Then '辨識關鍵字(左)
flagLeft = "once"
comTemp(0) = Mid(comTemp(0), 7, comTemp(0).Length - 1)
End If
If Mid(comTemp(1), 1, 8) = "(return)" Then '辨識關鍵字(右)
flagRight = "return"
comTemp(1) = Mid(comTemp(1), 9, comTemp(1).Length - 1)
End If
Dim comLeft As String = Trim(comTemp(0))
Dim comRight As String = Trim(comTemp(1))
Dim compare As Integer = InStr(outputTemp, comLeft)
Dim outputLeft As String = ""
Dim outputMid As String = ""
Dim outputRight As String = ""
If comLeft = "" Then
outputTemp = comRight + outputTemp
TextBox2.Text += " -> " + command(i) + vbNewLine
If flagLeft = "once" Then '執行關鍵字(左)
command(i) = ""
End If
If flagRight = "return" Then '執行關鍵字(右)
outputTemp = comRight
count = command.Length
End If
TextBox2.Text += outputTemp + vbNewLine
Application.DoEvents()
Threading.Thread.Sleep(delayTime)
Exit For '執行成功,跳脫for迴圈
ElseIf compare > 0 Then
outputLeft = Mid(outputTemp, 1, compare - 1)
outputMid = comRight
outputRight = Mid(outputTemp, compare + comLeft.Length, outputTemp.Length - 1)
outputTemp = outputLeft + outputMid + outputRight
TextBox2.Text += " -> " + command(i) + vbNewLine
If flagLeft = "once" Then '執行關鍵字(左)
command(i) = ""
End If
If flagRight = "return" Then '執行關鍵字(右)
outputTemp = comRight
count = command.Length
End If
TextBox2.Text += outputTemp + vbNewLine
Application.DoEvents()
Threading.Thread.Sleep(delayTime)
Exit For '執行成功,跳脫for迴圈
Else
count += 1 '比對不符合(此行程式碼未執行)
End If
Next
If count = command.Length Then '此次比對全部不符合,開始對照答案
If outputTemp = exOutput(num, exCount) Then
TextBox2.Text += "正確答案." + vbNewLine
exCount += 1 '答對,繼續執行下一組input
Application.DoEvents()
Threading.Thread.Sleep(delayTime / 2)
If exInput(num, exCount) <> "" Then '準備執行下一組input
outputTemp = exInput(num, exCount)
command = TextBox1.Text.Split(vbCrLf)
TextBox2.Text = "計算過程:" + vbNewLine
TextBox2.Text += outputTemp + vbNewLine
End If
Else
TextBox2.Text += "錯誤答案." + vbNewLine
TextBox2.Text += "範例輸出:" + exOutput(num, exCount) + vbNewLine
TextBox2.Text += "目前輸出:" + outputTemp + vbNewLine
Exit Do '答錯,跳脫do迴圈
End If
End If
timeOut += 1
If timeOut >= 500 Then
TextBox2.Text += "執行超時,強制中斷." + vbNewLine
Exit Do
ElseIf outputTemp.Length >= 200 Then
TextBox2.Text += "輸出字串超出上限,強制中斷." + vbNewLine
Exit Do
End If
Loop Until exInput(num, exCount) = "" 'input全數執行完畢,跳脫do迴圈
If Button1.Enabled = False Then lockButton() '按鈕解鎖
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs)
num -= 1
Button3.Enabled = True
If num = 0 Then
Button2.Enabled = False
End If
setQuestion()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs)
num += 1
Button2.Enabled = True
If question(num + 1) = "" Then
Button3.Enabled = False
End If
setQuestion()
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs)
num = ComboBox1.SelectedIndex
Button2.Enabled = True
Button3.Enabled = True
If num = 0 Then
Button2.Enabled = False
ElseIf question(num + 1) = "" Then
Button3.Enabled = False
End If
setQuestion()
End Sub
Sub setQuestion()
TextBox3.Text = "第 " & (num + 1) & " 題:" + question(num) + vbNewLine +
"範例輸入:" + input(num) + vbNewLine + "範例輸出:" + output(num)
TextBox1.Text = example(num)
TextBox2.Text = "計算過程:"
ComboBox1.SelectedIndex = num
End Sub
Sub lockButton() '控制按鈕開關
Button1.Enabled = Not Button1.Enabled
If num > 0 Then
Button2.Enabled = Not Button2.Enabled
End If
If question(num + 1) <> "" Then
Button3.Enabled = Not Button3.Enabled
End If
ComboBox1.Enabled = Not ComboBox1.Enabled
TextBox1.ReadOnly = Not TextBox1.ReadOnly
End Sub
Function checkCommand()
Dim command() As String = TextBox1.Text.Split(vbCrLf)
For i = 0 To command.Length - 1
command(i) = command(i).Replace(vbCr, "").Replace(vbLf, "")
Dim comTemp() As String = Split(command(i), "=")
If Mid(comTemp(0), 1, 1) = "#" Then
Continue For '跳過註解
ElseIf command(i).Length = 0 Then
Continue For '跳過空白行
End If
If comTemp.Length = 1 Then
TextBox2.Text += "語法錯誤." + vbNewLine
TextBox2.Text += "第 " & (i + 1) & " 行程式碼,沒有包含 = 符號" & vbNewLine
Return False
ElseIf comTemp.Length > 2 Then
TextBox2.Text += "語法錯誤." + vbNewLine
TextBox2.Text += "第 " & (i + 1) & " 行程式碼,包含2個以上的 = 符號" & vbNewLine
Return False
End If
If Mid(comTemp(0), 1, 8) = "(return)" Then '辨識關鍵字(左)
TextBox2.Text += "語法錯誤." + vbNewLine
TextBox2.Text += "第 " & (i + 1) & " 行程式碼,(return)只能放在 = 的右邊" & vbNewLine
Return False
End If
If Mid(comTemp(1), 1, 6) = "(once)" Then '辨識關鍵字(右)
TextBox2.Text += "語法錯誤." + vbNewLine
TextBox2.Text += "第 " & (i + 1) & " 行程式碼,(once)只能放在 = 的左邊" & vbNewLine
Return False
End If
Next
Return True
End Function
Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs)
TextBox2.SelectionStart = TextBox2.Text.Length '捲動TextBox到最下方
TextBox2.ScrollToCaret()
End Sub
End Class