在樹梅派安裝及測試 MQTT Server – mosquitto

主要參考網址:
Mosquitto Debian repository
Installing MQTT Broker(Mosquitto) on Raspberry Pi
MQTT学习笔记——树莓派MQTT客户端 使用Mosquitto和paho-python
Ameba Arduino: 使用MQTT上傳與傾聽資料

1.安裝 mosquitto 伺服器

// 切換為管理者
sudo su

// 下載 mosquitto 認證 KEY
wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key

// 加入至 APT 伺服器中
apt-key add mosquitto-repo.gpg.key

// 加入清單列表
cd /etc/apt/sources.list.d/
wget http://repo.mosquitto.org/debian/mosquitto-jessie.list

// 更新 APT 伺服器,使其連結 mosquitto
apt-get update
apt-cache search mosquitto

// 安裝
apt-get install mosquitto  mosquitto-clients

2.測試 MQTT

// 假設:
// Topic 名稱為 myTopic
// MQTT 伺服器所在 IP 為 192.168.0.201

// 在電腦一執行:訂閱 myTopic 資料
mosquitto_sub -h 192.168.0.201 -t myTopic

// 在電腦二執行:發布訊息至 myTopic
mosquitto_pub -h 192.168.0.201 -t myTopic -m "testMsg"

// 此時在電腦一畫面便可發現 testMsg 訊息

MQTT01

注意問題:
1.MQTT 預設通訊埠為 1883,防火牆可能會阻擋。
2.Ameba 的發佈功能仍有問題。
3.如果發現 1883 被占用,可以使用 pkill mosquito 指令,將當在記憶體內部的 MQTT 強迫關閉。
 可以用以下指令,查看系統中是否有應用程式在使用1883埠
 ps -ef | grep mosq && netstat -tln | grep 1883

在 Raspberry Pi 3 安裝 OpenCV

相關安裝文章可以參考:
Install guide: Raspberry Pi 3 + Raspbian Jessie + OpenCV 3
Raspberry Pi:Raspbian編譯OpenCV原始碼
http://vincecc.blogspot.tw/2013/09/opencv-extract-colors-hsv.html

0.請先切換至最高權限root

sudo su

1.更新系統

apt-get update

2.安裝轉譯程式

apt-get install build-essential

3.聲音與影像的編碼和解碼

apt-get install libavformat-dev

4.聲音與影像的轉碼
注意:在樹梅派3無法直接安裝ffmpeg,需要自行make。
參考網站1:Installing FFMPEG for Raspberry Pi
參考網站2:Raspberry Pi: Streaming video to Ustream – Ustream Support
參考網站3:ffmpeg – Debian Wiki

apt-get install git libav-tools
cd /usr/src
sudo mkdir ffmpeg
sudo chown pi:users ffmpeg
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
./configure
make
make install

5.Opencv基本函式庫
注意:版本須注意隨時會更新。

apt-get install libcv2.4
apt-get install libcvaux2.4
apt-get install libhighgui2.4

6.Opencv-python版套件(必要)

apt-get install python-opencv

7.Opencv技術文件

apt-get install opencv-doc

8.顯示更多用來編譯opencv的開發工具

apt-get install libcvaux-dev

9.顯示opencv標頭檔和靜態資料庫

apt-get install libcv-dev

10.另一個顯示opencv標頭檔和靜態資料庫

apt-get install libhighgui-dev

4-1:資料結構(樹)—輸出二元樹的後序拜訪的結果

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _4_1
{
    class Node<T>
    {
        public Node<T> Left { get; internal set; }
        public Node<T> Right { get; internal set; }
        public Node<T> Parent { get; internal set; }
        public T Value { get; internal set; }
        public Node(T value)
        {
            Value = value;
        }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }

        string retVisited = "";

        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            List<Node<int>> ls;

            rdFile(inFile, out ls);

            for (int i = 0; i < ls.Count; i++)
            {
                retVisited = "";
                postOrder(ls[i]);

                retVisited = retVisited.Trim().Replace(' ', ',');
                sw.WriteLine(retVisited);
            }
            sw.WriteLine();
            sw.Close();
        }

        void postOrder(Node<int> thisNode)
        {
            // 先拜訪左樹
            if (thisNode.Left != null)
                postOrder(thisNode.Left);
            // 再拜訪右樹
            if (thisNode.Right != null)
                postOrder(thisNode.Right);

            retVisited += (thisNode.Value.ToString() + " ");
        }

        void addNode(Node<int> thisNode, int addValue)
        {
            if (addValue > thisNode.Value)
            { // 比根大,加入右樹
                if (thisNode.Right == null)
                    thisNode.Right = new Node<int>(addValue);
                else
                    addNode(thisNode.Right, addValue);
            }
                
            else
            { // 比根小,加入左樹
                if (thisNode.Left == null)
                    thisNode.Left = new Node<int>(addValue);
                else
                    addNode(thisNode.Left, addValue);
            }
                
        }

        void rdFile(string inFile, out List<Node<int>> ls)
        {
            StreamReader sr = new StreamReader(inFile);
            int rNum = int.Parse(sr.ReadLine());
            ls = new List<Node<int>>();

            for (int j = 0; j < rNum; j++)
            {
                sr.ReadLine();
                string[] row = sr.ReadLine().Split(new char[] { ',' });
                Node<int> r = new Node<int>(int.Parse(row[0]));

                for (int i = 1; i < row.Length; i++)
                    addNode(r, int.Parse(row[i]));

                ls.Add(r);
            }            
            sr.Close();
        }
    }
}

3-2:其他—矩陣的乘法

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _3_2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }


        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            int[][,] A, B, AB;
            int m, r, n, _m, _r, _n;
            long sum = 0, div = 0;
            rdFile(inFile, out A, out B, out AB);

            for (int i = 0; i < A.Length; i++)
            {
                m = A[i].GetUpperBound(0) + 1;
                r = A[i].GetUpperBound(1) + 1;
                n = B[i].GetUpperBound(1) + 1;

                for (_m = 0; _m < m; _m++)
                {
                    for (_n = 0; _n < n; _n++)
                    {
                        sum = 0;
                        for (_r = 0; _r < r; _r++)
                            sum += A[i][_m, _r] * B[i][_r, _n];
                        
                        if (sum != AB[i][_m, _n])
                        {
                            sum = AB[i][_m, _n];
                            for (_r = 0; _r < r; _r++)
                            {
                                if(A[i][_m, _r]!=9999 && B[i][_r, _n]!=9999)
                                    sum -= A[i][_m, _r] * B[i][_r, _n];
                                else if(A[i][_m, _r] != 9999)
                                    div = A[i][_m, _r];
                                else
                                    div = B[i][_r, _n];
                            }
                            sum /= div;
                            sw.WriteLine(sum);
                            break;
                        }
                    }
                    if (_n < n) break;
                }
            }
            sw.WriteLine();
            sw.Close();
        }

        void rdFile(string inFile, out int[][,] A, out int[][,] B, out int[][,] AB)
        {
            StreamReader sr = new StreamReader(inFile);
            int rNum = int.Parse(sr.ReadLine());

            A = new int[rNum][,];
            B = new int[rNum][,];
            AB = new int[rNum][,];

            for (int i = 0; i < rNum; i++)
            {
                string[] sizeOfArray = sr.ReadLine().Split(new char[] { ',' });
                int m = int.Parse(sizeOfArray[0]);
                int r = int.Parse(sizeOfArray[1]);
                int n = int.Parse(sizeOfArray[3]);
                A[i] = new int[m, r];
                B[i] = new int[r, n];
                AB[i] = new int[m, n];

                int j, k;
                string[] ts;
                for (j = 0; j < m; j++)
                {
                    ts = sr.ReadLine().Split(new char[] { ' ', '\t' });
                    for (k = 0; k < r; k++)
                        A[i][j, k] = int.Parse(ts[k]);
                }

                for (j = 0; j < r; j++)
                {
                    ts = sr.ReadLine().Split(new char[] { ' ', '\t' });
                    for (k = 0; k < n; k++)
                        B[i][j, k] = int.Parse(ts[k]);
                }

                for (j = 0; j < m; j++)
                {
                    ts = sr.ReadLine().Split(new char[] { ' ', '\t' });
                    for (k = 0; k < n; k++)
                        AB[i][j, k] = int.Parse(ts[k]);
                }
            }

            sr.Close();
        }
    }
}

3-1:其他—計算位元為1 的個數

Problem 3:其他
子題 1:計算位元為1 的個數。(程式執行限制時間: 2 秒) 10 分
計算機概論中的數字系統轉換,內容是將一個十進位的數字,轉換成二進位的數字。現在請
你設計一個程式,計算由十進位數字(整數)轉換的二進位數字中,位元值為1 的位元個數。
輸入說明:
第一列的數字 n 代表有幾筆資料要測試, 。第二列起為測試資料,測試資料每一列
為一個十進位數字(整數) 。
輸出說明:
對每一列的十進位數字,分別以一列輸出,計算轉換成二位進數字中,位元值為1 的位元個
數。
輸入檔案 1:【檔名:in1.txt】
2
1025
65535
輸入檔案 2:【檔名:in2.txt】
2
0
3
輸出範例:【檔名:out.txt】
2
16
0
2

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _3_1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }

        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            int[] dt;
            rdFile(inFile, out dt);

            for (int i = 0; i < dt.Length; i++)
            {
                int s = 0;
                while(dt[i]!=0)
                {
                    s += (dt[i] % 2);
                    dt[i] = dt[i] / 2;
                }
                sw.WriteLine(s);
            }

            sw.WriteLine();
            sw.Close();
        }

        void rdFile(string inFile, out int[] dt)
        {
            StreamReader sr = new StreamReader(inFile);
            int rNum = int.Parse(sr.ReadLine());
            dt = new int[rNum];
            for (int i = 0; i < rNum; i++)
                dt[i] = int.Parse(sr.ReadLine());
            sr.Close();
        }
    }
}

2-2:數學問題—最大公約數計算

子題2:最大公約數計算。(程式執行限制時間: 2 秒) 11分
最大公因數(Greatest Common Divisor,簡寫為G.C.D.),指某幾個正整數共有因數中最大的一個。例如數字20,8和30的最大公因數為2。

GCD(20,8,30)=2

輸入說明:
第一列的數字n代表有幾筆資料要測試, ,第二列起為測試資料,之後每列為每筆測試資料,每筆測試資料至少有2個正整數最多有5個正整數,正整數數字 , 。各個數字間以“,”隔開。

輸出說明:
每筆測試資料輸出一列。算出每列這幾個正整數的最大公因數。

輸入檔案1:【檔名:in1.txt】
3
20,8,30
10,20,30
8,12

輸入檔案2:【檔名:in2.txt】
3
24,60,36
2,65535
2,3,4,5,6

輸出範例:【檔名:out.txt】
2
10
4

12
1
1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _2_2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }

        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            int[][] row;
            int i, j, k;
            rdFile(inFile, out row);

            for (i = 0; i < row.Length; i++)
            {
                for (j = row[i].Max(); j >= 1; j--)
                {
                    for (k = 0; k < row[i].Length; k++)
                        if (row[i][k] % j != 0) break;

                    if (k == row[i].Length)
                    {
                        sw.WriteLine(j);
                        break;
                    }
                }
            }
            sw.WriteLine();
            sw.Close();
        }

        void rdFile(string inFile, out int[][] rowData)
        {
            StreamReader sr = new StreamReader(inFile);
            int rNum = int.Parse(sr.ReadLine());
            rowData = new int[rNum][];

            for (int i = 0; i < rNum; i++)
            {
                string[] row = sr.ReadLine().Split(new char[] { ',' });
                rowData[i] = new int[row.Length];
                for (int j = 0; j < row.Length; j++)
                    rowData[i][j] = int.Parse(row[j]);
            }
            sr.Close();
        }
    }
}

2-1:數學問題—排列組合

可以先練習,給一個數字N,並印出0~N,所有的排列

子題1:排列組合。(程式執行限制時間: 3秒) 13分
在排列組合問題中將一組數字進行排列,可以得到不同的數字順序,例如12這個數的排列共有:(1)12、(2)21二組(由小到大排序);例如123這個數的排列組合順序為:(1)123、(2)132、(3)213、(4)231、(5)312、(6)321六組(由小到大排序);例如1234這數的排列組合有24組,數列順序如下:
(1)1234 (2)1243 (3)1324 (4)1342 (5)1423 (6)1432
(7)2134 (8)2143 (9)2314 (10)2341 (11)2413 (12)2431
(13)3124 (14)3142 (15)3214 (16)3241 (17)3412 (18)3421
(19)4123 (20)4132 (21)4213 (22)4231 (23)4312 (24)4321

輸入說明:
第一列的數字n代表有幾筆資料要測試, ,之後每列為每筆的測試資料,共有三個正整數 。各個數字間以“,”隔開。i的值為 其中之一,而j和k代表i值排列組合順序(由小到大排序)的第j個和第k個值。j和k不會超出i的排列數,請輸出第j個和第k個值的總合。
例如 這組測試資料中,12這個數的排列組合有:(1)12、(2)21二組(由小到大排序),第1個值為12;第2個值為21;總合為12+21=33。
例如 這組測試資料中,123這個數的排列組合有:(1)123、(2)132、(3)213、(4)231、(5)312、(6)321六組(由小到大排序),第1個值為123;第2個值為132;總合為123+132=255。
例如 這組測試資料中,123這個數的排列組合有:(1)123、(2)132、(3)213、(4)231、(5)312、(6)321六組(由小到大排序),第2個值為132;第5個值為312;總合為132+312=444。
例如 這組測試資料中,1234這個數的排列組合有24組(由小到大排序),第15個值為3214;第9個值為2314;總合為3214+2314=5528。
例如 這組測試資料中,1234這個數的排列組合有24組(由小到大排序),第3個值為1324;第4個值為1342;總合為1324+1342=2666。

輸出說明:
每筆測試資料輸出一列。輸出以i值排列組合順序中,找出第j個和第k個的值,再算出個這二個值的總合。

輸入檔案1:【檔名:in1.txt】
3
12,1,2
123,1,2
123,2,5

輸入檔案2:【檔名:in2.txt】
2
1234,15,9
1234,3,4

輸出範例:【檔名:out.txt】
33
255
444

5528
2666

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _2_1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }

        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            string[][] ls;
            rdFile(inFile, out ls);

            for (int i = 0; i < ls.Length; i++)
            {
                List<string> numSerial = new List<string>();
                arrange(ls[i][0], "", numSerial);
                int j = int.Parse(ls[i][1])-1, k = int.Parse(ls[i][2])-1;
                sw.WriteLine(int.Parse(numSerial[j]) + int.Parse(numSerial[k]));
            }
            sw.WriteLine();
            sw.Close();
        }

        void arrange(string s, string d,List<string> numSerial)
        {
            if (d.Length == s.Length)
                numSerial.Add(d);
            else
                foreach (char i in s)
                    if (d.IndexOf(i) == -1)
                        arrange(s, d + i, numSerial);
        }

        // x!
        int s(int x)
        {
            if (x == 0) return 1;   // 0! = 1
            if (x <= 2) return x;   // 1! = 1 , 2! = 2
            else return x * s(x - 1);
        }

        void rdFile(string path, out string[][] ls)
        {
            StreamReader sr = new StreamReader(path);
            int rNum = int.Parse(sr.ReadLine());
            ls = new string[rNum][];
            for (int i = 0; i < rNum; i++)
                ls[i] = sr.ReadLine().Split(new char[] { ',' });
        }
    }
}

1-1:生活問題—電梯電費計算系統

子題1:電梯電費計算系統。 (程式執行限制時間: 2 秒) 9分
假設你身為一個電梯公司的工程師,正要為某個百貨公司的電梯設計一套電費計算系統,計算百貨公司的電梯某時段所耗的電費是多少。以下是電梯所耗電力之電費的規則:
(1) 電梯上樓時,每經過一個樓層,所需電費為 20元。
(2) 電梯下樓時,每經過一個樓層,所需電費為10 元。
(3) 假設電梯停在某一個樓層時不會耗電。
舉例來說:電梯從3樓到8 樓再到5 樓,則所耗的電費為:從3樓到8 樓,所耗的電費是 元;電梯從8 樓到5 樓,所耗的電費是 元。所以總共花了130 元。

輸入說明:
第一列的數字n代表有幾組資料要測試, ,第二列起為每組的測試資料,之後每二列為每組的測試資料。每組測試資料第一列是一個整數 ,用來表示某時段電梯所停過的樓層數;每組測試資料第二列是一組以“,”分隔的 個數字(相鄰的數字不會相同),分別表示電梯先後停過的樓層。輸入測試資料的電梯樓層最高不會超過 20 樓(含)。

輸出說明:
每組測試資料輸出一列。請根據電梯上下運作的樓層,計算出某時段電梯運作所花的電費。

輸入檔案1:【檔名:in1.txt】
2
3
3,8,5
7
2,9,7,3,4,6,1

輸入檔案2:【檔名:in2.txt】
2
3
18,19,20
3
2,5,2

輸出範例:【檔名:out.txt】
130
310

40
90

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _1_1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }

        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            List<Array> ls = new List<Array>();

            rdFile(inFile, ls);

            foreach (int[] item in ls)
            {
                int cost = 0;
                for (int i = 0; i < item.Length-1; i++)
                {
                    int j = item[i] - item[i + 1];
                    if (j < 0)
                        cost += (-j * 20);
                    else
                        cost += (j * 10);
                }
                sw.WriteLine(cost);
            }
            sw.WriteLine();
            sw.Close();
        }

        void rdFile(string path, List<Array> ls)
        {
            StreamReader sr = new StreamReader(path);
            int rNum = int.Parse(sr.ReadLine());

            for (int i = 0; i < rNum; i++)
            {
                sr.ReadLine();
                string[] row = sr.ReadLine().Split(new char[] { ',' });
                int[] data = new int[row.Length];
                for (int j = 0; j < row.Length; j++)
                    data[j] = int.Parse(row[j]);
                ls.Add(data);
            }

            sr.Close();
        }
    }
}

1-2:生活問題—樂透

建議閱讀【不盡相異物排列】相關主題後,再來試作本題。
本題也可採用暴力法,但會相當費工夫…

http://eprob.math.nsysu.edu.tw/
https://www.junyiacademy.org/search?page_search_query=%E6%8E%92%E5%88%97

子題2:樂透。(程式執行限制時間: 2 秒) 12分
今彩539是一種樂透型遊戲,投注者必須從01~39的號碼中任選5個不同的號碼進行投注。開獎時,開獎單位將隨機開出五個號碼,這一組號碼就是該期今彩539的中獎號碼,也稱為「獎號」。投注者的五個選號中,如有二個以上(含二個號碼)對中當期開出之五個中獎號碼,即為中獎。

為了方便包牌,投注者可任選6個不同號碼,共可以產生6組不同的5個號碼組合。用程式計算投注者任選的6個不同號碼的包牌的組合,各對中2碼(對中當期獎號之其中任二碼)、3碼、4碼及5碼的次數。

輸入說明:
第一列的數字n代表有幾組資料要測試, 。第二列為該期今彩539的中獎號碼(獎號),已由小到大排序好。第三列起為測試資料,每組測試資料為一列,有6個數字,是投注者任選的6個不同號碼,各個號碼間以“,”隔開,已由小到大排序好。

輸出說明:
計算每組測試資料中,獎號和投注者的6個號碼,用程式計算投注者任選的6個不同號碼所組合的6種不同投注,對中2碼(對中當期獎號之其中任二碼) 、3碼、4碼及5碼各中幾次,各個對中次數間以“,”隔開,且輸出順序依規定。

例如今彩539的中獎號碼為01,07,28,29,30:投注者任選的6個不同號碼為01,07,29,30,36,39
6種不同投注為:(底線是為了方便比對中獎號碼)
07,29,30,36,39對中3碼
01,29,30,36,39對中3碼
01,07,30,36,39對中3碼
01,07,29,36,39對中3碼
01,07,29,30,39對中4碼
01,07,29,30,36對中4碼
在這6個不同號碼對中2碼0次;3碼4次;4碼2次;5碼0次;則輸出0,4,2,0。

例如今彩539的中獎號碼為01,07,28,29,30:投注者任選的6個不同號碼為01,07,22,23,24,38
6種不同投注為:
07,22,23,24,38對中1碼
01,22,23,24,38對中1碼
01,07,23,24,38對中2碼
01,07,22,24,38對中2碼
01,07,22,23,38對中2碼
01,07,22,23,24對中2碼
在這6個不同號碼對中2碼4次;3碼0次;4碼0次;5碼0次;則輸出4,0,0,0。
例如今彩539的中獎號碼為21,22,23,24,32:投注者任選的6個不同號碼為21,22,23,24,25,32
6種不同投注為:
22,23,24,25,32對中4碼
21,23,24,25,32對中4碼
21,22,24,25,32對中4碼
21,22,23, 25,32對中4碼
21,22,23,24, 32對中5碼
21,22,23,24,25對中4碼
在這6個不同號碼對中2碼0次;3碼0次;4碼5次;5碼1次;則輸出0,0,5,1

輸入檔案1:【檔名:in1.txt】
2
01,07,28,29,30
01,07,29,30,36,39
01,07,22,23,24,38

輸入檔案2:【檔名:in2.txt】
2
21,22,23,24,32
01,02,03,04,05,06
21,22,23,24,25,32

輸出範例:【檔名:out.txt】
0,4,2,0
4,0,0,0

0,0,0,0
0,0,5,1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace _1_2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            run("in1.txt", "out.txt", false);
            run("in2.txt", "out.txt", true);
            run("in3.txt", "out.txt", true);
            run("in4.txt", "out.txt", true);
        }

        void run(string inFile, string outFile, bool append)
        {
            StreamWriter sw = new StreamWriter(outFile, append);
            int[][] ls;
            rdFile(inFile, out ls);

            for (int i = 0; i < ls.Length; i++)
            {
                for (int j = 2; j <= 5; j++)
                {
                    sw.Write(arrange(ls[i][0], j, false) * arrange(ls[i][1], 5 - j, false));
                    if (j != 5) sw.Write(',');
                }
                sw.WriteLine();
            }
            sw.WriteLine();
            sw.Close();
        }

        // x 取 n 個
        // b=True  相異物排列(1,2,3!=2,1,3!=3,1,2!=...)
        // b=False 不盡相異物排列(1,2,3=2,1,3=3,1,2=...)
        int arrange(int x, int n, bool b)
        {
            if (n > x) return 0;        // 數量不夠取
            else if (n == x) return 1;  // 母群 = 子群

            if(b) return s(x) / s(x - n);
            else return s(x) / s(x - n) / s(n);
        }

        // x!
        int s(int x)
        {
            if (x == 0) return 1;   // 0! = 1
            if (x <= 2) return x;   // 1! = 1 , 2! = 2
            else return x * s(x - 1);
        }

        void rdFile(string path, out int[][] ls)
        {
            StreamReader sr = new StreamReader(path);
            int rNum = int.Parse(sr.ReadLine());

            string[] lotto = sr.ReadLine().Split(new char[] { ',' });
            ls = new int[rNum][];

            for (int i = 0; i < rNum; i++)
            {
                ls[i] = new int[2];
                string[] ts = sr.ReadLine().Split(new char[] {','});
                for (int j = 0; j < ts.Length; j++)
                    if (Array.IndexOf(lotto, ts[j]) != -1)
                        ls[i][0]++;     // 中獎數量
                    else
                        ls[i][1]++;     // 未中獎數量
            }
        }

    }
}