initial implementation of sorting algorithms
This commit is contained in:
79
GEMINI.md
Normal file
79
GEMINI.md
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# Gemini CLI Context for playground-frontend
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is the frontend of the Playground project, built with Angular 21 and Angular Material. It includes features like a light/dark theme toggle and multi-language support via ngx-translate. The application is a static Single Page Application (SPA) served by NGINX.
|
||||||
|
|
||||||
|
**Key Technologies:**
|
||||||
|
* **Frontend Framework:** Angular 21
|
||||||
|
* **UI Components & Theming:** Angular Material
|
||||||
|
* **Internationalization:** ngx-translate
|
||||||
|
* **Server:** NGINX (for serving the SPA)
|
||||||
|
* **Containerization:** Docker
|
||||||
|
* **CI/CD:** GitHub Actions
|
||||||
|
|
||||||
|
## Building and Running
|
||||||
|
|
||||||
|
### Local Development
|
||||||
|
|
||||||
|
1. **Install dependencies:**
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
2. **Start development server:**
|
||||||
|
```bash
|
||||||
|
ng serve --open
|
||||||
|
```
|
||||||
|
The app will run at `http://localhost:4200`.
|
||||||
|
|
||||||
|
### Building for Production
|
||||||
|
|
||||||
|
To build the project for production, which creates the optimized static files:
|
||||||
|
```bash
|
||||||
|
ng build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
To run the unit tests:
|
||||||
|
```bash
|
||||||
|
ng test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linting
|
||||||
|
|
||||||
|
To lint the codebase:
|
||||||
|
```bash
|
||||||
|
ng lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
To build and run the application using Docker locally:
|
||||||
|
|
||||||
|
1. **Build Docker image:**
|
||||||
|
```bash
|
||||||
|
docker build -t playground-frontend:local .
|
||||||
|
```
|
||||||
|
2. **Run Docker container:**
|
||||||
|
```bash
|
||||||
|
docker run -p 8080:80 playground-frontend:local
|
||||||
|
```
|
||||||
|
Then open `http://localhost:8080` in your browser.
|
||||||
|
|
||||||
|
## Development Conventions
|
||||||
|
|
||||||
|
* **Language:** TypeScript
|
||||||
|
* **Framework:** Angular
|
||||||
|
* **Styling:** SCSS (based on `styles.scss` and component-specific `.scss` files).
|
||||||
|
* **Linting:** ESLint is configured (see `eslint.config.js` and `package.json` scripts).
|
||||||
|
* **Internationalization:** Uses `ngx-translate` with `en.json` and `de.json` asset files.
|
||||||
|
|
||||||
|
## Project Structure (Key Areas)
|
||||||
|
|
||||||
|
* `src/app/`: Contains the main application logic, components, services, and routing.
|
||||||
|
* `src/app/pages/`: Specific pages of the application (e.g., about, algorithms, imprint, projects).
|
||||||
|
* `src/assets/`: Static assets including images, internationalization files (`i18n`), and logos.
|
||||||
|
* `Dockerfile`: Defines the Docker image for the application.
|
||||||
|
* `nginx.conf`: NGINX configuration for serving the SPA.
|
||||||
|
* `.gitea/workflows/`: Contains CI/CD workflows (e.g., `build-Frontend-a.yml`).
|
||||||
@@ -8,6 +8,7 @@ export const routes: Routes = [
|
|||||||
{ path: RouterConstants.PROJECTS.PATH, component: RouterConstants.PROJECTS.COMPONENT},
|
{ path: RouterConstants.PROJECTS.PATH, component: RouterConstants.PROJECTS.COMPONENT},
|
||||||
{ path: RouterConstants.ALGORITHMS.PATH, component: RouterConstants.ALGORITHMS.COMPONENT},
|
{ path: RouterConstants.ALGORITHMS.PATH, component: RouterConstants.ALGORITHMS.COMPONENT},
|
||||||
{ path: RouterConstants.PATHFINDING.PATH, component: RouterConstants.PATHFINDING.COMPONENT},
|
{ path: RouterConstants.PATHFINDING.PATH, component: RouterConstants.PATHFINDING.COMPONENT},
|
||||||
|
{ path: RouterConstants.SORTING.PATH, component: RouterConstants.SORTING.COMPONENT},
|
||||||
{ path: RouterConstants.IMPRINT.PATH, component: RouterConstants.IMPRINT.COMPONENT},
|
{ path: RouterConstants.IMPRINT.PATH, component: RouterConstants.IMPRINT.COMPONENT},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {ProjectsComponent} from '../pages/projects/projects.component';
|
|||||||
import {ImprintComponent} from '../pages/imprint/imprint.component';
|
import {ImprintComponent} from '../pages/imprint/imprint.component';
|
||||||
import {AlgorithmsComponent} from '../pages/algorithms/algorithms.component';
|
import {AlgorithmsComponent} from '../pages/algorithms/algorithms.component';
|
||||||
import {PathfindingComponent} from '../pages/algorithms/pathfinding/pathfinding.component';
|
import {PathfindingComponent} from '../pages/algorithms/pathfinding/pathfinding.component';
|
||||||
|
import {SortingComponent} from '../pages/algorithms/sorting/sorting.component';
|
||||||
|
|
||||||
export class RouterConstants {
|
export class RouterConstants {
|
||||||
|
|
||||||
@@ -30,6 +31,12 @@ export class RouterConstants {
|
|||||||
COMPONENT: PathfindingComponent
|
COMPONENT: PathfindingComponent
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static readonly SORTING = {
|
||||||
|
PATH: 'algorithms/sorting',
|
||||||
|
LINK: '/algorithms/sorting',
|
||||||
|
COMPONENT: SortingComponent
|
||||||
|
};
|
||||||
|
|
||||||
static readonly IMPRINT = {
|
static readonly IMPRINT = {
|
||||||
PATH: 'imprint',
|
PATH: 'imprint',
|
||||||
LINK: '/imprint',
|
LINK: '/imprint',
|
||||||
|
|||||||
@@ -14,6 +14,12 @@ export class AlgorithmsService {
|
|||||||
title: 'ALGORITHM.PATHFINDING.TITLE',
|
title: 'ALGORITHM.PATHFINDING.TITLE',
|
||||||
description: 'ALGORITHM.PATHFINDING.DESCRIPTION',
|
description: 'ALGORITHM.PATHFINDING.DESCRIPTION',
|
||||||
routerLink: RouterConstants.PATHFINDING.LINK
|
routerLink: RouterConstants.PATHFINDING.LINK
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'sorting',
|
||||||
|
title: 'ALGORITHM.SORTING.TITLE',
|
||||||
|
description: 'ALGORITHM.SORTING.DESCRIPTION',
|
||||||
|
routerLink: RouterConstants.SORTING.LINK
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
97
src/app/pages/algorithms/sorting/service/sorting.service.ts
Normal file
97
src/app/pages/algorithms/sorting/service/sorting.service.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { SortData } from '../sorting.models';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class SortingService {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
async bubbleSort(array: SortData[], animationSpeed: number): Promise<void> {
|
||||||
|
console.log(animationSpeed);
|
||||||
|
const n = array.length;
|
||||||
|
for (let i = 0; i < n - 1; i++) {
|
||||||
|
console.log("1");
|
||||||
|
for (let j = 0; j < n - i - 1; j++) {
|
||||||
|
console.log("2");
|
||||||
|
array[j].state = 'comparing';
|
||||||
|
array[j + 1].state = 'comparing';
|
||||||
|
await this.delay(animationSpeed);
|
||||||
|
|
||||||
|
if (array[j].value > array[j + 1].value) {
|
||||||
|
// Swap elements
|
||||||
|
const temp = array[j].value;
|
||||||
|
array[j].value = array[j + 1].value;
|
||||||
|
array[j + 1].value = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
array[j].state = 'unsorted';
|
||||||
|
array[j + 1].state = 'unsorted';
|
||||||
|
}
|
||||||
|
array[n - 1 - i].state = 'sorted'; // Mark the largest element as sorted
|
||||||
|
}
|
||||||
|
array[0].state = 'sorted'; // Mark the last element as sorted (if n > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async selectionSort(array: SortData[], animationSpeed: number): Promise<void> {
|
||||||
|
const n = array.length;
|
||||||
|
for (let i = 0; i < n - 1; i++) {
|
||||||
|
let minIdx = i;
|
||||||
|
array[i].state = 'comparing';
|
||||||
|
for (let j = i + 1; j < n; j++) {
|
||||||
|
array[j].state = 'comparing';
|
||||||
|
await this.delay(animationSpeed);
|
||||||
|
|
||||||
|
if (array[j].value < array[minIdx].value) {
|
||||||
|
minIdx = j;
|
||||||
|
}
|
||||||
|
if (j !== minIdx) { // Only reset if it wasn't the minimum
|
||||||
|
array[j].state = 'unsorted';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (minIdx !== i) {
|
||||||
|
// Swap elements
|
||||||
|
const temp = array[i].value;
|
||||||
|
array[i].value = array[minIdx].value;
|
||||||
|
array[minIdx].value = temp;
|
||||||
|
}
|
||||||
|
array[i].state = 'sorted'; // Mark the current element as sorted
|
||||||
|
if (minIdx !== i) {
|
||||||
|
array[minIdx].state = 'unsorted';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array[n - 1].state = 'sorted'; // Mark the last element as sorted
|
||||||
|
}
|
||||||
|
|
||||||
|
async insertionSort(array: SortData[], animationSpeed: number): Promise<void> {
|
||||||
|
const n = array.length;
|
||||||
|
for (let i = 1; i < n; i++) {
|
||||||
|
const key = array[i].value;
|
||||||
|
array[i].state = 'comparing';
|
||||||
|
let j = i - 1;
|
||||||
|
|
||||||
|
while (j >= 0 && array[j].value > key) {
|
||||||
|
array[j].state = 'comparing';
|
||||||
|
await this.delay(animationSpeed);
|
||||||
|
|
||||||
|
array[j + 1].value = array[j].value;
|
||||||
|
array[j + 1].state = 'unsorted'; // Reset after shifting
|
||||||
|
j = j - 1;
|
||||||
|
}
|
||||||
|
await this.delay(animationSpeed); // Delay after loop for final position
|
||||||
|
array[j + 1].value = key;
|
||||||
|
array[i].state = 'unsorted'; // Reset original 'key' position
|
||||||
|
array.forEach((item, idx) => { // Mark sorted up to i
|
||||||
|
if (idx <= i) {
|
||||||
|
item.state = 'sorted';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
array.forEach(item => item.state = 'sorted'); // Mark all as sorted at the end
|
||||||
|
}
|
||||||
|
|
||||||
|
private delay(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/app/pages/algorithms/sorting/sorting.component.html
Normal file
44
src/app/pages/algorithms/sorting/sorting.component.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<div class="sorting-container">
|
||||||
|
<mat-card class="sorting-card">
|
||||||
|
<mat-card-header>
|
||||||
|
<mat-card-title>{{ 'ALGORITHM.SORTING.TITLE' | translate }}</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<div class="controls-panel">
|
||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>{{ 'ALGORITHM.SORTING.ALGORITHM' | translate }}</mat-label>
|
||||||
|
<mat-select [(ngModel)]="selectedAlgorithm" [disabled]="isSorting">
|
||||||
|
@for (algo of availableAlgorithms; track algo.value) {
|
||||||
|
<mat-option [value]="algo.value">{{ algo.name }}</mat-option>
|
||||||
|
}
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<button mat-raised-button color="primary" (click)="startSorting()" [disabled]="isSorting">
|
||||||
|
<mat-icon>play_arrow</mat-icon> {{ 'ALGORITHM.SORTING.START' | translate }}
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button color="warn" (click)="resetSorting()" [disabled]="isSorting">
|
||||||
|
<mat-icon>refresh</mat-icon> {{ 'ALGORITHM.SORTING.RESET' | translate }}
|
||||||
|
</button>
|
||||||
|
<button mat-raised-button (click)="generateNewArray()" [disabled]="isSorting">
|
||||||
|
<mat-icon>add_box</mat-icon> {{ 'ALGORITHM.SORTING.GENERATE_NEW_ARRAY' | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="info-panel">
|
||||||
|
<p>{{ 'ALGORITHM.SORTING.EXECUTION_TIME' | translate }}: {{ executionTime }} ms</p>
|
||||||
|
</div>
|
||||||
|
<div class="visualization-area">
|
||||||
|
@for (item of sortArray; track $index) {
|
||||||
|
<div
|
||||||
|
class="bar"
|
||||||
|
[style.height.px]="item.value * 3"
|
||||||
|
[class.unsorted]="item.state === 'unsorted'"
|
||||||
|
[class.comparing]="item.state === 'comparing'"
|
||||||
|
[class.sorted]="item.state === 'sorted'"
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
62
src/app/pages/algorithms/sorting/sorting.component.scss
Normal file
62
src/app/pages/algorithms/sorting/sorting.component.scss
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
.sorting-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 20px;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.sorting-card {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1200px;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
.controls-panel {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.visualization-area {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
height: 300px; /* Max height for bars */
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
gap: 1px;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
flex-grow: 1;
|
||||||
|
background-color: #424242; /* Default unsorted color */
|
||||||
|
transition: height 0.1s ease-in-out, background-color 0.1s ease-in-out;
|
||||||
|
width: 10px; /* Default width, flex-grow will adjust */
|
||||||
|
min-width: 1px; /* Ensure bars are always visible */
|
||||||
|
|
||||||
|
&.unsorted {
|
||||||
|
background-color: #424242;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.comparing {
|
||||||
|
background-color: #ffeb3b; /* Yellow for comparing */
|
||||||
|
}
|
||||||
|
|
||||||
|
&.sorted {
|
||||||
|
background-color: #4caf50; /* Green for sorted */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-panel {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/app/pages/algorithms/sorting/sorting.component.ts
Normal file
92
src/app/pages/algorithms/sorting/sorting.component.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import {MatCardModule} from "@angular/material/card";
|
||||||
|
import {MatFormFieldModule} from "@angular/material/form-field";
|
||||||
|
import {MatSelectModule} from "@angular/material/select";
|
||||||
|
import {MatButtonModule} from "@angular/material/button";
|
||||||
|
import {MatIconModule} from "@angular/material/icon";
|
||||||
|
import {TranslateModule} from "@ngx-translate/core";
|
||||||
|
import { SortingService } from './service/sorting.service';
|
||||||
|
import { SortData } from './sorting.models';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-sorting',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, MatCardModule, MatFormFieldModule, MatSelectModule, MatButtonModule, MatIconModule, TranslateModule, FormsModule],
|
||||||
|
templateUrl: './sorting.component.html',
|
||||||
|
styleUrls: ['./sorting.component.scss']
|
||||||
|
})
|
||||||
|
export class SortingComponent implements OnInit {
|
||||||
|
|
||||||
|
sortArray: SortData[] = [];
|
||||||
|
arraySize: number = 50;
|
||||||
|
maxArrayValue: number = 100;
|
||||||
|
animationSpeed: number = 10; // Milliseconds per step
|
||||||
|
|
||||||
|
// Placeholder for available sorting algorithms
|
||||||
|
availableAlgorithms: { name: string; value: string }[] = [
|
||||||
|
{ name: 'Bubble Sort', value: 'bubbleSort' },
|
||||||
|
{ name: 'Selection Sort', value: 'selectionSort' },
|
||||||
|
{ name: 'Insertion Sort', value: 'insertionSort' },
|
||||||
|
];
|
||||||
|
selectedAlgorithm: string = this.availableAlgorithms[0].value;
|
||||||
|
isSorting: boolean = false;
|
||||||
|
executionTime: number = 0;
|
||||||
|
|
||||||
|
constructor(private sortingService: SortingService) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.generateNewArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
generateNewArray(): void {
|
||||||
|
this.isSorting = false;
|
||||||
|
this.executionTime = 0;
|
||||||
|
this.sortArray = [];
|
||||||
|
for (let i = 0; i < this.arraySize; i++) {
|
||||||
|
this.sortArray.push({
|
||||||
|
value: Math.floor(Math.random() * this.maxArrayValue) + 1,
|
||||||
|
state: 'unsorted'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async startSorting(): Promise<void> {
|
||||||
|
if (this.isSorting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('Starting sorting...');
|
||||||
|
this.isSorting = true;
|
||||||
|
this.executionTime = 0;
|
||||||
|
|
||||||
|
// Reset states for visualization
|
||||||
|
this.sortArray.forEach(item => item.state = 'unsorted');
|
||||||
|
const startTime = performance.now();
|
||||||
|
console.log("Select algorithm ", this.selectedAlgorithm);
|
||||||
|
|
||||||
|
switch (this.selectedAlgorithm) {
|
||||||
|
case 'bubbleSort':
|
||||||
|
await this.sortingService.bubbleSort(this.sortArray, this.animationSpeed);
|
||||||
|
break;
|
||||||
|
case 'selectionSort':
|
||||||
|
await this.sortingService.selectionSort(this.sortArray, this.animationSpeed);
|
||||||
|
break;
|
||||||
|
case 'insertionSort':
|
||||||
|
await this.sortingService.insertionSort(this.sortArray, this.animationSpeed);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn('Unknown sorting algorithm selected:', this.selectedAlgorithm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log("Done with sorting...");
|
||||||
|
const endTime = performance.now();
|
||||||
|
this.executionTime = Math.round(endTime - startTime);
|
||||||
|
this.isSorting = false;
|
||||||
|
this.sortArray.forEach(item => item.state = 'sorted'); // Mark all as sorted after completion
|
||||||
|
}
|
||||||
|
|
||||||
|
resetSorting(): void {
|
||||||
|
this.generateNewArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
4
src/app/pages/algorithms/sorting/sorting.models.ts
Normal file
4
src/app/pages/algorithms/sorting/sorting.models.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export interface SortData {
|
||||||
|
value: number;
|
||||||
|
state: 'sorted' | 'comparing' | 'unsorted';
|
||||||
|
}
|
||||||
@@ -326,6 +326,15 @@
|
|||||||
"DESCRIPTION": "Vergleich von Dijkstra vs. A*.",
|
"DESCRIPTION": "Vergleich von Dijkstra vs. A*.",
|
||||||
"GRID_HEIGHT": "Höhe",
|
"GRID_HEIGHT": "Höhe",
|
||||||
"GRID_WIDTH": "Beite"
|
"GRID_WIDTH": "Beite"
|
||||||
|
},
|
||||||
|
"SORTING": {
|
||||||
|
"TITLE": "Sortieralgorithmen",
|
||||||
|
"DESCRIPTION": "Visualisierung verschiedener Sortieralgorithmen.",
|
||||||
|
"ALGORITHM": "Algorithmus",
|
||||||
|
"START": "Sortierung starten",
|
||||||
|
"RESET": "Zurücksetzen",
|
||||||
|
"GENERATE_NEW_ARRAY": "Neues Array generieren",
|
||||||
|
"EXECUTION_TIME": "Ausführungszeit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,6 +326,15 @@
|
|||||||
"DESCRIPTION": "Comparing of Dijkstra vs. A*.",
|
"DESCRIPTION": "Comparing of Dijkstra vs. A*.",
|
||||||
"GRID_HEIGHT": "Height",
|
"GRID_HEIGHT": "Height",
|
||||||
"GRID_WIDTH": "Width"
|
"GRID_WIDTH": "Width"
|
||||||
|
},
|
||||||
|
"SORTING": {
|
||||||
|
"TITLE": "Sorting Algorithms",
|
||||||
|
"DESCRIPTION": "Visualizing various sorting algorithms.",
|
||||||
|
"ALGORITHM": "Algorithm",
|
||||||
|
"START": "Start Sorting",
|
||||||
|
"RESET": "Reset",
|
||||||
|
"GENERATE_NEW_ARRAY": "Generate New Array",
|
||||||
|
"EXECUTION_TIME": "Execution Time"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user