yukicoderの言語欄に ChatGPT を追加するユーザスクリプトです。2023/04/01 エイプリルフールネタです。
言語 ChatGPT を選択すると、ChatGPT によって問題文から Python3 コードを生成し、テキストに貼り付けます。
動作にはユーザスクリプトを動作させるための tampermonkey と API を呼び出すための OpenAI API Key が必要です。
| // ==UserScript== | |
| // @name ChatGPT on yukicoder | |
| // @namespace http://app.ukibune.net/ | |
| // @version 0.2023.4.1 | |
| // @description try to take over the world! | |
| // @author mai buyoh | |
| // @match https://yukicoder.me/problems/* | |
| // @exclude https://yukicoder.me/problems/*/submit | |
| // @exclude https://yukicoder.me/problems/*/submissions | |
| // @exclude https://yukicoder.me/problems/*/code | |
| // @exclude https://yukicoder.me/problems/*/gen | |
| // @exclude https://yukicoder.me/problems/*/validation | |
| // @icon https://yukicoder.me/public/img/icon.png | |
| // @license WTFPL | |
| // @grant none | |
| // ==/UserScript== | |
| (function () { | |
| "use strict"; | |
| const kMock = false; | |
| let openAiApiKey = null; | |
| // let openAiApiKey = "sk-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaa"; | |
| const kOpenAiModel = "gpt-3.5-turbo"; | |
| const getOpenAiApiKey = () => { | |
| if (openAiApiKey === null) { | |
| const res = prompt( | |
| "Please input openAI API key!", | |
| "sk-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaa" | |
| ); | |
| if (!res) throw new Error("No api key!"); | |
| openAiApiKey = res; | |
| } | |
| return openAiApiKey; | |
| }; | |
| const postToChatGPT = async (content) => { | |
| const query = { | |
| model: kOpenAiModel, | |
| messages: [{ role: "user", content }], | |
| temperature: 0.7, | |
| }; | |
| const res = await fetch("https://api.openai.com/v1/chat/completions", { | |
| headers: new Headers([ | |
| ["Content-Type", "application/json"], | |
| ["Authorization", "Bearer " + getOpenAiApiKey()], | |
| ]), | |
| method: "POST", | |
| body: JSON.stringify(query), | |
| }); | |
| if (!res.ok) { | |
| console.error("fetch failed!", res); | |
| return null; | |
| } | |
| const json = await res.json(); | |
| return { | |
| content: json.choices[0].message.content, | |
| }; | |
| }; | |
| // For testing | |
| const mock_postToChatGPT = (content) => | |
| new Promise((resolve) => { | |
| const _ = getOpenAiApiKey(); | |
| console.log("query: ", content); | |
| setTimeout(() => { | |
| resolve({ | |
| content: | |
| 'year, month, day = map(int, input().split("/"))\nif year < 1989:\n' + | |
| ' print("No")\nelif year == 1989:\n if month < 1 or (month == 1 and day < 8):\n' + | |
| ' print("No")\n else:\n print("Yes")\nelse:\n print("Yes")', | |
| }); | |
| }, 1500); | |
| }); | |
| // | |
| const getCode = () => ace.edit("rich_source").getValue(); | |
| const setCode = (text) => ace.edit("rich_source").setValue(text); | |
| const getProblemText = () => | |
| Array.from(document.getElementById("content").querySelectorAll(".block")) | |
| .map((e) => e.innerText) | |
| .join("\n\n"); | |
| const putResult = (code) => { | |
| const domSelect = document.getElementById("lang"); | |
| domSelect.value = "python3"; | |
| setTimeout(() => { | |
| setCode(code); | |
| }, 0); | |
| }; | |
| const askToAI = async () => { | |
| setCode("chatGPTing..."); | |
| const problem = getProblemText(); | |
| const content = | |
| "Write a Python3 code that solves the following competitive programming problem. " + | |
| 'Do not write anything other than the code."""' + | |
| problem + | |
| '"""'; | |
| const answer = kMock | |
| ? await mock_postToChatGPT(content) | |
| : await postToChatGPT(content); | |
| putResult(answer.content); | |
| }; | |
| const addOptionIntoLang = () => { | |
| const domSelect = document.getElementById("lang"); | |
| const o = document.createElement("option"); | |
| o.appendChild(document.createTextNode("ChatGPT (" + kOpenAiModel + ")")); | |
| o.value = "_user_chatgpt"; | |
| domSelect.addEventListener("change", () => { | |
| if (domSelect.value != "_user_chatgpt") return; | |
| setTimeout(askToAI, 0); | |
| }); | |
| domSelect.appendChild(o); | |
| }; | |
| setTimeout(addOptionIntoLang, 2000); | |
| })(); |