diff --git a/README.md b/README.md new file mode 100644 index 0000000..e43f8ae --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +## Contributing to WPM +add new challenges +locate **CodeBlocks.json** in data folder and add the block with the following format example considering spaces and line breaks **\n** + +
"id": 1,
+"title": "Hello World",
+"language": "js",
+"blocks": [
+  "console.log(\"Hello, World!\");\n"
+] 
+ +update build +open command console in game folder and type npm run build +this will be located in the dist\assets inside game folder, rename to game and replace the existing version inside website\public\game diff --git a/game/index.html b/game/index.html index 0f6a54a..f99de2c 100644 --- a/game/index.html +++ b/game/index.html @@ -1,7 +1,7 @@ - mygame + WPM diff --git a/game/package-lock.json b/game/package-lock.json index 86ac54c..b55bcc1 100644 --- a/game/package-lock.json +++ b/game/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "mygame", "dependencies": { - "kaplay": "^3001.0.2" + "kaplay": "^4000.0.0-alpha.17" }, "devDependencies": { "prettier": "^3.4.1", @@ -718,10 +718,13 @@ } }, "node_modules/kaplay": { - "version": "3001.0.2", - "resolved": "https://registry.npmjs.org/kaplay/-/kaplay-3001.0.2.tgz", - "integrity": "sha512-4gyknxI8mSKOywjs7QmWTYjW/tAFJwYRzjWFXnJccHi6okRh1YxNKc5B2oR5CSU5WY75QmdxlAM+u+bpXaIgRw==", - "license": "MIT" + "version": "4000.0.0-alpha.17", + "resolved": "https://registry.npmjs.org/kaplay/-/kaplay-4000.0.0-alpha.17.tgz", + "integrity": "sha512-x7BEaFkGP78ShkPVMQaQ68n1ql/W/AavC4kyr3d1YofqOWyw42YMa7okBDzSBgx8GabV7XK2brA68UfUMQSwNQ==", + "license": "MIT", + "funding": { + "url": "https://opencollective.com/kaplay" + } }, "node_modules/nanoid": { "version": "3.3.7", diff --git a/game/package.json b/game/package.json index 0cdb0b2..c716a03 100644 --- a/game/package.json +++ b/game/package.json @@ -9,10 +9,11 @@ "fmt": "prettier --write ." }, "dependencies": { - "kaplay": "^3001.0.2" + "kaplay": "^4000.0.0-alpha.17" }, "devDependencies": { "prettier": "^3.4.1", "vite": "^5.4.11" - } + }, + "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1" } diff --git a/game/public/fonts/jetbrains.ttf b/game/public/fonts/jetbrains.ttf new file mode 100644 index 0000000..8c93043 Binary files /dev/null and b/game/public/fonts/jetbrains.ttf differ diff --git a/game/public/fonts/thaleahFat.ttf b/game/public/fonts/thaleahFat.ttf new file mode 100644 index 0000000..91fc7dc Binary files /dev/null and b/game/public/fonts/thaleahFat.ttf differ diff --git a/game/public/sounds/code_sound.mp3 b/game/public/sounds/code_sound.mp3 new file mode 100644 index 0000000..89b4bd3 Binary files /dev/null and b/game/public/sounds/code_sound.mp3 differ diff --git a/game/public/sounds/endgame.mp3 b/game/public/sounds/endgame.mp3 new file mode 100644 index 0000000..05c74d4 Binary files /dev/null and b/game/public/sounds/endgame.mp3 differ diff --git a/game/public/sounds/videogame.mp3 b/game/public/sounds/videogame.mp3 new file mode 100644 index 0000000..95b3702 Binary files /dev/null and b/game/public/sounds/videogame.mp3 differ diff --git a/game/public/sounds/wrong typing.mp3 b/game/public/sounds/wrong typing.mp3 new file mode 100644 index 0000000..aedc1fe Binary files /dev/null and b/game/public/sounds/wrong typing.mp3 differ diff --git a/game/public/sprites/BG_AWPM_IN_GAME.png b/game/public/sprites/BG_AWPM_IN_GAME.png new file mode 100644 index 0000000..364fdda Binary files /dev/null and b/game/public/sprites/BG_AWPM_IN_GAME.png differ diff --git a/game/public/sprites/BG_TIME_IN_GAME.png b/game/public/sprites/BG_TIME_IN_GAME.png new file mode 100644 index 0000000..86a05da Binary files /dev/null and b/game/public/sprites/BG_TIME_IN_GAME.png differ diff --git a/game/public/sprites/BG_WPM_IN_GAME.png b/game/public/sprites/BG_WPM_IN_GAME.png new file mode 100644 index 0000000..736fb3f Binary files /dev/null and b/game/public/sprites/BG_WPM_IN_GAME.png differ diff --git a/game/public/sprites/SilverDev_logo.png b/game/public/sprites/SilverDev_logo.png new file mode 100644 index 0000000..25f0782 Binary files /dev/null and b/game/public/sprites/SilverDev_logo.png differ diff --git a/game/public/sprites/WPM.png b/game/public/sprites/WPM.png new file mode 100644 index 0000000..5af0190 Binary files /dev/null and b/game/public/sprites/WPM.png differ diff --git a/game/public/sprites/arrow_yellow.png b/game/public/sprites/arrow_yellow.png new file mode 100644 index 0000000..b9fae10 Binary files /dev/null and b/game/public/sprites/arrow_yellow.png differ diff --git a/game/public/sprites/bg.png b/game/public/sprites/bg.png new file mode 100644 index 0000000..05bb586 Binary files /dev/null and b/game/public/sprites/bg.png differ diff --git a/game/public/sprites/bg2.png b/game/public/sprites/bg2.png index d2a4879..64fec5f 100644 Binary files a/game/public/sprites/bg2.png and b/game/public/sprites/bg2.png differ diff --git a/game/public/sprites/bg4.png b/game/public/sprites/bg4.png new file mode 100644 index 0000000..13b8a37 Binary files /dev/null and b/game/public/sprites/bg4.png differ diff --git a/game/public/sprites/icon_01.png b/game/public/sprites/icon_01.png new file mode 100644 index 0000000..7576046 Binary files /dev/null and b/game/public/sprites/icon_01.png differ diff --git a/game/public/sprites/icon_02.png b/game/public/sprites/icon_02.png new file mode 100644 index 0000000..2ab7fd4 Binary files /dev/null and b/game/public/sprites/icon_02.png differ diff --git a/game/public/sprites/icon_03.png b/game/public/sprites/icon_03.png new file mode 100644 index 0000000..e4b68f6 Binary files /dev/null and b/game/public/sprites/icon_03.png differ diff --git a/game/public/sprites/icon_04.png b/game/public/sprites/icon_04.png new file mode 100644 index 0000000..62771c6 Binary files /dev/null and b/game/public/sprites/icon_04.png differ diff --git a/game/public/sprites/icon_05.png b/game/public/sprites/icon_05.png new file mode 100644 index 0000000..9d36e29 Binary files /dev/null and b/game/public/sprites/icon_05.png differ diff --git a/game/public/sprites/muteOFF.png b/game/public/sprites/muteOFF.png new file mode 100644 index 0000000..63ecafd Binary files /dev/null and b/game/public/sprites/muteOFF.png differ diff --git a/game/public/sprites/muteON.png b/game/public/sprites/muteON.png new file mode 100644 index 0000000..f2065da Binary files /dev/null and b/game/public/sprites/muteON.png differ diff --git a/game/public/style.css b/game/public/style.css index acad5b9..4a9772e 100644 --- a/game/public/style.css +++ b/game/public/style.css @@ -1,40 +1,32 @@ -canvas { - position: absolute; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - z-index: 10; -} - :root { - --bg: #0a0a1b; -} - -body { + --bg: hsl(0, 3.60%, 11.00%); + --gray1: #0a080a; + --gray2: #110b11; + } + + body { margin: 0; - background: var(--bg); - background-image: linear-gradient( - 90deg, - rgba(35, 9, 30, 0.8) 2px, - transparent 1px - ), - linear-gradient(0deg, rgba(9, 35, 50, 0.8) 2px, transparent 1px); - background-size: 30px 30px; - display: flex; - justify-content: center; - align-items: center; - min-height: 100vh; overflow: hidden; -} - -.editor { - background: rgba(10, 10, 27, 0.8); - width: 1280px; - height: 640px; - border: 4px solid var(--neon2); - box-shadow: 0 0 10px var(--neon2); - display: flex; - flex-direction: column; + background: var(--bg); position: relative; -} \ No newline at end of file + } + + body::before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: + linear-gradient(45deg, var(--gray1) 25%, transparent 25%), + linear-gradient(-45deg, var(--gray1) 25%, transparent 25%), + linear-gradient(45deg, transparent 75%, var(--gray1) 75%), + linear-gradient(-45deg, transparent 75%, var(--gray1) 75%), + rgba(0, 0, 0, 0.81); + background-size: 15px 15px, 15px 15px, 15px 15px, 15px 15px, cover; + background-position: 0 0, 0 7.5px, 7.5px -7.5px, -7.5px 0, center; + background-blend-mode: multiply; + backdrop-filter: blur(10px); + z-index: -1; + } \ No newline at end of file diff --git a/game/src/assets.js b/game/src/assets.js index c49342f..3a3892e 100644 --- a/game/src/assets.js +++ b/game/src/assets.js @@ -1,11 +1,15 @@ // @ts-check - import { k } from "./kaplay.js"; - -k.loadFont("monogram", "/fonts/monogram.ttf", { - outline: 4, - filter: "linear", +k.loadFont("jetbrains", "/fonts/jetbrains.ttf", { + outline: { + width: 6, + color: k.rgb(8, 8, 8) + }, }); - -k.loadSprite("bgpng", "/sprites/bgpng.png"); -k.loadSprite("bg2", "/sprites/bg2.png"); \ No newline at end of file +k.loadSprite("bg4", "/sprites/bg4.png"); +k.loadSprite("bg2", "/sprites/bg2.png"); +k.loadSound("code_sound", "/sounds/code_sound.mp3"); +k.loadSound("wrong_typing", "/sounds/wrong typing.mp3"); +k.loadSprite("muteON", "/sprites/muteON.png"); +k.loadSprite("muteOff", "/sprites/muteOFF.png"); +k.loadSprite("WPM", "/sprites/WPM.png"); \ No newline at end of file diff --git a/game/src/components/resizablePos.js b/game/src/components/resizablePos.js new file mode 100644 index 0000000..a3fec3d --- /dev/null +++ b/game/src/components/resizablePos.js @@ -0,0 +1,32 @@ +/** + * @typedef {import("kaplay").Vec2} Vec2 + * @typedef {import("kaplay").GameObj} GameObj + * @typedef {import("kaplay").PosComp} PosComp + */ + +import { gameState } from "../constants.js"; + +/** + * Set the position on resize + * + * @param {() => Vec2} sizeFunc + */ +export const resizablePos = (sizeFunc) => ({ + id: "resizablePos", + sizeFunc, + add() { + gameState.resizableObjects.push(this); + this.pos = this.sizeFunc(); + }, + /** + * @type { GameObj } this + */ + updatePos() { + // this.pos = this.sizeFunc(); + }, + destroy() { + gameState.resizableObjects = gameState.resizableObjects.filter( + (obj) => obj !== this, + ); + }, +}); diff --git a/game/src/components/resizableRect.js b/game/src/components/resizableRect.js new file mode 100644 index 0000000..3fe3bee --- /dev/null +++ b/game/src/components/resizableRect.js @@ -0,0 +1,29 @@ +/** + * @typedef {import("kaplay").Vec2} Vec2 + * @typedef {import("kaplay").GameObj} GameObj + * @typedef {import("kaplay").RectComp} RectComp + */ + +import { gameState } from "../constants.js"; +import { k } from "../kaplay.js"; + +/** + * Set the rect on resize + * + * @param {() => Vec2} resizeFunc + */ +export const resizableRect = (resizeFunc) => ({ + id: "resizableRect", + resizeFunc, + add() { + // this.use(k.rect(this.resizeFunc().x, this.resizeFunc().y)); + }, + updateRectSize() { + // this.use(k.rect(this.resizeFunc().x, this.resizeFunc().y)); + }, + destroy() { + gameState.resizableObjects = gameState.resizableObjects.filter( + (obj) => obj !== this, + ); + }, +}); diff --git a/game/src/constants.js b/game/src/constants.js index cc4173b..f8bbb98 100644 --- a/game/src/constants.js +++ b/game/src/constants.js @@ -1,12 +1,37 @@ // @ts-check -import dialogs from "./data/dialog.json"; - -export const goalBlocks = 2; -export const maxtime = 500; -export const maxMistakes = 2; -export const lineHeight = 24; -export const charSpacing = 10; -export const startmoveline = 1; +import dialogs from "./data/CodeBlocks.json"; +export const EASY_RIVAL_SPEED = 0.35; +export const HARD_RIVAL_SPEED = 0.18; +export const MAX_TIME = 60; +export const goalBlocks = 5; +export const maxMistakes = 1; +export const lineHeight = 28; +export const startmoveline = 3; export const marginvisiblebox = 1; -export const jsonData = dialogs; +export const dialogsData = dialogs; +export const ICON_START_Y = 0.15; +export const TEXT_START_Y = 0.15; +export const SPACING = 0.05; +export const MAX_BLOCKS = 5; +/** + * @type {number} + */ +// reduce for a jump line after x lines +export const JUMP_AFTER = 40; + +/** + * Object for manage different states and configurations in the game + */ +export const gameState = { + /** + * Allocated resizable objects for update on resize + * + * @type {import("kaplay").GameObj[]} + */ + resizableObjects: [], + /** + * Time left + */ + timeLeft: 0, +}; diff --git a/game/src/data/CodeBlocks.json b/game/src/data/CodeBlocks.json new file mode 100644 index 0000000..89c0251 --- /dev/null +++ b/game/src/data/CodeBlocks.json @@ -0,0 +1,1339 @@ +[ + { + "id": 1, + "title": "twoSum", + "language": "javascript", + "blocks": [ + "var twoSum = function(nums, target) {\n", + " let map = {};\n", + " \n", + " for (let i = 0; i < nums.length; i++) {\n", + " let other = target - nums[i];\n", + " \n", + " if (other in map) {\n", + " return [i, map[other]];\n", + " }\n", + " \n", + " map[nums[i]] = i;\n", + " }\n", + " \n", + " return [];\n", + "};\n" + ] + }, + { + "id": 2, + "title": "isPalindrome", + "language": "javascript", + "blocks": [ + "var isPalindrome = function(x) {\n", + " if (x < 0) {\n", + " return false;\n", + " }\n", + " \n", + " let reverse = 0;\n", + " let xcopy = x;\n", + " \n", + " while (x > 0) {\n", + " reverse = (reverse * 10) + (x % 10);\n", + " x = Math.floor(x / 10);\n", + " }\n", + " \n", + " return reverse === xcopy;\n", + "};\n" + ] + }, + { + "id": 3, + "title": "longestCommonPrefix", + "language": "javascript", + "blocks": [ + "var longestCommonPrefix = function(strs) {\n", + " return strs.reduce((prev, next) => {\n", + " let i = 0;\n", + " while (prev[i] && next[i] && prev[i] === next[i]) i++;\n", + " return prev.slice(0, i);\n", + " });\n", + "};\n" + ] + }, + { + "id": 4, + "title": "mergeTwoLists", + "language": "javascript", + "blocks": [ + "var mergeTwoLists = function(list1, list2) {\n", + " let dummy = new ListNode();\n", + " let cur = dummy;\n", + " \n", + " while (list1 && list2) {\n", + " if (list1.val > list2.val) {\n", + " cur.next = list2;\n", + " list2 = list2.next;\n", + " } else {\n", + " cur.next = list1;\n", + " list1 = list1.next;\n", + " }\n", + " cur = cur.next;\n", + " }\n", + " \n", + " cur.next = list1 || list2;\n", + " \n", + " return dummy.next;\n", + "};\n" + ] + }, + { + "id": 5, + "title": "removeDuplicates", + "language": "javascript", + "blocks": [ + "var removeDuplicates = function(nums) {\n", + " let i = 1;\n", + " \n", + " for (let j = 1; j < nums.length; j++) {\n", + " if (nums[j] !== nums[i - 1]) {\n", + " nums[i] = nums[j];\n", + " i++;\n", + " }\n", + " }\n", + " \n", + " return i;\n", + "};\n" + ] + }, + { + "id": 6, + "title": "strStr", + "language": "javascript", + "blocks": [ + "var strStr = function(haystack, needle) {\n", + " if (haystack.length < needle.length) {\n", + " return -1;\n", + " }\n", + " \n", + " for (let i = 0; i <= haystack.length - needle.length; i++) {\n", + " if (haystack.substring(i, i + needle.length) === needle) {\n", + " return i;\n", + " }\n", + " }\n", + " \n", + " return -1;\n", + "};\n" + ] + }, + { + "id": 7, + "title": "searchInsert", + "language": "javascript", + "blocks": [ + "var searchInsert = function(nums, target) {\n", + " let left = 0;\n", + " let right = nums.length - 1;\n", + " \n", + " while (left <= right) {\n", + " let mid = Math.floor((left + right) / 2);\n", + " \n", + " if (nums[mid] === target) {\n", + " return mid;\n", + " } else if (nums[mid] > target) {\n", + " right = mid - 1;\n", + " } else {\n", + " left = mid + 1;\n", + " }\n", + " }\n", + " \n", + " return left;\n", + "};\n" + ] + }, + { + "id": 8, + "title": "lengthOfLastWord", + "language": "javascript", + "blocks": [ + "var lengthOfLastWord = function(s) {\n", + " let length = 0;\n", + " for (let i = s.length - 1; i >= 0; i--) {\n", + " if (s[i] !== ' ') {\n", + " length++;\n", + " } else if (length > 0) {\n", + " break;\n", + " }\n", + " }\n", + " \n", + " return length;\n", + "};\n" + ] + }, + { + "id": 9, + "title": "plusOne", + "language": "javascript", + "blocks": [ + "var plusOne = function(digits) {\n", + " for (let i = digits.length - 1; i >= 0; i--) {\n", + " if (digits[i] + 1 !== 10) {\n", + " digits[i] += 1;\n", + " return digits;\n", + " }\n", + " digits[i] = 0;\n", + " if (i === 0) {\n", + " digits.unshift(1);\n", + " return digits;\n", + " }\n", + " }\n", + "};\n" + ] + }, + { + "id": 10, + "title": "addBinary", + "language": "javascript", + "blocks": [ + "var addBinary = function(a, b) {\n", + " let carry = 0;\n", + " let res = '';\n", + " let i = a.length - 1;\n", + " let j = b.length - 1;\n", + " \n", + " while (i >= 0 || j >= 0 || carry) {\n", + " let sum = carry;\n", + " if (i >= 0) sum += parseInt(a[i]);\n", + " if (j >= 0) sum += parseInt(b[j]);\n", + " \n", + " res = (sum % 2) + res;\n", + " carry = Math.floor(sum / 2);\n", + " \n", + " i--;\n", + " j--;\n", + " }\n", + " \n", + " return res;\n", + "};\n" + ] + }, + { + "id": 11, + "title": "mySqrt", + "language": "javascript", + "blocks": [ + "var mySqrt = function(x) {\n", + " var left = 1;\n", + " var right = Math.floor(x / 2) + 1;\n", + " var mid;\n", + " \n", + " while (left <= right) {\n", + " mid = Math.floor((left + right) / 2);\n", + " \n", + " if (mid * mid > x) {\n", + " right = mid - 1;\n", + " } else if (mid * mid < x) {\n", + " left = mid + 1;\n", + " } else {\n", + " return mid;\n", + " }\n", + " }\n", + " \n", + " return right;\n", + "};\n" + ] + }, + { + "id": 12, + "title": "climbStairs", + "language": "javascript", + "blocks": [ + "var climbStairs = function(n) {\n", + " if (n <= 3) return n;\n", + " \n", + " let prev1 = 3;\n", + " let prev2 = 2;\n", + " let cur = 0;\n", + " \n", + " for (let i = 3; i < n; i++) {\n", + " cur = prev1 + prev2;\n", + " prev2 = prev1;\n", + " prev1 = cur;\n", + " }\n", + " \n", + " return cur;\n", + "};\n" + ] + }, + { + "id": 13, + "title": "deleteDuplicates", + "language": "javascript", + "blocks": [ + "var deleteDuplicates = function(head) {\n", + " let res = head;\n", + " \n", + " while (head && head.next) {\n", + " if (head.val === head.next.val) {\n", + " head.next = head.next.next;\n", + " } else {\n", + " head = head.next;\n", + " }\n", + " }\n", + " \n", + " return res;\n", + "};\n" + ] + }, + { + "id": 14, + "title": "mergeSortedArray", + "language": "javascript", + "blocks": [ + "var merge = function(nums1, m, nums2, n) {\n", + " for (let i = m, j = 0; j < n; i++, j++) {\n", + " nums1[i] = nums2[j];\n", + " }\n", + " nums1.sort((a, b) => a - b);\n", + "};\n" + ] + }, + { + "id": 15, + "title": "inorderTraversal", + "language": "javascript", + "blocks": [ + "var inorderTraversal = function(root) {\n", + " const res = [];\n", + " \n", + " function inorder(node) {\n", + " if (!node) {\n", + " return;\n", + " }\n", + " inorder(node.left);\n", + " res.push(node.val);\n", + " inorder(node.right);\n", + " }\n", + " \n", + " inorder(root);\n", + " return res;\n", + "};\n" + ] + }, + { + "id": 16, + "title": "isSameTree", + "language": "javascript", + "blocks": [ + "var isSameTree = function(p, q) {\n", + " if (!p && !q) {\n", + " return true;\n", + " }\n", + " \n", + " if (p && q && p.val === q.val) {\n", + " return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);\n", + " }\n", + " \n", + " return false;\n", + "};\n" + ] + }, + { + "id": 17, + "title": "isSymmetric", + "language": "javascript", + "blocks": [ + "var isSymmetric = function(root) {\n", + " const isMirror = (n1, n2) => {\n", + " if (!n1 && !n2) {\n", + " return true;\n", + " }\n", + " \n", + " if (!n1 || !n2) {\n", + " return false;\n", + " }\n", + " const leftMirror = isMirror(n1.left, n2.right);\n", + " const rightMirror = isMirror(n1.right, n2.left);\n", + " return n1.val === n2.val && leftMirror && rightMirror;\n", + " };\n", + " \n", + " return isMirror(root.left, root.right);\n", + "};\n" + ] + }, + { + "id": 18, + "title": "twoSum", + "language": "golang", + "blocks": [ + "func twoSum(nums []int, target int) []int {\n", + " m := map[int]int{}\n", + " for i, n := range nums {\n", + " if j, ok := m[target-n]; ok {\n", + " return []int{j, i}\n", + " }\n", + " m[n] = i\n", + " }\n", + " return nil\n", + "}\n" + ] + }, + { + "id": 19, + "title": "isPalindrome", + "language": "golang", + "blocks": [ + "func isPalindrome(x int) bool {\n", + " if x < 0 {\n", + " return false\n", + " }\n", + " orig, rev := x, 0\n", + " for x > 0 {\n", + " rev = rev*10 + x%10\n", + " x /= 10\n", + " }\n", + " return rev == orig\n", + "}\n" + ] + }, + { + "id": 20, + "title": "longestCommonPrefix", + "language": "golang", + "blocks": [ + "func longestCommonPrefix(strs []string) string {\n", + " if len(strs) == 0 {\n", + " return \"\"\n", + " }\n", + " pref := strs[0]\n", + " for _, s := range strs[1:] {\n", + " i := 0\n", + " for i < len(pref) && i < len(s) && pref[i] == s[i] {\n", + " i++\n", + " }\n", + " pref = pref[:i]\n", + " if pref == \"\" {\n", + " break\n", + " }\n", + " }\n", + " return pref\n", + "}\n" + ] + }, + { + "id": 21, + "title": "mergeTwoLists", + "language": "golang", + "blocks": [ + "func mergeTwoLists(l1, l2 *ListNode) *ListNode {\n", + " d := &ListNode{}\n", + " cur := d\n", + " for l1 != nil && l2 != nil {\n", + " if l1.Val < l2.Val {\n", + " cur.Next, l1 = l1, l1.Next\n", + " } else {\n", + " cur.Next, l2 = l2, l2.Next\n", + " }\n", + " cur = cur.Next\n", + " }\n", + " if l1 != nil {\n", + " cur.Next = l1\n", + " } else {\n", + " cur.Next = l2\n", + " }\n", + " return d.Next\n", + "}\n" + ] + }, + { + "id": 22, + "title": "removeDuplicates", + "language": "golang", + "blocks": [ + "func removeDuplicates(nums []int) int {\n", + " i := 1\n", + " for j := 1; j < len(nums); j++ {\n", + " if nums[j] != nums[i-1] {\n", + " nums[i], i = nums[j], i+1\n", + " }\n", + " }\n", + " return i\n", + "}\n" + ] + }, + { + "id": 23, + "title": "strStr", + "language": "golang", + "blocks": [ + "func strStr(haystack, needle string) int {\n", + " if len(needle) == 0 {\n", + " return 0\n", + " }\n", + " for i := 0; i+len(needle) <= len(haystack); i++ {\n", + " if haystack[i:i+len(needle)] == needle {\n", + " return i\n", + " }\n", + " }\n", + " return -1\n", + "}\n" + ] + }, + { + "id": 24, + "title": "searchInsert", + "language": "golang", + "blocks": [ + "func searchInsert(nums []int, target int) int {\n", + " l, r := 0, len(nums)-1\n", + " for l <= r {\n", + " m := (l + r) / 2\n", + " if nums[m] == target {\n", + " return m\n", + " }\n", + " if nums[m] < target {\n", + " l = m + 1\n", + " } else {\n", + " r = m - 1\n", + " }\n", + " }\n", + " return l\n", + "}\n" + ] + }, + { + "id": 25, + "title": "lengthOfLastWord", + "language": "golang", + "blocks": [ + "func lengthOfLastWord(s string) int {\n", + " l := 0\n", + " for i := len(s) - 1; i >= 0; i-- {\n", + " if s[i] != ' ' {\n", + " l++\n", + " } else if l > 0 {\n", + " break\n", + " }\n", + " }\n", + " return l\n", + "}\n" + ] + }, + { + "id": 26, + "title": "plusOne", + "language": "golang", + "blocks": [ + "func plusOne(digits []int) []int {\n", + " for i := len(digits) - 1; i >= 0; i-- {\n", + " digits[i]++\n", + " if digits[i] < 10 {\n", + " return digits\n", + " }\n", + " digits[i] = 0\n", + " }\n", + " return append([]int{1}, digits...)\n", + "}\n" + ] + }, + { + "id": 27, + "title": "addBinary", + "language": "golang", + "blocks": [ + "func addBinary(a, b string) string {\n", + " i, j, carry := len(a)-1, len(b)-1, 0\n", + " res := \"\"\n", + " for i >= 0 || j >= 0 || carry > 0 {\n", + " sum := carry\n", + " if i >= 0 {\n", + " sum += int(a[i] - '0')\n", + " i--\n", + " }\n", + " if j >= 0 {\n", + " sum += int(b[j] - '0')\n", + " j--\n", + " }\n", + " res = string('0'+sum%2) + res\n", + " carry = sum / 2\n", + " }\n", + " return res\n", + "}\n" + ] + }, + { + "id": 28, + "title": "mySqrt", + "language": "golang", + "blocks": [ + "func mySqrt(x int) int {\n", + " l, r := 0, x\n", + " for l <= r {\n", + " m := (l + r) / 2\n", + " if m*m <= x {\n", + " l = m + 1\n", + " } else {\n", + " r = m - 1\n", + " }\n", + " }\n", + " return r\n", + "}\n" + ] + }, + { + "id": 29, + "title": "climbStairs", + "language": "golang", + "blocks": [ + "func climbStairs(n int) int {\n", + " if n <= 3 {\n", + " return n\n", + " }\n", + " a, b := 2, 3\n", + " for i := 4; i <= n; i++ {\n", + " a, b = b, a+b\n", + " }\n", + " return b\n", + "}\n" + ] + }, + { + "id": 30, + "title": "deleteDuplicatesList", + "language": "golang", + "blocks": [ + "func deleteDuplicatesList(head *ListNode) *ListNode {\n", + " cur := head\n", + " for cur != nil && cur.Next != nil {\n", + " if cur.Val == cur.Next.Val {\n", + " cur.Next = cur.Next.Next\n", + " } else {\n", + " cur = cur.Next\n", + " }\n", + " }\n", + " return head\n", + "}\n" + ] + }, + { + "id": 31, + "title": "mergeSortedArray", + "language": "golang", + "blocks": [ + "func merge(nums1 []int, m int, nums2 []int, n int) {\n", + " i, j, k := m-1, n-1, m+n-1\n", + " for j >= 0 {\n", + " if i >= 0 && nums1[i] > nums2[j] {\n", + " nums1[k] = nums1[i]\n", + " i--\n", + " } else {\n", + " nums1[k] = nums2[j]\n", + " j--\n", + " }\n", + " k--\n", + " }\n", + "}\n" + ] + }, + { + "id": 32, + "title": "inorderTraversal", + "language": "golang", + "blocks": [ + "func inorderTraversal(root *TreeNode) []int {\n", + " res := []int{}\n", + " var dfs func(*TreeNode)\n", + " dfs = func(n *TreeNode) {\n", + " if n == nil {\n", + " return\n", + " }\n", + " dfs(n.Left)\n", + " res = append(res, n.Val)\n", + " dfs(n.Right)\n", + " }\n", + " dfs(root)\n", + " return res\n", + "}\n" + ] + }, + { + "id": 33, + "title": "isSameTree", + "language": "golang", + "blocks": [ + "func isSameTree(p, q *TreeNode) bool {\n", + " if p == nil || q == nil {\n", + " return p == q\n", + " }\n", + " if p.Val != q.Val {\n", + " return false\n", + " }\n", + " return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)\n", + "}\n" + ] + }, + { + "id": 34, + "title": "isSymmetric", + "language": "golang", + "blocks": [ + "func isSymmetric(root *TreeNode) bool {\n", + " var check func(a, b *TreeNode) bool\n", + " check = func(a, b *TreeNode) bool {\n", + " if a == nil || b == nil {\n", + " return a == b\n", + " }\n", + " if a.Val != b.Val {\n", + " return false\n", + " }\n", + " return check(a.Left, b.Right) && check(a.Right, b.Left)\n", + " }\n", + " if root == nil {\n", + " return true\n", + " }\n", + " return check(root.Left, root.Right)\n", + "}\n" + ] + }, + { + "id": 35, + "title": "twoSum", + "language": "python", + "blocks": [ + "def twoSum(nums, target):\n", + " lookup = {}\n", + " for i, num in enumerate(nums):\n", + " other = target - num\n", + " if other in lookup:\n", + " return [lookup[other], i]\n", + " lookup[num] = i\n", + " return []\n" + ] + }, + { + "id": 36, + "title": "isPalindrome", + "language": "python", + "blocks": [ + "def isPalindrome(x):\n", + " if x < 0:\n", + " return False\n", + " original, rev = x, 0\n", + " while x > 0:\n", + " rev = rev * 10 + (x % 10)\n", + " x //= 10\n", + " return rev == original\n" + ] + }, + { + "id": 37, + "title": "longestCommonPrefix", + "language": "python", + "blocks": [ + "def longestCommonPrefix(strs):\n", + " if not strs: return \"\"\n", + " prefix = strs[0]\n", + " for s in strs[1:]:\n", + " i = 0\n", + " while i < len(prefix) and i < len(s) and prefix[i] == s[i]:\n", + " i += 1\n", + " prefix = prefix[:i]\n", + " if not prefix:\n", + " break\n", + " return prefix\n" + ] + }, + { + "id": 38, + "title": "mergeTwoLists", + "language": "python", + "blocks": [ + "def mergeTwoLists(l1, l2):\n", + " dummy = ListNode()\n", + " cur = dummy\n", + " while l1 and l2:\n", + " if l1.val <= l2.val:\n", + " cur.next, l1 = l1, l1.next\n", + " else:\n", + " cur.next, l2 = l2, l2.next\n", + " cur = cur.next\n", + " cur.next = l1 or l2\n", + " return dummy.next\n" + ] + }, + { + "id": 39, + "title": "removeDuplicates", + "language": "python", + "blocks": [ + "def removeDuplicates(nums):\n", + " if not nums: return 0\n", + " i = 1\n", + " for j in range(1, len(nums)):\n", + " if nums[j] != nums[i - 1]:\n", + " nums[i] = nums[j]\n", + " i += 1\n", + " return i\n" + ] + }, + { + "id": 40, + "title": "strStr", + "language": "python", + "blocks": [ + "def strStr(haystack, needle):\n", + " if len(needle) == 0:\n", + " return 0\n", + " for i in range(len(haystack) - len(needle) + 1):\n", + " if haystack[i:i + len(needle)] == needle:\n", + " return i\n", + " return -1\n" + ] + }, + { + "id": 41, + "title": "searchInsert", + "language": "python", + "blocks": [ + "def searchInsert(nums, target):\n", + " left, right = 0, len(nums) - 1\n", + " while left <= right:\n", + " mid = (left + right) // 2\n", + " if nums[mid] == target:\n", + " return mid\n", + " elif nums[mid] < target:\n", + " left = mid + 1\n", + " else:\n", + " right = mid - 1\n", + " return left\n" + ] + }, + { + "id": 42, + "title": "lengthOfLastWord", + "language": "python", + "blocks": [ + "def lengthOfLastWord(s):\n", + " length = 0\n", + " for i in range(len(s) - 1, -1, -1):\n", + " if s[i] != ' ':\n", + " length += 1\n", + " elif length > 0:\n", + " break\n", + " return length\n" + ] + }, + { + "id": 43, + "title": "plusOne", + "language": "python", + "blocks": [ + "def plusOne(digits):\n", + " n = len(digits)\n", + " for i in range(n - 1, -1, -1):\n", + " if digits[i] < 9:\n", + " digits[i] += 1\n", + " return digits\n", + " digits[i] = 0\n", + " return [1] + digits\n" + ] + }, + { + "id": 44, + "title": "addBinary", + "language": "python", + "blocks": [ + "def addBinary(a, b):\n", + " i, j, carry = len(a) - 1, len(b) - 1, 0\n", + " res = []\n", + " while i >= 0 or j >= 0 or carry:\n", + " s = carry\n", + " if i >= 0:\n", + " s += int(a[i])\n", + " i -= 1\n", + " if j >= 0:\n", + " s += int(b[j])\n", + " j -= 1\n", + " res.append(str(s % 2))\n", + " carry = s // 2\n", + " return ''.join(reversed(res))\n" + ] + }, + { + "id": 45, + "title": "mySqrt", + "language": "python", + "blocks": [ + "def mySqrt(x):\n", + " left, right = 0, x\n", + " ans = 0\n", + " while left <= right:\n", + " mid = (left + right) // 2\n", + " if mid * mid <= x:\n", + " ans = mid\n", + " left = mid + 1\n", + " else:\n", + " right = mid - 1\n", + " return ans\n" + ] + }, + { + "id": 46, + "title": "climbStairs", + "language": "python", + "blocks": [ + "def climbStairs(n):\n", + " if n <= 3:\n", + " return n\n", + " prev2, prev1 = 2, 3\n", + " for _ in range(4, n + 1):\n", + " next_val = prev1 + prev2\n", + " prev2 = prev1\n", + " prev1 = next_val\n", + " return prev1\n" + ] + }, + { + "id": 47, + "title": "deleteDuplicates", + "language": "python", + "blocks": [ + "def deleteDuplicates(head):\n", + " cur = head\n", + " while cur and cur.next:\n", + " if cur.val == cur.next.val:\n", + " cur.next = cur.next.next\n", + " else:\n", + " cur = cur.next\n", + " return head\n" + ] + }, + { + "id": 48, + "title": "mergeSortedArray", + "language": "python", + "blocks": [ + "def merge(nums1, m, nums2, n):\n", + " # Modifica nums1 en sitio\n", + " i, j, k = m - 1, n - 1, m + n - 1\n", + " while j >= 0:\n", + " if i >= 0 and nums1[i] > nums2[j]:\n", + " nums1[k] = nums1[i]\n", + " i -= 1\n", + " else:\n", + " nums1[k] = nums2[j]\n", + " j -= 1\n", + " k -= 1\n" + ] + }, + { + "id": 49, + "title": "inorderTraversal", + "language": "python", + "blocks": [ + "def inorderTraversal(root):\n", + " res = []\n", + " def dfs(node):\n", + " if not node:\n", + " return\n", + " dfs(node.left)\n", + " res.append(node.val)\n", + " dfs(node.right)\n", + " dfs(root)\n", + " return res\n" + ] + }, + { + "id": 50, + "title": "isSameTree", + "language": "python", + "blocks": [ + "def isSameTree(p, q):\n", + " if not p and not q:\n", + " return True\n", + " if not p or not q or p.val != q.val:\n", + " return False\n", + " return isSameTree(p.left, q.left) and isSameTree(p.right, q.right)\n" + ] + }, + { + "id": 51, + "title": "isSymmetric", + "language": "python", + "blocks": [ + "def isSymmetric(root):\n", + " def isMirror(a, b):\n", + " if not a and not b:\n", + " return True\n", + " if not a or not b or a.val != b.val:\n", + " return False\n", + " return isMirror(a.left, b.right) and isMirror(a.right, b.left)\n", + " if not root:\n", + " return True\n", + " return isMirror(root.left, root.right)\n" + ] + }, + { + "id": 52, + "title": "Counter", + "language": "react", + "blocks": [ + "import { useState, useCallback } from 'react';\n", + "export default function App() {\n", + " const [count, setCount] = useState(0);\n", + " const update = useCallback((e) => {\n", + " const change = parseInt(e.currentTarget.dataset.change ?? '0');\n", + " setCount(currentCount => currentCount + change);\n", + " }, []);\n", + " return (\n", + "
\n", + " \n", + " \n", + "

Clicked: {count}

\n", + "
\n", + " );\n", + "}\n" + ] + }, + { + "id": 53, + "title": "Submit Form", + "language": "react", + "blocks": [ + "import { useState } from 'react';\n", + "export default function SubmitForm() {\n", + " const [formData, setFormData] = useState({ name: '', email: '' });\n", + " const handleChange = (e) => {\n", + " setFormData({ ...formData, [e.target.name]: e.target.value });\n", + " };\n", + " const handleSubmit = (e) => {\n", + " e.preventDefault();\n", + " alert(`Name: ${formData.name}, Email: ${formData.email}`);\n", + " };\n", + " return (\n", + "
\n", + " \n", + " \n", + " \n", + "
\n", + " );\n", + "}\n" + ] + }, + { + "id": 54, + "title": "Toggle Visibility", + "language": "react", + "blocks": [ + "import { useState } from 'react';\n", + "export default function ToggleVisibility() {\n", + " const [isVisible, setIsVisible] = useState(true);\n", + " const toggle = () => setIsVisible(!isVisible);\n", + " return (\n", + "
\n", + " \n", + " {isVisible &&

Now you see me!

}\n", + "
\n", + " );\n", + "}\n" + ] + }, + { + "id": 55, + "title": "Character Counter", + "language": "react", + "blocks": [ + "import { useState } from 'react';\n", + "export default function CharCounter() {\n", + " const [text, setText] = useState('');\n", + " return (\n", + "
\n", + "