一個 Lua 的湊24程式

來源:互聯網
上載者:User

上次看到一個“湊24”的題目但想不出來- -b,所以蛋疼地寫了個程式來算。。。現在終於知道答案了。。。

 

這個湊24程式沒有用搜尋或遞迴之類,想法就是先用逆波蘭式枚舉所有可能的運算式的形式(這個直接手算枚舉),共 5 種:

11+1+1+
11+11++
111++1+
111+1++
1111+++

上面是由 4 個數字和 3 個運算子組成的所有合法的逆波蘭式的模式。“1”表示一個數字,而“+”表示一個運算子。然後枚舉每一個數字和運算子。總枚舉量為:5 * 4! * 4^3 = 7680,枚舉量很小,所以直接窮舉即可。

 

代碼:

-- 計算逆波蘭式<br />-- (table) -> number<br />function evalPo(e)<br /> local s = {} -- a stack<br /> local a, b, c<br /> for i, v in ipairs(e) do<br /> if type(v) == "number" then<br /> table.insert(s, v)<br /> elseif type(v) == "string" then<br /> if #s < 2 then<br /> error('not enough values')<br /> end<br /> b = table.remove(s)<br /> a = table.remove(s)<br /> if v == '+' then<br /> c = a + b<br /> elseif v == '-' then<br /> c = a - b<br /> elseif v == '*' then<br /> c = a * b<br /> elseif v == '/' then<br /> if b == 0 then<br /> return nil, 'divided by 0'<br /> else<br /> c = a / b<br /> end<br /> else<br /> error('bad operator: '..v)<br /> end<br /> table.insert(s, c)<br /> end<br /> end<br /> if #s ~= 1 then<br /> return nil, 'not enough operators'<br /> end<br /> return s[1]<br />end</p><p>-- 將逆波蘭式轉換成普通運算式,用於輸出<br />-- (table) -> string<br />function RPNtoExp(e)<br /> local s = {} -- a stack<br /> local a, b, c<br /> for i, v in ipairs(e) do<br /> if type(v) == "number" then<br /> table.insert(s, v)<br /> elseif type(v) == "string" then<br /> if #s < 2 then<br /> error('not enough values')<br /> end<br /> b = table.remove(s)<br /> a = table.remove(s)<br /> table.insert(s, '('..a..v..b..')')<br /> end<br /> end<br /> if #s ~= 1 then<br /> return nil, 'not enough operators'<br /> end<br /> return s[1]<br />end</p><p>-- 前4列表示4個數字在逆波蘭式中的位置,後3列表示3個運算子在逆波蘭式中的位置<br />-- 這個表是手算出來的<br />local RPN_patterns = {<br /> {1, 2, 4, 6, 3, 5, 7},<br /> {1, 2, 4, 5, 3, 6, 7},<br /> {1, 2, 3, 6, 4, 5, 7},<br /> {1, 2, 3, 5, 4, 6, 7},<br /> {1, 2, 3, 4, 5, 6, 7}<br />}</p><p>local ar = {}<br />io.write('Please input 4 numbers: ')<br />for i = 1, 4 do<br /> ar[i] = io.read('*n')<br />end</p><p>local operators = {'+', '-', '*', '/'}</p><p>-- 逆波蘭式<br />local exp = {}</p><p>for a = 1, 4 do<br /> for b = 1, 4 do<br /> if b ~= a then<br /> for c = 1, 4 do<br /> if c ~= a and c ~= b then<br /> for d = 1, 4 do<br /> if d ~= a and d ~= b and d ~= c then<br /> for i = 1, 4 do<br /> for j = 1, 4 do<br /> for k = 1, 4 do<br /> for m = 1, 5 do<br /> exp[RPN_patterns[m][1]] = ar[a]<br /> exp[RPN_patterns[m][2]] = ar[b]<br /> exp[RPN_patterns[m][3]] = ar[c]<br /> exp[RPN_patterns[m][4]] = ar[d]<br /> exp[RPN_patterns[m][5]] = operators[i]<br /> exp[RPN_patterns[m][6]] = operators[j]<br /> exp[RPN_patterns[m][7]] = operators[k]<br /> local t = evalPo(exp)<br /> if t == 24 then<br /> io.write(RPNtoExp(exp), '/n')<br /> os.exit()<br /> end<br /> end<br /> end<br /> end<br /> end<br /> end<br /> end<br /> end<br /> end<br /> end<br /> end<br />end<br />print('Maze24 has no idea.')

如果你的電腦上沒有 Lua 解譯器,也可以用 codepad(http://codepad.org/)來線上運行這段代碼。但 codepad 無法輸入,所以你需要稍微修改一下代碼:

 

把 'Please input 4 numbers: ' 後面的那個 for 迴圈去掉,改成:

ar = {5, 5, 5, 1}

或者填入其他你想要湊 24 的 4 個數字。

 

PS. 順便附 3 組收藏的湊 24 題目:

 

1 4 5 6
6 7 -6 2 // 還負數呢,我勒個去
4 4 10 10

 

如果想不出來,用上面的程式看答案吧:P

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.