Greasy Fork

Greasy Fork is available in English.

国家安全知识竞赛答题最新版本提高了正确率,可以放心了

2021/12/5 上午12:06:09

当前为 2021-12-05 提交的版本,查看 最新版本

// ==UserScript==
// @name        国家安全知识竞赛答题最新版本提高了正确率,可以放心了
// @namespace   gjaqzsjs
// @match       http://gjaqzsjs.haedu.cn/gjaq_dati/page/answer.html
// @grant       none
// @version     3.01
// @author      star_even
// @description 2021/12/5 上午12:06:09
// ==/UserScript==

(function () {
  const mapping = 'ABCDEFGHI';

  const onlyRemainCh = (sentenceWithSigns) =>
    sentenceWithSigns.replace(/[^\u4e00-\u9fa5]/gi, '');
  function cut(string, r) {
    let cutStringArr = [];
    let length = string.length;
    let randInLength = () => Math.floor(Math.random() * length * r);
    const getMinToMax = () => {
      let max = randInLength();
      let min = randInLength();
      max < min ? ([max, min] = [min, max]) : 0;

      return [min, max];
    };

    for (let i = 0; i < string.length; i++) {
      cutStringArr.push(string.slice(...getMinToMax()));
    }
    return cutStringArr.filter((e) => e.length >= 4);
  }

  function fuzzySearch(testString, tikuBank) {
    let matchIndex = [];
    let reg = new RegExp(['', ...testString, ''].join('.*'));
    tikuBank.forEach((e, i) => {
      if (reg.test(e.charactor)) {
        matchIndex.push(i);
      }
    });
    if (matchIndex === []) {
      return [-1];
    } else {
      return matchIndex;
    }
  }
  function sliceQuery(keyWords, tikuBank) {
    // 传入一堆关键字,将关键字进行查询,最后看哪个的最匹配!
    answerIndexArray = [];
    keyWords.forEach((e) => {
      answerIndexArray.push(...fuzzySearch(e, tikuBank));
    });
    return findMostElement(answerIndexArray, tikuBank);
  }
  function findMostElement(arr, tikuBank) {
    const len = arr.length;

    let arrCopy = arr.map((e) => e);
    if (!len) return { match: false };
    if (len === 1) return arr[0];
    let res = {};
    let maxName,
      maxNum = 0;
    // 遍历数组
    arr.forEach((item) => {
      res[item] ? (res[item] += 1) : (res[item] = 1);
    });
    // 遍历 res
    for (let r in res) {
      if (res[r] > maxNum) {
        maxNum = res[r];
        maxName = r;
      }
    }

    numberAnswer = tikuBank[maxName].answer.map((e) => mapping.indexOf(e));

    let reli = (maxNum / len).toFixed(2);
    if (reli <= 0.2 && maxNum <= 3) {
      l(
        `%c 通过切片匹配,共${len}个关键词切片,但只匹配到了${maxNum}个,且可信度为${reli}太低!将刷新题目!`,
        'color:red'
      );

      location.reload();
    }

    return {
      match: true,
      answer: tikuBank[maxName].answer,
      numAnswer: numberAnswer,
      matchArray: arrCopy, //都匹配到了哪些对应的索引
      bestMatchedIndex: maxName, //最匹配的索引
      reliability: `${(maxNum / len).toFixed(2)}=>>${maxNum}/${len}`, //最匹配的元素出现的次数占数组总长度的比例
      content: tikuBank[maxName].question,
      wholeContent: tikuBank[maxName],
    };
  }

  //   便于调试
  let l = console.log;
  let t = console.table;

  const ratio = 3; //比例系数,尽量2-4之间 越大越慢=>可靠性更好
  window.onload = () => {
    //     业务部分开始
    setTimeout(() => {
      let doc = document;
      let tikuBank = GM_getValue('tiku');
      tikuBank = tikuBank.map((e) => {
        return {
          charactor: onlyRemainCh(e.question),
          question: e.question,
          answer: e.answer,
        };
      });
      // l(tikuBank)

      let tests = [];
      let keywordsGroup = [];
      doc.querySelectorAll('.issue').forEach((e) => {
        tests.push(e.innerText);
      });
      let optionsGroup = doc.querySelectorAll('.options');
      // t(tests)
      let wholeResult = [];
      tests.forEach((e, i) => {
        l(`正在匹配第${i + 1}题!`);
        let everySingleResult = sliceQuery(
          cut(onlyRemainCh(e), ratio),
          tikuBank
        );
        wholeResult.push(everySingleResult);
        // t(everySingleResult)
        if (everySingleResult.match === true) {
          // l({"question":onlyRemainCh(e),"searched":everySingleResult.wholeContent.charactor.slice(0,onlyRemainCh(e).length)})
          let a = everySingleResult.numAnswer;
          // l(`第${i+1}题:${a}`)
          // l(`第${i+1}题匹配成功~可信度:${everySingleResult.reliability}`)
          setTimeout(() => {
            a.forEach((ee, ii) => {
              optionsGroup[i].childNodes[ee].click();
            });
          }, 0);
        } else {
          l(`%c 第${i + 1}题匹配失败!`, 'color:red;');
          setTimeout(() => {}, 50);
          l(`正在尝试跳转`);
          location.reload();
        }

        //   ///
      });
    }, 100);

    setTimeout(() => {
      if (
        (r = window.confirm(
          '所有题已答完,请点击确认。如果没有答上,请刷新(ctrl+R)!如果不放心想要手动确认正确率,可以点击右键调出开发者控制台(F12 for Windows) (control+command+I for Mac)查看每一条的答案'
        ))
      ) {
        window.scrollTo(
          0,
          document.documentElement.offsetHeight - window.innerHeight
        );
        //   修改为一个正常的提交时间
        maxTime = parseInt(Math.random() * (500 - 200 + 1) + 200, 10);
      } else {
        maxTime = parseInt(Math.random() * (500 - 200 + 1) + 200, 10);
      }
    }, 600);
  };
})();