From 868ab68ec3b22770133841ffc26bd7701537d723 Mon Sep 17 00:00:00 2001 From: Jackie Edwards Date: Fri, 31 May 2024 09:09:51 -0400 Subject: [PATCH] some cleanup --- bun.lockb | Bin 52266 -> 52266 bytes src/App.tsx | 357 ++++++++++++++-------------- src/assets/algorithms/bubblesort.ts | 2 +- src/assets/algorithms/mergesort.ts | 6 +- src/assets/algorithms/quicksort.ts | 4 +- src/business/commands.ts | 2 + src/types.ts | 2 + 7 files changed, 182 insertions(+), 191 deletions(-) diff --git a/bun.lockb b/bun.lockb index 21c5b119a872d33cf66fbec2cd919f8e7a02a6a2..f6dbe5c5481c5399be56d5deb5f98ed2adda439b 100755 GIT binary patch delta 23 fcmZ2AgL%~q<_(=49E@?MdIoxi7Mmw_%yb3-X*mdm delta 23 acmZ2AgL%~q<_(=4983%luz6y~OlJUF1P1;9 diff --git a/src/App.tsx b/src/App.tsx index ac573d0..4a2b00c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,126 +1,124 @@ import { MonacoEditor } from "solid-monaco"; -import type { Monaco } from '@monaco-editor/loader'; -// import { useCallback, useEffect, useRef, useState } from "solid-js"; -import { PanelGroup, Panel, PanelResizeHandle } from "solid-resizable-panels-port"; -// import { useInterval } from "usehooks-ts"; -// import defaultScriptText from "./defaultScript?raw"; +import type { Monaco } from "@monaco-editor/loader"; +import { + PanelGroup, + Panel, + PanelResizeHandle, +} from "solid-resizable-panels-port"; import editorExtraTypes from "./types?raw"; import "./business/audio"; import "./App.css"; -import { quickSort } from "./business/commands"; +import { quickSort, VisualizerGenerator } from "./business/commands"; import { transformTypescript } from "./ts"; import { createOscillator } from "./business/audio"; -// import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -// import * as Icons from "@fortawesome/free-solid-svg-icons"; import { Pause, Play, RefreshCw, Volume2, VolumeX } from "lucide-solid"; import { createEffect, createSignal, Index } from "solid-js"; -import quicksortScript from './assets/algorithms/quicksort?raw'; -import bubblesortScript from './assets/algorithms/bubblesort?raw'; -import mergesortScript from './assets/algorithms/mergesort?raw'; +import quicksortScript from "./assets/algorithms/quicksort?raw"; +import bubblesortScript from "./assets/algorithms/bubblesort?raw"; +import mergesortScript from "./assets/algorithms/mergesort?raw"; +import { createStore, unwrap } from "solid-js/store"; +import { produce } from "solid-js/store"; const JS_EXTRA_FUNCTIONS = transformTypescript(editorExtraTypes); -// console.log(JS_EXTRA_FUNCTIONS); function setUpMonaco(monaco: Monaco): void { - monaco.editor.setTheme('vs-dark'); + monaco.editor.setTheme("vs-dark"); monaco.languages.typescript.typescriptDefaults.addExtraLib(editorExtraTypes); } export default function App() { const [itemCount, setItemCount] = createSignal(50); let interval: ReturnType | null = null; - const [swaps, setSwaps] = createSignal(Array(itemCount()).fill(false)); - const [sorted, setSorted] = createSignal(Array(itemCount()).fill(false)); - const [items, setItems] = createSignal([...Array(itemCount()).keys()].sort(() => Math.random() - 0.5)); - const [ justSet, setJustSet ] = createSignal(Array(itemCount()).fill(false)); - - const [cursors, setCursors] = createSignal([]); const [defaultScript, setDefaultScript] = createSignal(quicksortScript); const [latestCursor, setLatestCursor] = createSignal(-1); + const [buckets, setBuckets] = createStore({ + swaps: Array(itemCount()).fill(false), + sorted: Array(itemCount()).fill(false), + items: [...Array(itemCount()).keys()].sort(() => Math.random() - 0.5), + justSet: Array(itemCount()).fill(false), + cursors: new Array(), + }); + const oscillator = createOscillator(); - const [commandGenerator, setCommandGenerator] = createSignal | null>(quickSort(items())); + const [commandGenerator, setCommandGenerator] = + createSignal(quickSort(buckets.items)); - const [commandGeneratorFunction, setCommandGeneratorFunction] = createSignal(quickSort); + const [commandGeneratorFunction, setCommandGeneratorFunction] = + createSignal(quickSort); const [sortPlaying, setSortPlaying] = createSignal(false); const [muted, setMuted] = createSignal(false); const [sortFinished, setSortFinished] = createSignal(false); const [delay, setDelay] = createSignal(10); - // useEffect(() => { - // if(commandGeneratorFunction) setCommandGenerator(commandGeneratorFunction(items)); - // }, [commandGenerator]) - // createEffect(() => { - // setItems([...Array(itemCount()).keys()].sort(() => Math.random() - 0.5)); - // }, [itemCount()]); createEffect(() => { if (interval) clearInterval(interval); const gen = commandGenerator(); if (sortPlaying() && gen) { interval = setInterval(() => { - // if (!commandGenerator) return; - // if (!sortPlaying) return; - - const command = gen.next(items()); + const command = gen.next(buckets.items); if (!command.done) { - swaps().fill(false); - justSet().fill(false); + setBuckets( + produce(({ swaps, justSet }) => { + swaps.fill(false); + justSet.fill(false); + }) + ); switch (command.value.kind) { case "swap": { - const [i, j] = [command.value.firstIndex, command.value.secondIndex]; - swaps()[i] = true; - swaps()[j] = true; - [items()[i], items()[j]] = [items()[j], items()[i]]; + const [i, j] = [ + command.value.firstIndex, + command.value.secondIndex, + ]; + setBuckets("swaps", i, true); + setBuckets("swaps", j, true); + setBuckets( + produce(({ items }) => { + [items[i], items[j]] = [items[j], items[i]]; + }) + ); break; } case "setCursors": { const newCursor = command.value.cursors.find( - (c) => !cursors().includes(c) + (c) => !buckets.cursors.includes(c) ); if (newCursor) { setLatestCursor(newCursor); } - setCursors(command.value.cursors); + setBuckets("cursors", command.value.cursors); break; } case "sorted": { for (const index of command.value.indexes) { - sorted()[index] = true; + setBuckets("sorted", index, true); } break; } case "notSorted": { for (const index of command.value.indexes) { - sorted()[index] = false; + setBuckets("sorted", index, false); } break; } case "set": { for (const [index, value] of command.value.values) { - items()[index] = value; - justSet()[index] = true; + setBuckets("items", index, value); + setBuckets("justSet", index, true); } } } - setSorted(sorted().slice()); - setSwaps(swaps().slice()); - setItems(items().slice()); - setJustSet(justSet().slice()); - if (sorted().every((s) => s)) { + if (buckets.sorted.every((s) => s)) { setSortPlaying(false); setSortFinished(true); oscillator.mute(); } } oscillator.oscillator.frequency.setValueAtTime( - 150 + ((latestCursor() / itemCount()) * 1350), + 150 + (latestCursor() / itemCount()) * 1350, oscillator.ctx.currentTime ); }, delay()); @@ -129,107 +127,49 @@ export default function App() { } }); - // Run a step of the sorting algorithm every x ms - // useInterval(() => { - // if (!commandGenerator) return; - // if (!sortPlaying) return; - - // const command = commandGenerator.next(items); - // if (!command.done) { - // swaps.fill(false); - // switch (command.value.kind) { - // case "swap": { - // const [i, j] = [command.value.firstIndex, command.value.secondIndex]; - // swaps[i] = true; - // swaps[j] = true; - // [items[i], items[j]] = [items[j], items[i]]; - // break; - // } - // case "setCursors": { - // const newCursor = command.value.cursors.find( - // (c) => !cursors.includes(c) - // ); - // if (newCursor) { - // setLatestCursor(newCursor); - // } - // setCursors(command.value.cursors); - // break; - // } - // case "sorted": { - // for (const index of command.value.indexes) { - // sorted[index] = true; - // } - // break; - // } - // case "notSorted": { - // for (const index of command.value.indexes) { - // sorted[index] = false; - // } - // break; - // } - // } - // setSorted(sorted.slice()); - // setSwaps(swaps.slice()); - // setItems(items.slice()); - // if (sorted.every((s) => s)) { - // setSortPlaying(false); - // setSortFinished(true); - // oscillator.current.mute(); - // } - // } - // oscillator.current.oscillator.frequency.setValueAtTime( - // 150 + ((latestCursor / itemCount) * 1350), - // 0 - // ); - // }, 10); - - const reset = /*useCallback(*/() => { - setItems( - [...Array(itemCount()).keys()].sort(() => Math.random() - 0.5) + const reset = () => { + const items = [...Array(itemCount()).keys()].sort( + () => Math.random() - 0.5 ); - setSorted(items().map(() => false)); - setSwaps(items().map(() => false)); + setBuckets({ + items: items, + sorted: items.map(() => false), + swaps: items.map(() => false), + cursors: [], + }); setSortFinished(false); - setCursors([]); - setCommandGenerator(commandGeneratorFunction()(items())); + setCommandGenerator(commandGeneratorFunction()(buckets.items)); setLatestCursor(0); - - }/*, [setItems, itemCount, setSorted, setSwaps, setCursors, commandGeneratorFunction, setCommandGenerator])*/; + }; const onTextChange = async (text: string) => { setDefaultScript(text); try { const javascriptCode = transformTypescript(text); - // if (lastScript === javascriptCode) return; - // else { - // } if (javascriptCode) { - // lastScript = javascriptCode; const newGenerator = ( await import( /* @vite-ignore */ URL.createObjectURL( - new Blob( - [ - `${JS_EXTRA_FUNCTIONS} + new Blob( + [ + `${JS_EXTRA_FUNCTIONS} ${javascriptCode}`, - ], - { type: "text/javascript" } + ], + { type: "text/javascript" } + ) ) ) - ) ).default; if (typeof newGenerator === "function") { setCommandGeneratorFunction(() => newGenerator); reset(); } else { - // setCommandGenerator(null); reset(); } } } catch (e) { setCommandGenerator(null); - // console.warn(e); } }; @@ -267,92 +207,139 @@ export default function App() {
- + - { setItemCount(parseInt(e.target.value)); reset() }} /> + { + setItemCount(parseInt(e.target.value)); + reset(); + }} + />
- {/* */} - Delay of setDelay(parseFloat(e.target.value) || 10)} value={delay()} step="1" type="number" min="1" max="1000" />ms + + Delay of{" "} + setDelay(parseFloat(e.target.value) || 10)} + value={delay()} + step="1" + type="number" + min="1" + max="1000" + /> + ms +
- +
- - {(item, index) => { - return ( - - - - ); - }} + + + {(item, index) => { + return ( + + + + ); + }} +
); -} \ No newline at end of file +} diff --git a/src/assets/algorithms/bubblesort.ts b/src/assets/algorithms/bubblesort.ts index ecd5ae4..ec237f8 100644 --- a/src/assets/algorithms/bubblesort.ts +++ b/src/assets/algorithms/bubblesort.ts @@ -1,4 +1,4 @@ -export default function* bubbleSort(items: number[]): Generator { +export default function* bubbleSort(items: number[]): VisualizerGenerator { let clean = false; while (!clean) { clean = true; diff --git a/src/assets/algorithms/mergesort.ts b/src/assets/algorithms/mergesort.ts index 3e974eb..bd65977 100644 --- a/src/assets/algorithms/mergesort.ts +++ b/src/assets/algorithms/mergesort.ts @@ -1,5 +1,5 @@ -export default function* mergeSort(items: number[]): Generator { - function* merge(low: number, mid: number, high: number): Generator { +export default function* mergeSort(items: number[]): VisualizerGenerator { + function* merge(low: number, mid: number, high: number): VisualizerGenerator { let left = items.slice(low, mid + 1); let right = items.slice(mid + 1, high + 1); let i = 0, j = 0, k = low; @@ -33,7 +33,7 @@ export default function* mergeSort(items: number[]): Generator { + function* sort(low: number, high: number): VisualizerGenerator { if (low < high) { const mid = Math.floor((low + high) / 2); yield* sort(low, mid); diff --git a/src/assets/algorithms/quicksort.ts b/src/assets/algorithms/quicksort.ts index 1da22b5..8b013a0 100644 --- a/src/assets/algorithms/quicksort.ts +++ b/src/assets/algorithms/quicksort.ts @@ -1,4 +1,4 @@ -export default function* quicksort(items: number[]): Generator { +export default function* quicksort(items: number[]): VisualizerGenerator { yield* _quicksort(items, 0, items.length - 1); // Final sweep, three at a time so it's faster @@ -8,7 +8,7 @@ export default function* quicksort(items: number[]): Generator { +function* _quicksort(arr: number[], low: number, high: number): VisualizerGenerator { arr = yield cursors([low, high]); if (low < high) { const [pivotIndex, updatedArr] = yield* partition(arr, low, high); diff --git a/src/business/commands.ts b/src/business/commands.ts index 7ae6942..6edb734 100644 --- a/src/business/commands.ts +++ b/src/business/commands.ts @@ -26,6 +26,8 @@ export type VisualizerCommand = | VisualizerNotSortedCommand | VisualizerSetCommand; +export type VisualizerGenerator = Generator; + export function swap( firstIndex: number, secondIndex: number diff --git a/src/types.ts b/src/types.ts index 10b327a..d49921b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,6 +27,8 @@ type VisualizerCommand = | VisualizerNotSortedCommand | VisualizerSetCommand; +type VisualizerGenerator = Generator; + // eslint-disable-next-line @typescript-eslint/no-unused-vars function swap(firstIndex: number, secondIndex: number): VisualizerSwapCommand { return { kind: "swap", firstIndex, secondIndex };