标题: [其他] 批处理及多种语言实现 CWHGN猜数字 [打印本页]
作者: happy886rr 时间: 2017-8-9 22:00 标题: 批处理及多种语言实现 CWHGN猜数字
我先用看似单纯的批处理去实现CWHGN猜数字游戏,虽然批处理不支持发送请求,但凭借调用一个4行的外部js可以实现网络请求功能。索性集成到一个批文。由于该题目涉及到数组的频繁操作,每次post批处理需要先筛选几千次,因此 处理较大的数组 就暴露了其运行缓慢的缺陷:每分钟猜题速度10左右。若改用位运算可以缓解一些,但提速不大。测试效果和代码如下:
(图片引用均为外部链接)
[批处理实现]略带js混编- 1>1/* :
- @echo off
- REM 开启变量延迟
- setlocal enabledelayedexpansion
-
- REM 设置全局变量
- set "USER_NAME=adad"
- set "PASS_WORD=123"
- set "POST_URL=http://www.codetiger.win/extra/API.php"
-
- REM 生成[0-9]的四位全排列数
- set "PM_LENGTH=0"
- for /l %%i in (0,1,9) do (
- for /l %%j in (0,1,9) do (
- for /l %%k in (0,1,9) do (
- for /l %%l in (0,1,9) do (
- 2> NUL set/a "1/((%%i-%%j)*(%%i-%%k)*(%%i-%%l)*(%%j-%%k)*(%%j-%%l)*(%%k-%%l))" && (
- set/a "PM_LENGTH+=1"
- set "PM[!PM_LENGTH!]=%%i%%j%%k%%l"
- )
- )
- )
- )
- )
-
- REM 初始化标记数组
- for /l %%i in (1,1,!PM_LENGTH!) do (
- set "PM_MARK[%%i]=1"
- )
-
- REM 初始化变量值
- set/a "RESP_TOKENS=0, RESP_DATA=0, GUESS_TIMES=0, CUR_INDEX=1"
-
- REM 锚点
- :LOOP1
- REM 利用局部变量表,实现快速初始化
- setlocal
-
- REM 内层循环
- :LOOP2
- REM 变量中转
- for %%a in (!CUR_INDEX!) do (
- set "GUESS_NUMBER=!PM[%%a]!"
- )
-
- REM 向服务器发送请求,并处理返回json格式
- for /f "tokens=2,4,6,8,10 delims=,:{}" %%a in ('cscript -nologo -e:jscript "%~f0" "%POST_URL%" "%USER_NAME%" "%PASS_WORD%" !GUESS_NUMBER!') do (
-
- REM 猜数计次器
- set/a "GUESS_TIMES+=1"
-
- REM 显示界面
- set/a "DIS_CUR_INDEX=10000+CUR_INDEX"
- echo #POST:{PM[!DIS_CUR_INDEX:~-4!]=!GUESS_NUMBER!} #RESP_JSON:{%%a %%b %%c %%d %%e}
-
- REM 网络检测器
- if "%%e"=="" (
- echo Requests error^^!
- endlocal
- goto :LOOP1
- )
-
- REM 答案验证器
- if "%%b"=="4" (
- echo Takes:[!GUESS_TIMES!th], Answer:!GUESS_NUMBER!, Score:[%%d]
- endlocal
- goto :LOOP1
- )
-
- REM TOKENS重置器
- if "!RESP_TOKENS!"=="0" (
- set "RESP_TOKENS=%%e"
- ) else (
- if not "!RESP_TOKENS!"=="%%e" (
- echo Reset...
- endlocal
- goto :LOOP1
- )
- )
-
- REM 计算猜测权值
- set/a "R_WEIGHTS=%%b*5+%%c, NEW_INDEX=0"
-
- REM 权值筛选器
- for /l %%i in (1,1,!PM_LENGTH!) do (
- if !PM_MARK[%%i]! equ 1 (
- set "T_WEIGHTS=0"
-
- REM 数码比对器
- for /l %%p in (0,1,3) do (
- for /f "tokens=1,2" %%A in ("!PM[%%i]:~%%p,1! !CUR_INDEX!") do (
- if not "!PM[%%B]:%%A=!"=="!PM[%%B]!" (
- if "!PM[%%B]:~%%p,1!"=="%%A" (
- set/a "T_WEIGHTS+=5"
- ) else (
- set/a "T_WEIGHTS+=1"
- )
- )
- )
- )
-
- REM 筛选标记器
- if !T_WEIGHTS! neq !R_WEIGHTS! (
- set "PM_MARK[%%i]=0"
- ) else (
- if !CUR_INDEX! neq %%i (
- set "NEW_INDEX=%%i"
- )
- )
- )
- )
-
- REM 索引价值判定
- if !NEW_INDEX! neq 0 (
- set "CUR_INDEX=!NEW_INDEX!"
- goto :LOOP2
- ) else (
- echo Fault.
- endlocal
- goto :LOOP1
- )
- )
-
- REM 内层循环结尾
- goto :LOOP2
- */
- var xmlHTTP=new ActiveXObject('Msxml2.XMLHTTP');
- xmlHTTP.open('SEND', WScript.arguments(0) + '?username=' + WScript.arguments(1) + '&password=' + WScript.arguments(2) + '&send=answer&number=' + WScript.arguments(3), false);
- xmlHTTP.send();
- WScript.echo(xmlHTTP.responseText);
复制代码
.
.
之后我改用了java语言,采用正则表达式去解析json。由于java是字节码,运行速度已经发送了质的改变。将它编译成了跨平台jar包后,可以在多种设备上运行。在手机上跑,无需jre,以微乎其微的耗电量和ARM芯片占用率刷榜单。 请下载附件后 (把zip后缀改成jar即可运行):链接: https://pan.baidu.com/s/1qiEzR32fxyorm9SZGBUXVQ?pwd=345e
调用参数cwhgn.jar -u [用户名] -p [用户密码], 当用户名未注册时,程序会自动帮你注册。手机端建议使用ej 脚本运行。
[java实现]Main.java- package com.android.test;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.io.PrintWriter;
- import java.net.URL;
- import java.net.URLConnection;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
-
-
- /**
- * @author Happy from Bathome
- * @time
- */
- public class Main
- {
- private static final String REGU_URL = "http://www.codetiger.win/extra/index.php";
- private static final String POST_URL = "http://www.codetiger.win/extra/API.php";
- private static final int MAX_ARRAY_SIZE = 5040;
- private static boolean[] markPmArray = new boolean[MAX_ARRAY_SIZE];
-
- private static final Pattern reCode = Pattern.compile("\\{\\\"code\\\":(\\d+)");
- private static final Pattern re = Pattern.compile("\\{\\\"code\\\":(\\d+),\\\"A\\\":(\\d+),\\\"B\\\":(\\d+),\\\"count\\\":(\\d+),\\\"tokens\\\":\\\"(\\d+)\\\"\\}");
- private static ResponseJson responseJson = new ResponseJson();
-
- public static void main(String[] args)
- {
- if(args.length !=4 || !args[0].equals("-u") || !args[2].equals("-p"))
- {
- System.out.println("Usage: java -jar cwhgn.jar -u [userName] -p [passWord]");
- System.exit(1);
- }
-
- String userName = args[1];
- String userPassword = args[3];
-
- String responseString = sendPost(POST_URL, "send=answer&number=0123&username=" + userName + "&password=" + userPassword).toString();
- Matcher m = reCode.matcher(responseString);
- if(m.find())
- {
- if(Integer.parseInt(m.group(1)) == 300)
- {
- int regRet = regUser(userName, userPassword);
- if(regRet != 100)
- {
- System.out.printf("The userName '%s' has been registered or the userPassword '%s' is wrong!\n", userName, userPassword);
- System.exit(1);
- }
- }
- }
- else
- {
- System.out.println("Please try again!");
- System.exit(1);
- }
-
- String[] pmArray = getPermutations();
- int pmArrayLen = pmArray.length;
-
- long startMilis=System.currentTimeMillis();
- long guessScore=0;
- long guessSpeed=0;
-
- while (true)
- {
- int currentIndex = 0;
- long responseTokens = -1;
- int guessTimes = 0;
-
- for(int i=0; i<MAX_ARRAY_SIZE; i++)
- {
- markPmArray[i] = true;
- }
-
- while (true)
- {
- try
- {
- responseString = sendPost(POST_URL, "send=answer&username=" + userName + "&password=" + userPassword + "&number="+ pmArray[currentIndex]).toString();
- m = re.matcher(responseString);
- if(! m.find())
- {
- System.out.println("Received data failed!");
- continue;
- //break;
- }
- responseJson.getJson(Integer.parseInt(m.group(1),10), Integer.parseInt(m.group(2),10), Integer.parseInt(m.group(3),10), Integer.parseInt(m.group(4),10), Long.parseLong(m.group(5)));
- }
- catch (Exception e)
- {
- continue;
- //break;
- }
-
- if(guessScore == 0)
- {
- guessScore = responseJson.count;
- }
-
- guessTimes ++;
-
- if(responseJson.A == 4)
- {
- if(System.currentTimeMillis()-startMilis > 6000)
- {
- guessSpeed = (responseJson.count - guessScore);
- guessScore = responseJson.count;
- startMilis = System.currentTimeMillis();
- }
-
- System.out.printf("Takes:[%d cycles], Answer:%s, Score:[%d +%d/min]\n", guessTimes, pmArray[currentIndex], responseJson.count, guessSpeed*10);
- break;
- }
-
- if(responseTokens == -1)
- {
- responseTokens = responseJson.tokens;
- }
- else if(responseTokens != responseJson.tokens)
- {
- System.out.println("Reset ...");
- break;
- }
-
- currentIndex = guessCore(pmArray, pmArrayLen, responseJson.A*5+responseJson.B, pmArray[currentIndex]);
- }
- }
- }
-
- private static int regUser(String userName, String userPassword)
- {
- String responseString = sendPost(REGU_URL, "send=reg&qq=123456789&username=" + userName + "&password="+ userPassword).toString();
- Matcher m = reCode.matcher(responseString);
- return (m.find()) ?(Integer.parseInt(m.group(1), 10)) :0;
- }
-
- private static int getWeights(String correctNum, String guessNum)
- {
- int retWeights = 0;
- for(int i=0; i<4; i++)
- {
- int digitalPosition = guessNum.indexOf((correctNum.substring(i, i+1)));
- if(digitalPosition != -1)
- {
- retWeights += (digitalPosition==i)?5:1;
- }
- }
- return retWeights;
- }
-
- private static int guessCore(String[] inputPmArray, int inputPmArrayLen, int responseWeights, String guessNum)
- {
- int markIndex = 0;
- for(int i=0; i<inputPmArrayLen; i++)
- {
- if(markPmArray[i])
- {
- if(getWeights(inputPmArray[i], guessNum) != responseWeights)
- {
- markPmArray[i] = false;
- }
- else if(markIndex == 0)
- {
- markIndex = i;
- }
- }
- }
- return markIndex;
- }
-
- private static String[] getPermutations()
- {
- String[] pmArray = new String[MAX_ARRAY_SIZE];
- int index=0;
- for(int i=0; i<10; i++)
- for(int j=0; j<10; j++)
- for(int k=0; k<10; k++)
- for(int l=0; l<10; l++)
- {
- if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)!=0)
- {
- pmArray[index++]= "" + i + j + k + l;
- }
-
- }
- return pmArray;
- }
-
- public static StringBuffer sendPost(String postURL, String postData)
- {
- PrintWriter pWriter = null;
- BufferedReader bReader = null;
- StringBuffer sBuffer = new StringBuffer("");
-
- try
- {
- URL realUrl = new URL(postURL);
- URLConnection conn = realUrl.openConnection();
-
- conn.setRequestProperty("accept", "*/*");
- conn.setRequestProperty("connection", "keep-alive");
- conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
- conn.setDoOutput(true);
- conn.setDoInput(true);
-
- pWriter = new PrintWriter(conn.getOutputStream());
- pWriter.print(postData);
- pWriter.flush();
-
- bReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
-
- String line = null;
- while ((line = bReader.readLine()) != null)
- {
- sBuffer.append(line);
- }
- }
- catch (Exception e)
- {
- System.out.println("An exception occurred while sending a POST request!"+e);
- }
- finally
- {
- try
- {
- pWriter.close();
- bReader.close();
- }
- catch (Exception e)
- {
- // TODO: handle exception
- }
- }
- return sBuffer;
- }
-
- protected static class ResponseJson
- {
- int code, A, B, count;
- long tokens;
- void getJson(int inputCode, int inputA, int inputB, int inputCount, long inputTokens)
- {
- this.code = inputCode;
- this.A = inputA;
- this.B = inputB;
- this.count = inputCount;
- this.tokens = inputTokens;
- }
- }
- }
复制代码
.
.
用其他语言的实现,思路基本相同,就当复习语法。
>>
[vbs版]- '&@echo off&cls&cscript -nologo -e:vbscript "%~f0" %*&pause&exit /b
-
- '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- Dim markPM(5040)
- GuessNumber "adad", "123", "http://www.codetiger.win/extra/API.php"
-
- '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
- Function GetPermutations()
- Dim retArray(5040), index
- index = 0
- For i = 0 To 9
- For j = 0 To 9
- For k = 0 To 9
- For l = 0 To 9
- If ((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)) <> 0 Then
- retArray(index) = i & j & k & l & ""
- index = index + 1
- End If
- Next
- Next
- Next
- Next
- GetPermutations = retArray
- End Function
-
- Function GetWeights(correctNum, guessNum)
- Dim retWeights
- retWeights = 0
- For i = 1 To 4
- For j = 1 To 4
- If Mid(correctNum, i, 1) = Mid(guessNum, j, 1) Then
- If i = j Then
- retWeights = retWeights + 5
- Else
- retWeights = retWeights + 1
- End If
- End If
- Next
- Next
- GetWeights = retWeights
- End Function
-
- Function GuessCore(arrayPM, arrayPMLen, responseWeights, guessIndex)
- Dim markIndex
- markIndex = -1
- For i = 0 To arrayPMLen-1
- If markPM(i) Then
- If GetWeights(arrayPM(i), arrayPM(guessIndex)) <> responseWeights Then
- markPM(i) = False
- ElseIf i <> guessIndex And markIndex = -1 Then
- markIndex = i
- End If
- End If
- Next
- GuessCore = markIndex
- End Function
-
- Function HttpPostData(hostURL, postString)
- Dim respJson
- With CreateObject("MSXML2.XMLHTTP")
- .Open "POST", hostURL, False
- .setRequestHeader "CONTENT-TYPE", "application/x-www-form-urlencoded"
- .setRequestHeader "CONNECTION", "Keep-Alive"
- .send postString
- respJson = .responseText
- End With
- HttpPostData = Split(replace(respJson, ":", ","), ",")
- End Function
-
- Function GuessNumber(userName, passWord, hostURL)
- Dim pmArray, pmArrayLen
- Dim startMilis, guessScore, guessSpeed
- startTime = Timer : guessScore = 0 : guessSpeed = 0
-
- pmArray = GetPermutations()
- pmArrayLen = Ubound(pmArray)
-
- Do
- Dim nIndex, responseTokens, respData, guessTimes
- responseString="" : nIndex=0 : responseTokens="" : espData="": guessTimes=0
-
- For i = 0 To pmArrayLen-1
- markPM(i) = True
- Next
-
- Do
- respData = HttpPostData(hostURL, "username=" & userName & "&password=" & passWord & "&send=answer&number=" & pmArray(nIndex))
- If Ubound(respData) + 1 <> 10 Then
- WScript.echo "Requests error!!!'"
- Exit Do
- End If
-
- If guessScore = 0 Then
- guessScore = respData(7)
- End If
-
- guessTimes = guessTimes + 1
-
- If respData(3) = "4" Then
- If Timer - startTime > 6 Then
- guessSpeed = (CLng(respData(7)) - guessScore)*10
- guessScore = CLng(respData(7))
- startTime = Timer
- End If
- WScript.echo "Takes:[" & guessTimes & "th], Answer:" & pmArray(nIndex) & ", Score:[" & respData(7) & " +" & guessSpeed & "/min]"
- Exit Do
- End If
-
- If responseTokens = "" Then
- responseTokens = respData(9)
- ElseIf responseTokens <> respData(9) Then
- WScript.echo "Reset..."
- Exit Do
- End If
-
- nIndex = GuessCore(pmArray, pmArrayLen, CInt(respData(3))*5+CInt(respData(5)), nIndex)
- If nIndex = -1 Then
- WScript.echo "Fault..."
- Exit Do
- End If
- Loop
- Loop
- End Function
复制代码
>>
[js混编]效率还不错- 1>1/* :
- @echo off
- cscript -nologo -e:jscript "%~f0" %*
- pause&exit /b
- */
- /********************** MAIN PROCESS ***********************/
- var USER_NAME='adad';
- var PASS_WORD='123';
- var POST_URL ='http://www.codetiger.win/extra/API.php';
-
- var markPM=[];
- guessNumber(USER_NAME, PASS_WORD, POST_URL);
- /***********************************************************/
-
- function getPermutations()
- {
- var retArray=[];
- for(var i=0; i<10; i++)
- for(var j=0; j<10; j++)
- for(var k=0; k<10; k++)
- for(var l=0; l<10; l++)
- if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l))
- retArray.push('' + i + j + k + l);
- return retArray;
- }
-
- function getWeights(correctNum, guessNum)
- {
- var retWeights = 0;
- var gArray=guessNum.split('');
- for(var i=0; i<4; i++)
- {
- var dIndex=correctNum.indexOf( gArray[i]);
- if(dIndex != -1)
- {
- retWeights += (dIndex==i)?5:1;
- }
- }
- return retWeights;
- }
-
- function guessCore(arrayPM, arrayPMLen, responseWeights, guessNum)
- {
- var markIndex = -1;
- for(var i=1; i<arrayPMLen; i++)
- {
- if(markPM[i])
- {
- if(getWeights(arrayPM[i], guessNum) != responseWeights)
- {
- markPM[i] = false;
- }
- else if(markIndex == -1)
- {
- markIndex = i;
- }
- }
- }
- return markIndex;
- }
-
- function httpPostData(hostURL, postString)
- {
- var xmlHTTP=new ActiveXObject('Msxml2.XMLHTTP');
- xmlHTTP.open('POST', hostURL, false);
- xmlHTTP.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- xmlHTTP.setRequestHeader('Connection', 'Keep-Alive');
- xmlHTTP.send(postString);
-
- if(xmlHTTP.readyState === 4)
- {
- if(
- (
- (xmlHTTP.status >= 200) &&
- (xmlHTTP.status < 300)
- ) ||
- (
- (xmlHTTP.status == 304)
- )
- )
- {
- return eval( '(' + xmlHTTP.responseText + ')' );
- }
- else
- {
- return null
- }
- }
- }
-
- function guessNumber(userName, passWord, hostURL)
- {
- var pmArray=getPermutations();
- var pmArrayLen=pmArray.length;
- var startMilis=new Date(), guessScore=0, guessSpeed=0;
-
- for(;;)
- {
- var currentIndex=0, responseTokens=null, respData=null, guessTimes=0;
-
- for(var i=0; i<pmArrayLen; i++)
- {
- markPM[i] = true;
- }
-
- for(;;)
- {
- try
- {
- respData = httpPostData(hostURL, 'username=' + userName + '&password=' + passWord + '&send=answer&number=' + pmArray[currentIndex]);
- if(respData == null)
- {
- continue;
- }
- }
- catch(e)
- {
- WScript.echo('Requests error!!!');
- break;
- }
-
-
- if(guessScore == 0)
- {
- guessScore = respData['count'];
- }
-
- guessTimes ++;
-
- if(respData['A'] == 4)
- {
- if(new Date()-startMilis > 6000)
- {
- guessSpeed=(respData['count'] - guessScore)*10;
- guessScore=respData['count'];
- startMilis=new Date();
- }
- WScript.echo('Takes:[' + guessTimes + 'th], Answer:' + pmArray[currentIndex] + ', Score:[' + respData['count'] + ' +' + guessSpeed + '/min]');
- break;
- }
-
- if(responseTokens == null)
- {
- responseTokens = respData['tokens'];
- }
- else if(responseTokens != respData['tokens'])
- {
- WScript.echo('Reset...');
- break;
- }
-
- if( (currentIndex=guessCore(pmArray, pmArrayLen, respData['A']*5+respData['B'], pmArray[currentIndex])) == -1)
- {
- WScript.echo('Fault...');
- break;
- }
- }
- }
- }
复制代码
>>
[python版] py3标准- # -*- coding:utf-8 -*-
- import requests
- import itertools
-
- # 用户信息
- userNAMZE='adad'
- passWORD='123'
-
- # 主机地址
- hostURL='http://www.codetiger.win/extra/API.php'
-
-
- # 筛法标记数组
- markPM=[]
-
- # 获取权重
- def GetWeights(correctNum, guessNum):
- retWeights=0
- for i in range(0,4):
- for j in range(0,4):
- if correctNum[i] == guessNum[j] :
- if i==j :
- retWeights += 5
- else:
- retWeights += 1
- return retWeights
-
- # 猜数筛法
- def GuessCore(arrayPM, arrayLen, responseWeights, guessNum):
- markIndex=None
- for i in range(0, arrayPMLen):
- if markPM[i]:
- if GetWeights(arrayPM[i], guessNum) != responseWeights :
- markPM[i]=False
- elif markIndex == None :
- markIndex=i
- if markIndex==None :
- markIndex=0
- return markIndex
-
- # 主函数
- if __name__ == "__main__":
-
- # 生成由[0-9]构成的4位全排列数
- arrayPM=[]
- for r in itertools.permutations('0123456789', 4):
- arrayPM.append(''.join(r))
-
- # 获取全排列数组长度
- arrayPMLen = len(arrayPM)
-
- # 根据全排列数组长度,分配标记数组
- markPM=[False]*arrayPMLen
-
- # 外层循环主程
- while True:
-
- # 标记数组重置为真
- for i in range(0, arrayPMLen):
- markPM[i]=True
-
- # 重置数组索引
- currentIndex=0
-
- # 重置猜测次数
- guessTimes=0
-
- # 重置tokens
- responseTokens=None
-
- #内层循环猜测
- while True:
-
- # 提交数字,返回json格式
- try:
- r = requests.post(hostURL, {'password':passWORD, 'username':userNAMZE, 'number':arrayPM[currentIndex], 'send':'answer'}).json()
- except:
- print("Requests error!!!")
- break
-
- # 猜测次数自增
- guessTimes += 1
-
- # 判断是否猜测正确
- if r['A'] == 4 :
- print("Takes {0} times: {1}".format(guessTimes, arrayPM[currentIndex]))
- break
-
- # 如果tokens为空更新tokens
- if responseTokens == None:
- responseTokens = r['tokens']
-
- # 如果tokens改则跳出内层循环
- elif responseTokens != r['tokens'] :
- print("Reset...")
- break
-
- # 调用猜数字筛法函数
- currentIndex = GuessCore(arrayPM, arrayPMLen, r['A']*5+r['B'], arrayPM[currentIndex])
复制代码
>>
[C语言版]cfree编译- #include <stdio.h>
- #include <stdbool.h>
- #include <string.h>
- #include <windows.h>
- #include <winsock2.h>
- #include <time.h>
-
- //定义用户信息
- #define USER_NAME "adad"
- #define PASS_WORD "123"
-
- //=======================================================//
- #define POST_HEAD "\
- POST /extra/API.php HTTP/1.1\r\n\
- TE: deflate,gzip;q=0.3\r\n\
- Connection: Keep-Alive\r\n\
- Host: www.codetiger.win\r\n\
- Content-Length: 50\r\n\
- Content-Type: application/x-www-form-urlencoded\r\n\
- \r\n"
- //=======================================================//
-
- //宏定义数组阈值
- #define MAX_POST_SIZE 512
- #define MAX_ARRAY_SIZE 5040
-
- //定义SCOKET收发阈值
- #define RECEIVE_SIZE 512
- #define SEND_SIZE 512
-
- //POST 发送容器
- static char sendBuf[MAX_POST_SIZE] = POST_HEAD "username="USER_NAME "&password="PASS_WORD "&send=answer&number=";
- //Json number开始索引
- static int sendbuf_JSON_NUMBER_OFFSET;
-
- //数组pmArray
- static char pmArray[MAX_ARRAY_SIZE][4];
- //筛法标记数组
- static bool markPM[MAX_ARRAY_SIZE]= {false};
-
- //返回Json结构体
- typedef struct{
- int A;
- int B;
- int count;
- long long tokens;
- } RESPJSON, *PRESPJSON;
-
- //ParseReceiveBuf Json解析函数
- int ParseReceiveBuf(PRESPJSON pRespJson, const char* receiveBuf)
- {
- int ret = 0;
- char* p = NULL;
-
- ((p=strstr(receiveBuf, "\"A\":")) != NULL)? (pRespJson->A = atoi(p+4)) :(ret=1);
- ((p=strstr(receiveBuf, "\"B\":")) != NULL)? (pRespJson->B = atoi(p+4)) :(ret=1);
- ((p=strstr(receiveBuf, "\"count\":")) != NULL)? (pRespJson->count = atoi(p+8)) :(ret=1);
- ((p=strstr(receiveBuf, "\"tokens\":")) != NULL)? (pRespJson->tokens = atoll(p+10)) :(ret=1);
-
- return ret;
- }
-
- //初始化数组pmArray,生成4位全排列
- int InitpmArray()
- {
- int i, j, k, l, index=0;
-
- for(i=0; i<10; i++)
- for(j=0; j<10; j++)
- for(k=0; k<10; k++)
- for(l=0; l<10; l++)
- {
- if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l))
- {
- pmArray[index][0] = i+'0';
- pmArray[index][1] = j+'0';
- pmArray[index][2] = k+'0';
- pmArray[index][3] = l+'0';
- index ++;
- }
- }
-
- return 0;
- }
-
- //获取权重
- int GetWeights(char* correctNum, char* guessNum)
- {
- int i, j, retWeights = 0;
-
- for(i=0; i<4; i++)
- for(j=0; j<4; j++)
- {
- if (correctNum[i] == guessNum[j])
- {
- retWeights += (i==j)?5:1;
- }
- }
-
- return retWeights;
- }
-
- //猜数筛法
- int GuessCore(int responseWeights, int currentIndex)
- {
- int i, markIndex = -1;
- for(i=0; i<MAX_ARRAY_SIZE; i++)
- {
- if(markPM[i])
- {
- if(GetWeights(pmArray[i], pmArray[currentIndex]) != responseWeights)
- {
- markPM[i] = false;
- }
- else if( (markIndex <i ) && (i != currentIndex) )
- {
- markIndex = i;
- }
- }
- }
- return markIndex;
- }
-
- //猜数字核心函数
- int GuessNumber(struct sockaddr_in sAddr)
- {
- //初始化数组pmArray,生成4位全排列
- InitpmArray();
-
- //声明参数、计数器
- long long responseTokens;
- int currentIndex, guessTimes;
-
- //POST返回结构接收容器
- char receiveBuf[RECEIVE_SIZE];
-
- //Json返回结构体
- RESPJSON respJson={0}, *pRespJson = &respJson;
-
- //声明安全套接口
- SOCKET uintScoket;
-
- for(;;)
- {
- //重置布尔标记数组
- memset(markPM, true, MAX_ARRAY_SIZE);
-
- //重置各类参数、计数器
- currentIndex =2519/*rand()%MAX_ARRAY_SIZE*/, guessTimes =0, responseTokens =-1;
-
- for(;;)
- {
- //装入猜测数字 pmArray[currentIndex]
- strncpy(sendBuf+sendbuf_JSON_NUMBER_OFFSET, pmArray[currentIndex], 4);
-
- //生成一个安全套接口
- if((uintScoket = socket(AF_INET,SOCK_STREAM,0)) < 0)
- {
- fprintf(stderr, "Socket error!\n");
- break;
- }
-
- //建立安全套接口连接
- if(connect(uintScoket,(const struct sockaddr*)&sAddr,sizeof(sAddr)) < 0)
- {
- fprintf(stderr, "Connet error!\n");
- break;
- }
-
- //POST发送
- if(send(uintScoket,sendBuf,SEND_SIZE,0) < 0)
- {
- fprintf(stdout, "Send error!!!\n");
- break;
- }
-
- //POST接收
- int respINT = -1;
- if((respINT = recv(uintScoket,receiveBuf,RECEIVE_SIZE,0)) < 0)
- {
- fprintf(stdout, "Receive error!!!\n");
- break;
- }
-
- //关闭安全套接口
- closesocket(uintScoket);
-
- //解析POST返还信息
- if(ParseReceiveBuf(pRespJson,receiveBuf) == 1){
- fprintf(stdout, "Parse json failed!\n");
- break;
- }
-
- //猜数计数器
- guessTimes ++;
-
- //猜数正确,跳出内层循环
- if(pRespJson->A == 4)
- {
- fprintf(stdout, "=======Takes:%dth, Number:%-4.4s, Score:%d\n", guessTimes, pmArray[currentIndex], pRespJson->count);
- break;
- }
-
- //判断tokens重置
- if(responseTokens == -1)
- {
- responseTokens = pRespJson->tokens;
- }
- else if(responseTokens != pRespJson->tokens)
- {
- fprintf(stdout, "Reset...\n");
- break;
- }
-
- //筛选标记数组
- if((currentIndex=GuessCore(pRespJson->A*5+pRespJson->B, currentIndex)) == -1)
- {
- fprintf(stdout, "Error!!!\n");
- break;
- }
- }
- }
- return 0;
- }
-
- //------ MAIN 主函数 ------
- int main()
- {
- //初始化随机种子
- srand((unsigned)time(NULL));
-
- //获取Json number 开始索引
- sendbuf_JSON_NUMBER_OFFSET = strlen(sendBuf);
-
- //启动安全套接字
- WSADATA wsData;
- if(WSAStartup(MAKEWORD(2, 1), &wsData) !=0)
- {
- fprintf(stderr, "Starting the winsocket failed\n");
- exit(1);
- }
-
- //填充地址结构
- struct sockaddr_in sAddr={0};
- sAddr.sin_family = AF_INET;
- sAddr.sin_port = htons(80);
- sAddr.sin_addr.S_un.S_addr = inet_addr("43.240.12.145");
-
- //调用猜数字核心函数
- GuessNumber(sAddr);
-
- //关闭安全套接字
- WSACleanup();
- return 0;
- }
复制代码
>>
[C#版]写起来真啰嗦,还需要.NET3.5及以上。- /*************************************************************************
- @ECHO OFF&CLS&TITLE MINI CSHARP COMPILER BY HAPPY
- for /f "delims=" %%a in ('dir /a-d /b /s "%systemroot%\Microsoft.NET\Framework\v3.5\csc.exe"') do (
- "%%~a" /out:a.exe "%~f0" && a.exe
- pause&exit/b
- )
- )
- set/p=You needs Microsoft.NET!&exit/b
- **************************************************************************/
- using System;
- using System.Net;
- using System.IO;
- using System.Text;
- using System.Xml;
- using System.Runtime.Serialization.Json;
- using System.Runtime.Serialization;
- using System.Text.RegularExpressions;
-
- namespace GuessNumApplication
- {
- public class MainProgram
- {
- static void Main(string[] args)
- {
- GuessObj guessObj = new GuessObj("adad", "123", "http://www.codetiger.win/extra/API.php");
- }
- }
-
- public class RespData
- {
- public long tokens{get; set;}
- public int A{get; set;}
- public int B{get; set;}
- public int count{get; set;}
- }
-
- public class GuessObj
- {
- private static readonly int MAX_ARRAY_SIZE = 5040;
- private bool[] markPM = new bool[MAX_ARRAY_SIZE];
-
- public GuessObj(string userName, string passWord, string hostURL)
- {
- GuessNumber(userName, passWord, hostURL);
- }
-
- private string[] Permutations()
- {
- string[] pmArray = new string[MAX_ARRAY_SIZE];
- int index=0;
- for(int i=0; i<10; i++){
- for(int j=0; j<10; j++){
- for(int k=0; k<10; k++){
- for(int l=0; l<10; l++){
- if((i-j)*(i-k)*(i-l)*(j-k)*(j-l)*(k-l)!=0){
- pmArray[index++] = "" + i + j + k + l;
- }
- }
- }
- }
- }
- return pmArray;
- }
-
- private int GetWeights(string correctNum, string guessNum)
- {
- int retWeights = 0;
- for(int i=0; i<4; i++){
- for(int j=0; j<4; j++){
- if (correctNum[i] == guessNum[j]) {
- retWeights += (i==j)?5:1;
- }
- }
- }
- return retWeights;
- }
-
- private int GuessCore(string[] arrayPM, int arrayPMLen, int responseWeights, string guessNum)
- {
- int markIndex = -1;
- for(int i=1; i<arrayPMLen; i++){
- if(markPM[i]){
- if(GetWeights(arrayPM[i], guessNum) != responseWeights){
- markPM[i] = false;
- }else if(markIndex == -1){
- markIndex = i;
- }
- }
- }
- return markIndex;
- }
-
- private object ParseJson(string strJson)
- {
- DataContractJsonSerializer dJsonSerializer = new DataContractJsonSerializer(typeof(RespData));
- MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(strJson));
- return dJsonSerializer.ReadObject(memoryStream);
- }
-
- private string HttpPostData(string url, string postStr)
- {
- var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
- httpWebRequest.ContentType = "application/x-www-form-urlencoded";
- httpWebRequest.Method = "POST";
-
- using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
- {
- streamWriter.Write(postStr);
- streamWriter.Flush();
- streamWriter.Close();
- }
-
- var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
- using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
- {
- return streamReader.ReadToEnd();
- }
- }
-
- private void GuessNumber(string userName, string passWord, string hostURL)
- {
- string[] pmArray = Permutations();
- int pmArrayLen = pmArray.Length;
-
- RespData respData = new RespData();
-
- for(;;){
- string responseString = "";
- int currentIndex = 0;
- long? responseTokens = null;
- int guessTimes = 0;
-
- for(int i=0; i<MAX_ARRAY_SIZE; i++){
- markPM[i] = true;
- }
-
- for(;;){
- try{
- responseString = HttpPostData(hostURL, "username="+userName + "&password="+passWord + "&send=answer" + "&number="+pmArray[currentIndex]);
- respData =ParseJson(responseString) as RespData;
- }catch{
- Console.WriteLine("Requests error!!!");
- break;
- }
-
- guessTimes ++;
-
- if(respData.A == 4){
- Console.WriteLine("Takes:{0}th, Number:{1}, Score:{2}", guessTimes, pmArray[currentIndex], respData.count);
- break;
- }
-
- if(responseTokens == null){
- responseTokens = respData.tokens;
- }else if(responseTokens != respData.tokens){
- Console.WriteLine("Reset...");
- break;
- }
-
- if( (currentIndex=GuessCore(pmArray, pmArrayLen, respData.A*5+respData.B, pmArray[currentIndex])) == -1){
- Console.WriteLine("Fault...");
- break;
- }
- }
- }
- }
- }
- }
复制代码
>>
[php猜数字服务端实现]可用它在本地模拟猜数字游戏。- <?php
- header("Cache-Control: no-cache, must-revalidate");
-
- function digital4s_rand(){
- $rdigital = array();
- while ($i<4) {
- $rdigital[] = mt_rand(0, 9);
- $rdigital = array_flip(array_flip($rdigital));
- $i = count($rdigital);
- }
- shuffle($rdigital);
- return implode('', $rdigital);
- }
-
- if ($_POST['send'] == 'answer') {
- if (!empty($_POST['number'])) {
- $inputNumber = (string)$_POST['number'];
-
- $json=Json_decode(file_get_contents("server.sdb"),true);
-
- $count=$json['count'];
- $tokens=$json['tokens'];
- $correctNumber =$json['number'];
-
- $A=0; $B=0;
- for ($i=0; $i<4; $i++) {
- for ($j=0; $j<4; $j++) {
- if ($inputNumber[$i] === $correctNumber[$j]){
- ($i==$j) ?$A++ :$B++;
- }
- }
- }
-
- if($A == 4){
- $json['number'] = digital4s_rand();
- $json['tokens'] = (string)mt_rand(100000000, 200000000);
- $json[ 'count'] = $count + 1;
- file_put_contents("server.sdb",json_encode($json));
- }
- }
- die(json_encode(array("code"=>200, "A"=>$A, "B"=>$B, "count"=>$json['count'], "tokens"=>$tokens)));
- }else{
- ?>
-
- <html>
- <head>
- <title>phpinfo</title>
- <meta http-equiv="content-type" content="text/html;charset=utf-8">
-
- <style type="text/css">
- body {
- background-color: #fff;
- color: #222;
- font-family: sans-serif;
- }
- pre {
- margin: 0;
- font-family: monospace;
- }
- a:hover {
- text-decoration: underline;
- }
- table {
- border-collapse: collapse;
- border: 0;
- width: 934px;
- box-shadow: 1px 2px 3px #0D2B2D;
- }
- .center {text-align: center;}
- .center table {margin: 1em auto; text-align: left;}
- .center th {text-align: center !important;}
- td, th {
- border: 1px solid #666;
- font-size: 100%;
- vertical-align: baseline;
- padding: 4px 5px;
- }
- h1 {font-size: 150%;}
- h2 {font-size: 125%;}
- .p {text-align: left;}
- .e {
- background-color: #AAC1D4;
- width: 300px;
- font-weight:normal;
- }
- .h {
- background-color: #AAC1D4;
- font-weight: normal;
- }
- .alink{
- color: #000000;
- text-decoration: none;
- }
- .v {
- background-color: #ddd;
- max-width: 300px;
- overflow-x: auto;
- }
- .v i {color: #999;}
- img {display:none;}
- hr {
- width: 934px;
- background-color: #ccc;
- border: 0;
- height: 1px;
- }
- </style>
- </head>
-
- <body>
- <h1>APMA</h1>
- <table style="width:365px;background-color: #AAC1D4;>
- <tr class="h">
- <td>
- <a class="alink" href="expand.php">APMA<br>Expand Information</a>
- </td>
- <td>
- <a class="alink" href="adminer">Adminer<br>Database Manager</a>
- </tr>
- </table>
- <?php
- ob_start();
- phpinfo();
- $i = ob_get_contents();
- ob_end_clean();
- echo ( str_replace ( "module_Zend Optimizer", "module_Zend_Optimizer", preg_replace ( '%^.*<body>(.*)</body>.*$%ms', '$1', $i ) ) ) ;
- ?>
- </body>
- </html>
- <?php }?>
复制代码
作者: bbaa 时间: 2017-8-9 22:39
我还活着,回归时间未知 数独计划延期[有点事情]
猜数坏了,暂时修不了【可能代码不严谨产生的复制问题】
作者: 老刘1号 时间: 2017-8-9 22:44
回复 2# bbaa
发现窥屏er x1
作者: happy886rr 时间: 2017-8-9 22:46
回复 2# bbaa
ok,收到,延期不要紧,只要有创新就好玩。
作者: happy886rr 时间: 2017-8-9 22:57
回复 3# 老刘1号
小站有私货,不错。
作者: 老刘1号 时间: 2017-8-10 00:19
回复 5# happy886rr
感谢支持,偶尔发些小作品
作者: 523066680 时间: 2017-8-10 16:11
66666- adad 66666 + 0 0.0/min
- vic3 54761 + 0 0.0/min
- coadsa 839 + 0 0.0/min
- llsd 139 + 0 0.0/min
- sfwfssf 0 + 0 0.0/min
复制代码
作者: happy886rr 时间: 2017-8-10 19:45
回复 7# 523066680
一起6
作者: 523066680 时间: 2017-8-10 20:21
本帖最后由 523066680 于 2017-8-10 21:56 编辑
回复 8# happy886rr
一、
我还在折腾那个树的生成,但是遇到一些问题,
方案和百科中的 “反馈个数指标” 方案类似,但是平均猜数次数和里面的统计结果不同,懵逼了,还在排查。- times: 26991, rate: 5.355357
- $times_elements = {
- '1' => 1,
- '5' => 1993,
- '8' => 12,
- '6' => 1879,
- '7' => 390,
- '3' => 109,
- '2' => 13,
- '4' => 643
- };
复制代码
百度统计的是 5.308,每种回合数的统计也不一样
=================================
二、
如果不使用结构树,每次都遍历筛选,哪怕是索引操作,消耗也蛮大的,我写的C,测完5040种情况,去掉printf, 需要2.8秒。
=================================
三、
同样是筛选法,同样是5040种情况去测试,以不同的起点开始,平均回合数是不一样的。
0123 -> 5.560317
6789 -> 5.593254
不过,这大概和筛选数组后选取不同起点的区别类似。比如选择筛选后的最后一个、第一个排列,结果是不一样的。
作者: happy886rr 时间: 2017-8-10 22:37
本帖最后由 happy886rr 于 2017-8-10 22:39 编辑
回复 9# 523066680
我觉得要缩小数组的规模去筛选。
可以使用位筛法。这样降到5040/8的小规模,然后C语言的内存读取就会加快。效率就上去了。
作者: 523066680 时间: 2017-8-11 19:13
本帖最后由 523066680 于 2017-8-11 19:19 编辑
批处理的话可以用这种方式(借wget 或者curl)获取返回值- wget -O res.txt "http://www.codetiger.win/extra/API.php?username=***&password=***&number=1234&send=answer"
复制代码
返回示例:res.txt
{"code":150,"A":0,"B":1,"count":141878,"tokens":"6257936998656230"}
搜索树也可以用类似哈希的方式,事先初始化一系列变量,
TREE[0123][01]=0124
TREE[ORDER1][AB1][ORDER2][AB2]=...
这样的话处理过程就像是查表法。但是终究无力再写批处理,罢了。
作者: 523066680 时间: 2017-8-11 20:35
最后手痒还是写了,像这样:
struct.bat- @echo off
- set tree=0123
- set tree[0123][04]=1032
- set tree[0123][04][1032][04]=2301
- set tree[0123][04][1032][04][2301][22]=2310
- set tree[0123][04][1032][04][2301][22][2310][04]=3201
- set tree[0123][04][1032][04][2301][04]=3210
- set tree[0123][04][1032][22]=1230
- set tree[0123][04][1032][22][1230][13]=1302
- set tree[0123][04][1032][22][1230][13][1302][04]=2031
- set tree[0123][04][1032][22][1230][04]=3012
- set tree[0123][21]=0134
复制代码
批处理调用 struct.bat 为变量赋值。借 wget 向网站 post 并获取反馈信息。- @echo off
- setlocal enabledelayedexpansion
- echo Tree building ...
- call struct.bat
- echo Begin ...
-
- :AGAIN
- set guess=0123
- set varname=tree
- set prev=0
-
- :WHILE
- call :post %guess%
- echo %guess% - %AB%, %tokens%
-
- if "%AB%" == "40" (
- echo "Success"
- goto :AGAIN
- )
-
- if not "%prev%" == "0" (
- if not "%prev%" == "%tokens%" (
- echo "tokens changed";
- goto :AGAIN
- )
- )
-
- set varname=%varname%[%guess%][%AB%]
- set guess=!%varname%!
- set prev=%tokens%
- goto WHILE
-
- :post
- wget --quiet -O res.txt "http://www.codetiger.win/extra/API.php?username=BatchScript&password=batchscript&number=%1&send=answer" 2>nul
-
- for /f "tokens=4,6,10 delims=:,}" %%a in (res.txt) do (
- set AB=%%a%%b
- set tokens=%%c
- )
- goto :eof
复制代码
猜题速度(很慢,但是感觉好玩)- adad 193791 + 0 0.0/min
- vic3 142669 + 0 0.0/min
- coadsa 850 + 0 0.0/min
- BatchScript 752 + 55 109.6/min
- llsd 139 + 0 0.0/min
- s**sdf 75 + 0 0.0/min
- sfwfssf 0 + 0 0.0/min
复制代码
完整的 struct.bat 和 猜数字批处理,已上传附件:
作者: happy886rr 时间: 2017-8-11 20:52
本帖最后由 happy886rr 于 2017-8-11 20:53 编辑
回复 13# 523066680
批处理也只能查表了,因为5000次循环批处理就要好几秒。
你的思路完美的解决了批处理的效率问题,100/min已经是极限了,毕竟是批处理嘛。第三方调用也很耗时的。
作者: ivor 时间: 2017-8-17 10:59
支持一下
作者: 523066680 时间: 2017-8-18 20:01
本帖最后由 523066680 于 2017-8-23 12:04 编辑
本着坚持不懈的精神,终于把平均指标也跑出来了……- Times: 26551, average: 5.268056
- 1, 1
- 2, 4
- 3, 59
- 4, 574
- 5, 2430
- 6, 1885
- 7, 87
复制代码
作者: happy886rr 时间: 2017-8-18 20:48
回复 17# 523066680
这个结果跟百度上写的一样,是个概率值。
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |