feat: palindrome substring

This commit is contained in:
Brian Pooe 2023-10-11 17:28:30 +02:00
parent 6c8e1731ea
commit c8c19c3388
20 changed files with 322 additions and 1 deletions

View file

@ -4,7 +4,8 @@
"license": "MIT",
"scripts": {
"part1": "nx run part-1-html-css:serve",
"part2": "nx run part-2-javascript:serve"
"part2": "nx run part-2-javascript:serve",
"part4": "nx run part-4-problem-solving:serve"
},
"private": true,
"devDependencies": {

View file

@ -0,0 +1,33 @@
{
"extends": [
"../.eslintrc.json"
],
"ignorePatterns": [
"!**/*"
],
"overrides": [
{
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {}
},
{
"files": [
"*.ts",
"*.tsx"
],
"rules": {}
},
{
"files": [
"*.js",
"*.jsx"
],
"rules": {}
}
]
}

View file

@ -0,0 +1,8 @@
{
"jsc": {
"parser": {
"syntax": "typescript"
},
"target": "es2016"
}
}

View file

@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'part-4-problem-solving',
preset: '../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
transform: {
'^.+\\.[tj]s$': '@swc/jest'
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../coverage/part-4-problem-solving'
};

View file

@ -0,0 +1,86 @@
{
"name": "part-4-problem-solving",
"$schema": "../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "part-4-problem-solving/src",
"tags": [],
"targets": {
"build": {
"executor": "@nx/webpack:webpack",
"outputs": [
"{options.outputPath}"
],
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/part-4-problem-solving",
"compiler": "swc",
"main": "part-4-problem-solving/src/main.ts",
"tsConfig": "part-4-problem-solving/tsconfig.app.json",
"webpackConfig": "part-4-problem-solving/webpack.config.js",
"assets": [
"part-4-problem-solving/src/assets"
],
"index": "part-4-problem-solving/src/index.html",
"baseHref": "/",
"styles": [
"part-4-problem-solving/src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"fileReplacements": [
{
"replace": "part-4-problem-solving/src/environments/environment.ts",
"with": "part-4-problem-solving/src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"executor": "@nx/webpack:dev-server",
"options": {
"buildTarget": "part-4-problem-solving:build"
},
"configurations": {
"production": {
"buildTarget": "part-4-problem-solving:build:production"
}
}
},
"lint": {
"executor": "@nx/linter:eslint",
"outputs": [
"{options.outputFile}"
],
"options": {
"lintFilePatterns": [
"part-4-problem-solving/**/*.ts"
]
}
},
"test": {
"executor": "@nx/jest:jest",
"outputs": [
"{workspaceRoot}/coverage/{projectRoot}"
],
"options": {
"jestConfig": "part-4-problem-solving/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
}
}
}

View file

@ -0,0 +1,21 @@
import { AppElement } from './app.element';
describe('AppElement', () => {
let app: AppElement;
beforeEach(() => {
app = new AppElement();
});
it('should create successfully', () => {
expect(app).toBeTruthy();
});
it('should have a greeting', () => {
app.connectedCallback();
expect(app.querySelector('h1').innerHTML).toContain(
'Welcome part-4-problem-solving'
);
});
});

View file

@ -0,0 +1,34 @@
import "./app.element.css";
import { longestPalindrome } from "./palindrome.util";
export class AppElement extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<div class="bg-white px-6 py-32 lg:px-8">
<div class="mx-auto max-w-3xl text-base leading-7 text-gray-700">
<p class="text-base font-semibold leading-7 text-indigo-600">Longest Palindromic Substring</p>
<h1 class="mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">Algorithm logic:</h1>
<p class="mt-6 text-xl leading-8">
The algorithm works by first creating a table to store the longest palindromic substring for each substring of the input string. The table is initialized by setting the diagonal elements to true, since any substring of length one is a palindrome.
</p>
<div class="mt-10 max-w-2xl">
<p>
Then, the algorithm iterates over the table, calculating the longest palindromic substring for each substring. For each substring, the algorithm checks if the first and last characters are the same. If they are, and the substring is of length two, then the substring is a palindrome. If they are, and the substring is longer than two characters, then the substring is a palindrome if and only if the substring without the first and last characters is a palindrome.
</p>
<p class="py-4">
Finally, the algorithm finds the longest palindromic substring in the table and returns it.
</p>
</div>
<p style="color: red">Check browser console to see results :)</p>
</div>
</div>
`;
// Example usage:
console.log("Longest Palindromic Substring:", longestPalindrome("babad")); // "bab" or "aba"
}
}
customElements.define("app-root", AppElement);

View file

@ -0,0 +1,51 @@
/**
* Finds the longest palindromic substring in a given string.
*
* @param {string} str The string to search for a palindrome in.
* @returns {string} The longest palindromic substring found in the string, or an empty string if no palindrome is found.
*/
export const longestPalindrome = (str: string): string => {
// If the string is empty or less than one character long, return an empty string.
if (str.length < 1) {
return "";
}
// Create a table to store the longest palindromic substring for each substring of the input string.
const table: any[] = new Array(str.length);
for (let i: number = 0; i < str.length; i++) {
table[i] = new Array(str.length);
for (let j = 0; j < str.length; j++) {
table[i][j] = false;
}
}
// Initialize the table.
for (let i: number = 0; i < str.length; i++) {
table[i][i] = true;
}
// Iterate over the table, calculating the longest palindromic substring for each substring.
for (let i: number = 0; i < str.length; i++) {
for (let j: number = i + 1; j < str.length; j++) {
if (str[i] === str[j]) {
if (j - i === 1) {
table[i][j] = true;
} else {
table[i][j] = table[i + 1][j - 1];
}
}
}
}
// Find the longest palindromic substring in the table.
let longestPalindrome = "";
for (let i: number = 0; i < str.length; i++) {
for (let j: number = i; j < str.length; j++) {
if (table[i][j] && (j - i + 1) > longestPalindrome.length) {
longestPalindrome = str.substring(i, j + 1);
}
}
}
return longestPalindrome;
};

View file

@ -0,0 +1,3 @@
export const environment = {
production: true
};

View file

@ -0,0 +1,6 @@
// This file can be replaced during build by using the `fileReplacements` array.
// When building for production, this file is replaced with `environment.prod.ts`.
export const environment = {
production: false
};

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en" class="h-full bg-gray-100">
<head>
<meta charset="utf-8" />
<title>Part4ProblemSolving</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="https://www.payspace.com/wp-content/uploads/2018/03/PS-FAVICON-NEW-2017.png" sizes="32x32" />
<link rel="icon" href="https://www.payspace.com/wp-content/uploads/2018/03/PS-FAVICON-NEW-2017.png" sizes="192x192" />
<link rel="apple-touch-icon" href="https://www.payspace.com/wp-content/uploads/2018/03/PS-FAVICON-NEW-2017.png" />
<meta name="msapplication-TileImage"
content="https://www.payspace.com/wp-content/uploads/2018/03/PS-FAVICON-NEW-2017.png" />
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="h-full">
<app-root></app-root>
</body>
</html>

View file

@ -0,0 +1 @@
import './app/app.element';

View file

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

View file

View file

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../dist/out-tsc",
"types": ["node"]
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}

View file

@ -0,0 +1,13 @@
{
"extends": "../tsconfig.base.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}

View file

@ -0,0 +1,15 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"files": ["src/test-setup.ts"],
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}

View file

@ -0,0 +1,9 @@
const { composePlugins, withNx } = require('@nx/webpack');
// Nx plugins for webpack.
module.exports = composePlugins(withNx(), (config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
return config;
});