From 3f7e7eda6777cf79f9e31433a4a9bf73dd950e16 Mon Sep 17 00:00:00 2001 From: Devoalda Date: Fri, 26 Jan 2024 17:55:02 +0800 Subject: [PATCH] Initial Commit --- .gitignore | 595 ++++++++++++++++++++++ Coursework/ArrayManipulation.py | 77 +++ Coursework/TwoStackQueue.py | 59 +++ Coursework/sum.py | 40 ++ Coursework_2/AVL.py | 251 +++++++++ Coursework_2/LCA.py | 80 +++ Coursework_2/checkBinaryTree.py | 20 + Lab 1/Question1.py | 20 + Lab 1/Question2.py | 15 + Lab 1/Question3.py | 23 + Lab 1/Question5.md | 17 + Lab 1/Question6.py | 33 ++ Lab 1/Qustion4.py | 24 + Lab 1/Tutorial 1 - Python Programming.pdf | Bin 0 -> 101154 bytes Lab 1/q4_2.py | 26 + Lab 2/q1.py | 51 ++ Lab 2/q3.py | 141 +++++ Lab 2/q4.py | 167 ++++++ Lab 2/q5.py | 47 ++ Lab 4/q2.py | 39 ++ Lab 4/q3.py | 35 ++ Lab 4/q4.py | 30 ++ Lab 5/q1.py | 49 ++ Lab 5/q2.py | 86 ++++ Lab 6/insertionSort.py | 44 ++ Lab 6/selectionSort.py | 41 ++ Lab 7/Q2.py | 33 ++ Lab 8/BST.py | 48 ++ Practices/BSTOrder.py | 112 ++++ Practices/Searching/BinarySearch.py | 45 ++ Practices/Sorting/InsertionSort.py | 27 + Practices/Sorting/MergeSort.py | 41 ++ Practices/Sorting/__init__.py | 0 Practices/Sorting/bubbleSort.py | 11 + Practices/Sorting/quickSort.py | 24 + Practices/Sorting/quickSortDesc.py | 27 + Practices/Sorting/selectionSort.py | 29 ++ Practices/__init__.py | 0 Practices/checkEven.py | 12 + Practices/doublyLinkedList.py | 77 +++ Practices/queue.py | 46 ++ Practices/reverse.py | 13 + Practices/singly_linked_list.py | 131 +++++ Practices/stack.py | 66 +++ Practices/supDigit.py | 40 ++ Practices/test1.py | 57 +++ main.py | 16 + 47 files changed, 2865 insertions(+) create mode 100755 .gitignore create mode 100755 Coursework/ArrayManipulation.py create mode 100755 Coursework/TwoStackQueue.py create mode 100755 Coursework/sum.py create mode 100755 Coursework_2/AVL.py create mode 100755 Coursework_2/LCA.py create mode 100755 Coursework_2/checkBinaryTree.py create mode 100755 Lab 1/Question1.py create mode 100755 Lab 1/Question2.py create mode 100755 Lab 1/Question3.py create mode 100755 Lab 1/Question5.md create mode 100755 Lab 1/Question6.py create mode 100755 Lab 1/Qustion4.py create mode 100755 Lab 1/Tutorial 1 - Python Programming.pdf create mode 100755 Lab 1/q4_2.py create mode 100755 Lab 2/q1.py create mode 100755 Lab 2/q3.py create mode 100755 Lab 2/q4.py create mode 100755 Lab 2/q5.py create mode 100755 Lab 4/q2.py create mode 100755 Lab 4/q3.py create mode 100755 Lab 4/q4.py create mode 100755 Lab 5/q1.py create mode 100755 Lab 5/q2.py create mode 100755 Lab 6/insertionSort.py create mode 100755 Lab 6/selectionSort.py create mode 100755 Lab 7/Q2.py create mode 100755 Lab 8/BST.py create mode 100755 Practices/BSTOrder.py create mode 100755 Practices/Searching/BinarySearch.py create mode 100755 Practices/Sorting/InsertionSort.py create mode 100755 Practices/Sorting/MergeSort.py create mode 100755 Practices/Sorting/__init__.py create mode 100755 Practices/Sorting/bubbleSort.py create mode 100755 Practices/Sorting/quickSort.py create mode 100755 Practices/Sorting/quickSortDesc.py create mode 100755 Practices/Sorting/selectionSort.py create mode 100755 Practices/__init__.py create mode 100755 Practices/checkEven.py create mode 100755 Practices/doublyLinkedList.py create mode 100755 Practices/queue.py create mode 100755 Practices/reverse.py create mode 100755 Practices/singly_linked_list.py create mode 100755 Practices/stack.py create mode 100755 Practices/supDigit.py create mode 100755 Practices/test1.py create mode 100755 main.py diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..39a4708 --- /dev/null +++ b/.gitignore @@ -0,0 +1,595 @@ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### VirtualEnv template +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +.Python +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +.venv +pip-selfcheck.json + +### TeX template +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 +.*.lb + +## Intermediate documents: +*.dvi +*.xdv +*-converted-to.* +# these rules might exclude image files for figures etc. +# *.ps +# *.eps +# *.pdf + +## Generated if empty string is given at "Please type another file name for output:" +.pdf + +## Bibliography auxiliary files (bibtex/biblatex/biber): +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.run.xml + +## Build tool auxiliary files: +*.fdb_latexmk +*.synctex +*.synctex(busy) +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync + +## Build tool directories for auxiliary files +# latexrun +latex.out/ + +## Auxiliary and intermediate files from other packages: +# algorithms +*.alg +*.loa + +# achemso +acs-*.bib + +# amsthm +*.thm + +# beamer +*.nav +*.pre +*.snm +*.vrb + +# changes +*.soc + +# comment +*.cut + +# cprotect +*.cpt + +# elsarticle (documentclass of Elsevier journals) +*.spl + +# endnotes +*.ent + +# fixme +*.lox + +# feynmf/feynmp +*.mf +*.mp +*.t[1-9] +*.t[1-9][0-9] +*.tfm + +#(r)(e)ledmac/(r)(e)ledpar +*.end +*.?end +*.[1-9] +*.[1-9][0-9] +*.[1-9][0-9][0-9] +*.[1-9]R +*.[1-9][0-9]R +*.[1-9][0-9][0-9]R +*.eledsec[1-9] +*.eledsec[1-9]R +*.eledsec[1-9][0-9] +*.eledsec[1-9][0-9]R +*.eledsec[1-9][0-9][0-9] +*.eledsec[1-9][0-9][0-9]R + +# glossaries +*.acn +*.acr +*.glg +*.glo +*.gls +*.glsdefs +*.lzo +*.lzs +*.slg +*.slo +*.sls + +# uncomment this for glossaries-extra (will ignore makeindex's style files!) +# *.ist + +# gnuplot +*.gnuplot +*.table + +# gnuplottex +*-gnuplottex-* + +# gregoriotex +*.gaux +*.glog +*.gtex + +# htlatex +*.4ct +*.4tc +*.idv +*.lg +*.trc +*.xref + +# hyperref +*.brf + +# knitr +*-concordance.tex +# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files +# *.tikz +*-tikzDictionary + +# listings +*.lol + +# luatexja-ruby +*.ltjruby + +# makeidx +*.idx +*.ilg +*.ind + +# minitoc +*.maf +*.mlf +*.mlt +*.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* + +# minted +_minted* +*.pyg + +# morewrites +*.mw + +# newpax +*.newpax + +# nomencl +*.nlg +*.nlo +*.nls + +# pax +*.pax + +# pdfpcnotes +*.pdfpc + +# sagetex +*.sagetex.sage +*.sagetex.py +*.sagetex.scmd + +# scrwfile +*.wrt + +# svg +svg-inkscape/ + +# sympy +*.sout +*.sympy +sympy-plots-for-*.tex/ + +# pdfcomment +*.upa +*.upb + +# pythontex +*.pytxcode +pythontex-files-*/ + +# tcolorbox +*.listing + +# thmtools +*.loe + +# TikZ & PGF +*.dpth +*.md5 +*.auxlock + +# titletoc +*.ptc + +# todonotes +*.tdo + +# vhistory +*.hst +*.ver + +# easy-todo +*.lod + +# xcolor +*.xcp + +# xmpincl +*.xmpi + +# xindy +*.xdy + +# xypic precompiled matrices and outlines +*.xyc +*.xyd + +# endfloat +*.ttt +*.fff + +# Latexian +TSWLatexianTemp* + +## Editors: +# WinEdt +*.bak +*.sav + +# Texpad +.texpadtmp + +# LyX +*.lyx~ + +# Kile +*.backup + +# gummi +.*.swp + +# KBibTeX +*~[0-9]* + +# TeXnicCenter +*.tps + +# auto folder when using emacs and auctex +./auto/* +*.el + +# expex forward references with \gathertags +*-tags.tex + +# standalone packages +*.sta + +# Makeindex log files +*.lpz + +# xwatermark package +*.xwm + +# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib +# option is specified. Footnotes are the stored in a file with suffix Notes.bib. +# Uncomment the next line to have this generated file ignored. +#*Notes.bib + +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen +### Windows template +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Syncthing template +# Syncthing caches +.stversions + +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/Coursework/ArrayManipulation.py b/Coursework/ArrayManipulation.py new file mode 100755 index 0000000..11a6d74 --- /dev/null +++ b/Coursework/ArrayManipulation.py @@ -0,0 +1,77 @@ +#!/bin/python3 + +import math +import os +import random +import re +import sys + +# +# Complete the 'arrayManipulation' function below. +# +# The function is expected to return a LONG_INTEGER. +# The function accepts following parameters: +# 1. INTEGER n +# 2. 2D_INTEGER_ARRAY queries +# +#Starting with a 1-indexed array of zeros and a list of operations, for each operation add a value to each the array element between two given indices, inclusive. Once all operations have been performed, return the maximum value in the array. + +def arrayManipulation(n, queries): + # Write your code here + # create an array of zeros + arr = [0] * (n + 1) + sum = 0 + max = 0 + # iterate through queries + for i in range(len(queries)): + # get the start and end indices + start = queries[i][0] + end = queries[i][1] + # get the value to add + value = queries[i][2] + # add the value to the start index + arr[start] += value + # subtract the value from the end index + 1 + if end + 1 <= n: + arr[end + 1] -= value + # iterate through the array + for i in range(1, len(arr)): + # add the value at the current index to the sum + sum += arr[i] + # if the sum is greater than the max, set the max to the sum + if sum > max: + max = sum + # return the max + return max + + +if __name__ == '__main__': + fptr = open(os.environ['OUTPUT_PATH'], 'w') + + first_multiple_input = input().rstrip().split() + + n = int(first_multiple_input[0]) + + m = int(first_multiple_input[1]) + + queries = [] + + for _ in range(m): + queries.append(list(map(int, input().rstrip().split()))) + + result = arrayManipulation(n, queries) + + fptr.write(str(result) + '\n') + + fptr.close() + + +# Sample Input +# +# 5 3 +# 1 2 100 +# 2 5 100 +# 3 4 100 +# Sample Output +# +# 200 \ No newline at end of file diff --git a/Coursework/TwoStackQueue.py b/Coursework/TwoStackQueue.py new file mode 100755 index 0000000..efb9fbf --- /dev/null +++ b/Coursework/TwoStackQueue.py @@ -0,0 +1,59 @@ +#!/bin/python3 + +class Stack: + def __init__(self): + self.top = -1 + self.data = [] + + def push(self, value): + self.data.append(0) + self.top += 1 + self.data[self.top] = value + + def pop(self): + value = self.data[self.top] + del self.data[self.top] + self.top -= 1 + return value + + def isEmpty(self): + return self.top == -1 + + +def enqueue(stack1, value): + stack1.push(value) + + +def dequeue(stack1, stack2): + if stack2.isEmpty(): + while not stack1.isEmpty(): + stack2.push(stack1.pop()) + return stack2.pop() + + +def peek(stack1, stack2): + if stack2.isEmpty(): + while not stack1.isEmpty(): + stack2.push(stack1.pop()) + return stack2.data[stack2.top] + + +if __name__ == '__main__': + stack1 = Stack() + stack2 = Stack() + + # Get number of queries + q = int(input()) + queries = [] + for i in range(q): + queries.append(list(map(int, input().rstrip().split()))) + query = queries[i][0] + # if the query is 1, enqueue + if query == 1: + enqueue(stack1, queries[i][1]) + # if the query is 2, dequeue + elif query == 2: + dequeue(stack1, stack2) + # if the query is 3, print the top of the queue + elif query == 3: + print(peek(stack1, stack2)) diff --git a/Coursework/sum.py b/Coursework/sum.py new file mode 100755 index 0000000..c7d2619 --- /dev/null +++ b/Coursework/sum.py @@ -0,0 +1,40 @@ +#!/bin/python3 + +import math +import os +import random +import re +import sys + +# +# Complete the 'superDigit' function below. +# +# The function is expected to return an INTEGER. +# The function accepts following parameters: +# 1. STRING n +# 2. INTEGER k +# + +def superDigit(n, k): + # Write your code here + if len(n) == 1: + return int(n) + else: + n = str(sum([int(i) for i in n]) * k) + return superDigit(n, 1) + + +if __name__ == '__main__': + fptr = open(os.environ['OUTPUT_PATH'], 'w') + + first_multiple_input = input().rstrip().split() + + n = first_multiple_input[0] + + k = int(first_multiple_input[1]) + + result = superDigit(n, k) + + fptr.write(str(result) + '\n') + + fptr.close() diff --git a/Coursework_2/AVL.py b/Coursework_2/AVL.py new file mode 100755 index 0000000..48e043b --- /dev/null +++ b/Coursework_2/AVL.py @@ -0,0 +1,251 @@ +import os +import sys + + +class BST: + root = None + + def put(self, key, val): + self.root = self.put2(self.root, key, val) + + def put2(self, node, key, val): + if node is None: + # key is not in tree, create node and return node to parent + return Node(key, val) + if key < node.key: + # key is in left subtree + node.left = self.put2(node.left, key, val) + elif key > node.key: + # key is in right subtree + node.right = self.put2(node.right, key, val) + else: + node.val = val + return node + + def createTree(self, a): + + for x in a: + n = x.split(":") + self.put(n[0], n[1]) + + # Create a AVL Tree, you are allowed to create other helper functions + def createBalancedTree(self, a): + for x in a: + n = x.split(":") + self.insertAVL(n[0], n[1]) + + # preOrder Traversal, this should be a recursive function + def preOrder(self, node): + if node is None: + return [] + return [node.key + ":" + node.val] + self.preOrder(node.left) + self.preOrder(node.right) + + # inOrder Traversal, this should be a recursive function + def inOrder(self, node): + if node is None: + return [] + return self.inOrder(node.left) + [node.key + ":" + node.val] + self.inOrder(node.right) + + # postOrder Traversal, this should be a recursive function + def postOrder(self, node): + if node is None: + return [] + return self.postOrder(node.left) + self.postOrder(node.right) + [node.key + ":" + node.val] + + # given a key, obtain its value + def get(self, key): + return self.get2(self.root, key) + + # given a key, find the node and obtain the depth, you are allowed to create other helper functions + def depth(self, key): + return self.depth2(self.root, key, 0) + + # given a key, find the node and obtain the height, you are allowed to create other helper functions + def height(self, key): + return self.height2(self.root, key) + + # given a key, find the node and obtain the size, you are allowed to create other helper functions + def size(self, key): + return self.size2(self.root, key) + + # given a key, delete the node, you are allowed to create other helper functions + def delete(self, key): + self.root = self.delete2(self.root, key) + return True + + def get2(self, root, key): + if root is None: + return None + if key < root.key: + return self.get2(root.left, key) + elif key > root.key: + return self.get2(root.right, key) + else: + return root.val + + def size2(self, root, key): + if root is None: + return 0 + if key < root.key: + return self.size2(root.left, key) + 1 + elif key > root.key: + return self.size2(root.right, key) + 1 + else: + return self.size2(root.left, key) + self.size2(root.right, key) + + def depth2(self, root, key, param): + if root is None: + return 0 + if key < root.key: + return self.depth2(root.left, key, param + 1) + elif key > root.key: + return self.depth2(root.right, key, param + 1) + else: + return param + + def height2(self, current_node, key): + if current_node is None: + return -1 + else: + return max(self.height2(current_node.left, key), self.height2(current_node.right, key)) + 1 + + def delete2(self, root, key): + if root is None: + return None + # Search for key to delete + if key < root.key: + root.left = self.delete2(root.left, key) + elif key > root.key: + root.right = self.delete2(root.right, key) + else: + # Found key + if root.right is None: + return root.left + if root.left is None: + return root.right + # Node has two children + temp = root + root = self.min(temp.right) + root.right = self.deleteMin(temp.right) + root.left = temp.left + return root + + def deleteMin(self, node): + if node.left is None: + return node.right + node.left = self.deleteMin(node.left) + return node + + def min(self, right): + if right.left is None: + return right + return self.min(right.left) + + def getBalance(self, root): + if not root: + return 0 + return self.getAVLHeight(root.left) - self.getAVLHeight(root.right) + + def leftRotate(self, z): + y = z.right + T2 = y.left + y.left = z + z.right = T2 + return y + + def rightRotate(self, z): + y = z.left + T3 = y.right + y.right = z + z.left = T3 + return y + + def getAVLHeight(self, root): + if not root: + return -1 + return 1 + max(self.getAVLHeight(root.left), self.getAVLHeight(root.right)) + + def insertAVL(self, key, val): + self.root = self.insertAVL2(self.root, key, val) + + def insertAVL2(self, root, key, val): + if not root: + return Node(key, val) + elif key < root.key: + root.left = self.insertAVL2(root.left, key, val) + else: + root.right = self.insertAVL2(root.right, key, val) + balance = self.getBalance(root) + if balance > 1 and key < root.left.key: + return self.rightRotate(root) + if balance < -1 and key > root.right.key: + return self.leftRotate(root) + if balance > 1 and key > root.left.key: + root.left = self.leftRotate(root.left) + return self.rightRotate(root) + if balance < -1 and key < root.right.key: + root.right = self.rightRotate(root.right) + return self.leftRotate(root) + return root + +class Node: + left = None + right = None + key = 0 + val = 0 + + def __init__(self, key, val): + self.key = key + self.val = val + + +array = input("Enter a list of key:value pairs separated by commas:\n") +array = [str(x) for x in array.split(",")] + +bst = BST() +bst.createTree(array) + +###testcase 0 (get()) +for i in range(2): + key1 = input("Input key for get() method:\n") + if key1 != '-': + print("The value of", key1, "is", bst.get(key1)) + +###testcase 1 (size(),depth(),height()) +key1 = input("Input key for size() method:\n") +if key1 != '-': + print("The size of", key1, "is", bst.size(key1)) + +key1 = input("Input key for depth() method:\n") +if key1 != '-': + print("The depth of", key1, "is", bst.depth(key1)) + +key1 = input("Input key for height() method:\n") +if key1 != '-': + print("The height of", key1, "is", bst.height(key1)) + +print() + +###testcase 2 (preOrder(), inOrder(), postOrder()) +print("The preOrder traversal is", bst.preOrder(bst.root)) +print("The inOrder traversal is", bst.inOrder(bst.root)) +print("The postOrder traversal is", bst.postOrder(bst.root)) +print() + +###testcase 3 delete() +for i in range(2): + key1 = input("Input key for delete() method:\n") + if key1 != '-': + print("Deleting", key1, "is", bst.delete(key1)) + print("The preOrder traversal is", bst.preOrder(bst.root)) + print("The inOrder traversal is", bst.inOrder(bst.root)) + print("The postOrder traversal is", bst.postOrder(bst.root)) + +###testcase 4 createbalancedTree() +key1 = input("Test balanced Tree? \n") +if key1 == 'Y': + bst = BST() + bst.createBalancedTree(array) + print("The preOrder traversal is", bst.preOrder(bst.root)) + print("The inOrder traversal is", bst.inOrder(bst.root)) + print("The postOrder traversal is", bst.postOrder(bst.root)) diff --git a/Coursework_2/LCA.py b/Coursework_2/LCA.py new file mode 100755 index 0000000..464dbb2 --- /dev/null +++ b/Coursework_2/LCA.py @@ -0,0 +1,80 @@ +class Node: + def __init__(self, info): + self.info = info + self.left = None + self.right = None + self.level = None + + def __str__(self): + return str(self.info) + + +class BinarySearchTree: + def __init__(self): + self.root = None + + def create(self, val): + if self.root == None: + self.root = Node(val) + else: + current = self.root + + while True: + if val < current.info: + if current.left: + current = current.left + else: + current.left = Node(val) + break + elif val > current.info: + if current.right: + current = current.right + else: + current.right = Node(val) + break + else: + break + + +# Enter your code here. Read input from STDIN. Print output to STDOUT +''' +class Node: + def __init__(self,info): + self.info = info + self.left = None + self.right = None + + + // this is a node of the tree , which contains info as data, left , right +''' + + +def lca(root, v1, v2): +# Enter your code here + if root is None: + return None + if root.info == v1 or root.info == v2: + return root + left = lca(root.left, v1, v2) + right = lca(root.right, v1, v2) + if left and right: + return root + if left is None: + return right + else: + return left + + + +tree = BinarySearchTree() +t = int(input()) + +arr = list(map(int, input().split())) + +for i in range(t): + tree.create(arr[i]) + +v = list(map(int, input().split())) + +ans = lca(tree.root, v[0], v[1]) +print(ans.info) diff --git a/Coursework_2/checkBinaryTree.py b/Coursework_2/checkBinaryTree.py new file mode 100755 index 0000000..116f94d --- /dev/null +++ b/Coursework_2/checkBinaryTree.py @@ -0,0 +1,20 @@ +""" Node is defined as +class node: + def __init__(self, data): + self.data = data + self.left = None + self.right = None +""" +def check_binary_search_tree_(root): + # Use the inorder traversal to check if the tree is a binary search tree + sequence = inorder_trav(root) + for i in range(len(sequence) - 1): + if sequence[i] >= sequence[i + 1]: + return False + return True + + +def inorder_trav(root): + if root is None: + return [] + return inorder_trav(root.left) + [root.data] + inorder_trav(root.right) \ No newline at end of file diff --git a/Lab 1/Question1.py b/Lab 1/Question1.py new file mode 100755 index 0000000..5db790a --- /dev/null +++ b/Lab 1/Question1.py @@ -0,0 +1,20 @@ +def largest(arr): + biggest = arr[0] + i = 0 + for index, item in enumerate(arr): + if item > biggest: + biggest = item + i = index + return i + + +def main(): + arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + print("Question 1: Write an algorithm that returns the index of the first occurrence of the largest element in an " + "array") + print("index: " + str(largest(arr))) + print("value: " + str(arr[largest(arr)])) + + +if __name__ == '__main__': + main() diff --git a/Lab 1/Question2.py b/Lab 1/Question2.py new file mode 100755 index 0000000..8d1b3da --- /dev/null +++ b/Lab 1/Question2.py @@ -0,0 +1,15 @@ +def reverse(arr): + arr_tmp = [] + for i in range(len(arr)): + arr_tmp.append(arr[len(arr) - 1 - i]) + return arr_tmp + + +def main(): + arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + print("Question 2: Write an algorithm that reverses the array") + print(reverse(arr)) + + +if __name__ == '__main__': + main() diff --git a/Lab 1/Question3.py b/Lab 1/Question3.py new file mode 100755 index 0000000..6bed3fc --- /dev/null +++ b/Lab 1/Question3.py @@ -0,0 +1,23 @@ +def smallesttwo(arr): + small = arr[0] + small2 = arr[0] + for item in arr: + if item < small: + small = item + for item in arr: + if item < small2 and item != small: + small2 = item + + return small, small2 + +def main(): + print("Question 3: Write an algorithm that output the smallest and the second smallest values in the array s[0]," + "…s[n-1]. Assume that n>1 and the values in the array are distinct.") + arr = [9, 2, 4, 5, 6, 7, 8, 3, 10] + small, small2 = smallesttwo(arr) + print("Smallest: " + str(small)) + print("Second Smallest: " + str(small2)) + + +if __name__ == '__main__': + main() diff --git a/Lab 1/Question5.md b/Lab 1/Question5.md new file mode 100755 index 0000000..09896e9 --- /dev/null +++ b/Lab 1/Question5.md @@ -0,0 +1,17 @@ +# Question 5 +An algorithm for finding the maximum element of an array is in the following +```python +def arrayMax(a,n): + currentMax = a[0] + for i in range(1,n): + if a[i] > currentMax: + currentMax = a[i] + return currentMax +``` + +Determine the number of times that the statement "currentMax = a[i]" will be +executed in the best case and in the worst case. + +The best case is when the array is already sorted in ascending order. In this case, the statement "currentMax = a[i]" will be executed only once, when i = 0. + +The worst case is when the array is sorted in descending order. In this case, the statement "currentMax = a[i]" will be executed n-1 times, when i = 1, 2, ..., n-1. \ No newline at end of file diff --git a/Lab 1/Question6.py b/Lab 1/Question6.py new file mode 100755 index 0000000..caa21c3 --- /dev/null +++ b/Lab 1/Question6.py @@ -0,0 +1,33 @@ +class Student: + def __init__(self, name, student_number, examDict): + self.name = name + self.student_number = student_number + self.examDict = examDict + + def getBestExamScore(self): + return max(self.examDict, key=self.examDict.get) + + def getFaileModules(self): + listOfFailedModules = [] + for key, value in self.examDict.items(): + if value < 40: + listOfFailedModules.append(key) + + print(listOfFailedModules) + # return [key for key, value in self.examDict.items() if value < 40] + + def addScore(self, subjectCode, examScore): + self.examDict[subjectCode] = examScore + + def printScore(self): + print(self.name) + print(self.examDict) + + +if __name__ == '__main__': + examDict = {"ICT1008": 96, "ICT1002": 78, "ICT1005": 30} + student = Student("Cristal", "123456", examDict) + student.addScore("ICT1010", 70) + student.printScore() + print(student.getBestExamScore()) + student.getFaileModules() diff --git a/Lab 1/Qustion4.py b/Lab 1/Qustion4.py new file mode 100755 index 0000000..e1e9213 --- /dev/null +++ b/Lab 1/Qustion4.py @@ -0,0 +1,24 @@ +def main(): + print("Question 4: Given an array s[0],…,s[n-1] such that n > 1 and s[i] ≤ s[i+1] for all i. Write an " + "algorithm that inserts an input value x into the array so that s[i] ≤ s[i+1] for all i.") + + arr = [] + i = int(input("Enter size of array: ")) + + while i > 0: + x = int(input("Enter a number: ")) + if arr: + if x >= arr[len(arr) - 1]: + arr.append(x) + i -= 1 + else: + print("Number must be greater than or equal to the last number in the array") + + else: + arr.append(x) + + print(arr) + + +if __name__ == '__main__': + main() diff --git a/Lab 1/Tutorial 1 - Python Programming.pdf b/Lab 1/Tutorial 1 - Python Programming.pdf new file mode 100755 index 0000000000000000000000000000000000000000..73bb94742c4619887eeb6954e85880b7275669d1 GIT binary patch literal 101154 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

77ALB}ki)Mrn^vZT)6mXOM2w2_=A;90tC} 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 V=C8#M0}_Ei4s>d22}Mct{{=ex`-%Vn literal 0 HcmV?d00001 diff --git a/Lab 1/q4_2.py b/Lab 1/q4_2.py new file mode 100755 index 0000000..5d17e43 --- /dev/null +++ b/Lab 1/q4_2.py @@ -0,0 +1,26 @@ +# question 4 +def orderInsert(a, value): + # remove pass + left = 0 + right = len(a) - 1 + + while left <= right: + mid = (left + right) >> 1 + if a[mid] == value: + a.insert(mid, value) + return + elif a[mid] < value: + left = mid + 1 + else: + right = mid - 1 + + a.insert(left, value) + + +array = input("Enter a list of numbers in increasing order separated by commas:\n") +array = [int(x) for x in array.split(",")] + +number = input("Enter a number to be inserted into the array:\n") + +orderInsert(array, int(number)) +print(array) \ No newline at end of file diff --git a/Lab 2/q1.py b/Lab 2/q1.py new file mode 100755 index 0000000..0c308ba --- /dev/null +++ b/Lab 2/q1.py @@ -0,0 +1,51 @@ +class Stack: + def __init__(self): + self.top = -1 + # this stack is implemented with Python list (array) + self.data = [] + + def push(self, value): + # increment the size of data using append() + self.data.append(0) + self.top += 1 + self.data[self.top] = value + pass + + def pop(self): + value = self.data[self.top] + # delete the top value using del + del self.data[self.top] + self.top -= 1 + return value + + def isEmpty(self): + return self.top == -1 + + def peek(self): + pass + + def printStack(self): + print(self.data) + + def invert(self): + # remove pass and add your code here + + tmpStack = Stack() + while not self.isEmpty(): + tmpStack.push(self.pop()) + self.data = tmpStack.data + self.top = tmpStack.top + + +array = input("Enter a list of numbers separated by commas:\n") +array = [int(x) for x in array.split(",")] + +s = Stack() +for n in array: + s.push(n) + +s.printStack() +s.invert() +s.printStack() +s.invert() +s.printStack() diff --git a/Lab 2/q3.py b/Lab 2/q3.py new file mode 100755 index 0000000..e2a4123 --- /dev/null +++ b/Lab 2/q3.py @@ -0,0 +1,141 @@ +class SinglyListNode: + def __init__(self, data): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__(self): + self.head = None + + # return the value of the node at index + + def search(self, index): + temp = self.head + prev = None + counter = 0 + while temp is not None and counter < index: + prev = temp + temp = temp.next + counter += 1 + + if temp is None: + print('search error: invalid index') + else: + return temp + + def insertAtHead(self, node): + if self.head is None: + self.head = node + else: + node.next = self.head + self.head = node + + def delete(self, value): + prev = None + temp = self.head + + while temp is not None and temp.data != value: + prev = temp + temp = temp.next + + # node to be deleted is head + if temp == self.head: + self.deleteAtHead() + + # Value found + elif temp != None: + prev.next = temp.next + del temp + # Value not found + else: + print('Value ', value, ' cannot be found') + + # delete the node at index + def deleteAt(self, index): + temp = self.head + prev = None + counter = 0 + while temp is not None and counter < index: + prev = temp + temp = temp.next + counter += 1 + + if temp is None: + print('search error: invalid index') + else: + if prev is None: + self.head = temp.next + else: + prev.next = temp.next + del temp + + def deleteAtHead(self): + temp = self.head + self.head = self.head.next + del temp + + def printList(self): + output = "Current list content: [ " + temp = self.head + while temp is not None: + output += str(temp.data) + " " + temp = temp.next + output += "]" + print(output) + + # return the number of elements in the queue + def size(self): + temp = self.head + size = 0 + while temp is not None: + size += 1 + temp = temp.next + return size + + +class Queue: + def __init__(self): + # You must implement this Queue with a SinglyLinkedList + self.q = SinglyLinkedList() + + def enqueue(self, value): + # remove pass and add your code here + self.q.insertAtHead(SinglyListNode(value)) + + def printQueue(self): + self.q.printList() + + def dequeue(self): + self.q.deleteAt(self.q.size() - 1) + + def isEmpty(self): + return self.q.size() == 0 + + def peek(self): + return self.q.search(self.q.size() - 1).data + + +Q = Queue() + +array = input("Enter a list of command separated by commas:\n") +array = [x for x in array.split(",")] + +for cmd in array: + if cmd.startswith("I"): + print("Checking if queue is empty") + print(Q.isEmpty()) + elif cmd.startswith("E"): + c, v = cmd.split() + Q.enqueue(int(v)) + print("After enqueuing", int(v)) + Q.printQueue() + elif cmd.startswith("P"): + print("Peeking at queue") + print(Q.peek()) + elif cmd.startswith("D"): + Q.dequeue() + print("After dequeing") + Q.printQueue() + else: + print("Command not recognized!") \ No newline at end of file diff --git a/Lab 2/q4.py b/Lab 2/q4.py new file mode 100755 index 0000000..cdc7c72 --- /dev/null +++ b/Lab 2/q4.py @@ -0,0 +1,167 @@ +# Enter your code here. Read input from STDIN. Print output to STDOUT +class SinglyListNode: + def __init__(self, data): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__(self): + self.head = None + self.data = [] + + def search(self, value): + temp = self.head + prev = None + counter = 0 + while temp is not None and counter < value: + prev = temp + temp = temp.next + counter += 1 + + if temp is None: + print('Error: invalid index') + else: + return temp + + def insert(self, node, index): + if index == 0: + self.insertAtHead(node) + else: + temp = self.search(index) + if temp is not None: + node.next = temp.next + temp.next = node + + def insertAtHead(self, node): + if self.head is None: + self.head = node + else: + node.next = self.head + self.head = node + + def delete(self, value): + prev = None + temp = self.head + + while temp != None and temp.data != value: + prev = temp + temp = temp.next + + # node to be deleted is head + if temp == self.head: + self.deleteAtHead() + + # Value found + elif temp != None: + prev.next = temp.next + del temp + # Value not found + else: + print('Value ', value, ' cannot be found') + + # delete the node at index + def deleteAt(self, index): + temp = self.head + prev = None + counter = 0 + while temp is not None and counter < index: + prev = temp + temp = temp.next + counter += 1 + + if temp is None: + print('search error: invalid index') + else: + if prev is None: + self.head = temp.next + else: + prev.next = temp.next + del temp + + def deleteAtHead(self): + temp = self.head + self.head = self.head.next + del temp + + def printList(self): + output = "[ " + temp = self.head + while temp is not None: + output += str(temp.data) + " " + temp = temp.next + output += "]" + print(output) + + # return the number of elements in the queue + def size(self): + temp = self.head + size = 0 + while temp is not None: + size += 1 + temp = temp.next + return size + + def reverse(self): + prev = None + current = self.head + while current is not None: + next = current.next + current.next = prev + prev = current + current = next + self.head = prev + + +def mergesort(list1, list2): + merged_list = SinglyLinkedList() + + while list1.head is not None and list2.head is not None: + if int(list1.head.data) < int(list2.head.data): + merged_list.insertAtHead(SinglyListNode(list1.head.data)) + list1.deleteAtHead() + else: + merged_list.insertAtHead(SinglyListNode(list2.head.data)) + list2.deleteAtHead() + while list1.head is not None: + merged_list.insertAtHead(SinglyListNode(list1.head.data)) + list1.deleteAtHead() + + while list2.head is not None: + merged_list.insertAtHead(SinglyListNode(list2.head.data)) + list2.deleteAtHead() + + merged_list.reverse() + print("Content of merged list") + merged_list.printList() + + +def reverse(array): + reversed_array = [] + for i in range(len(array)): + reversed_array.append(array[len(array) - 1 - i]) + return reversed_array + + +array1 = input("Enter a list of numbers in descending order for list 1 separated by commas:") +array1 = [x for x in array1.split(",")] +array1 = reverse(array1) +list1 = SinglyLinkedList() +list2 = SinglyLinkedList() + +for n in array1: + list1.insertAtHead(SinglyListNode(n)) + +array2 = input("\nEnter a list of numbers in descending order for list 2 separated by commas:") +array2 = [x for x in array2.split(",")] +array2 = reverse(array2) + +for n in array2: + list2.insertAtHead(SinglyListNode(n)) + +print("\nContent of list 1") +list1.printList() + +print("Content of list 2") +list2.printList() +mergesort(list1, list2) diff --git a/Lab 2/q5.py b/Lab 2/q5.py new file mode 100755 index 0000000..9f41d64 --- /dev/null +++ b/Lab 2/q5.py @@ -0,0 +1,47 @@ +class Stack: + def __init__(self): + self.top = -1 + # this stack is implemented with Python list (array) + self.data = [] + + def push(self, value): + # increment the size of data using append() + self.data.append(0) + self.top += 1 + self.data[self.top] = value + + def pop(self): + value = self.data[self.top] + # delete the top value using del + del self.data[self.top] + self.top -= 1 + return value + + def isEmpty(self): + return (self.top == -1) + + def printStack(self): + print(self.data) + + +def checkBrace(s): + stack = Stack() + for i in s: + if i == "(" or i== "[" or i == "{": + stack.push(i) + elif i == ")" or i == "]" or i == "}": + if stack.isEmpty(): + return False + else: + stack.pop() + if stack.isEmpty(): + return True + else: + return False + +array = input("Enter a string to check:\n") + +if checkBrace(array): + print("The string", array, "is balanced") +else: + print("The string", array, "is not balanced") \ No newline at end of file diff --git a/Lab 4/q2.py b/Lab 4/q2.py new file mode 100755 index 0000000..f3b6c88 --- /dev/null +++ b/Lab 4/q2.py @@ -0,0 +1,39 @@ +# recursive function to add first n term of the series 1+1/2 - 1/3+1/4-1/5 + +def sum(n): + if n == 1: # base case + return 1 + else: + if n % 2 == 0: # if n is even + return 1 / n + sum(n - 1) # add 1/n + else: + return -1 / n + sum(n - 1) # subtract 1/n + + +# Test cases +# assert sum(1) == 1, "sum(1) should be 1, but returned " + str(sum(1)) +# assert sum(2) == 1.5, "sum(2) should be 1.5, but returned " + str(sum(2)) +# assert sum(3) == (1 + 1/2 - 1/3), "sum(3) should be 1.1666666666666667, but returned " + str(sum(3)) +# assert sum(4) == (1 + 1/2 - 1/3 + 1/4), "sum(4) should be 1.4166666666666667, but returned " + str(sum(4)) +# assert sum(5) == (1 + 1/2 - 1/3 + 1/4 - 1/5), "sum(5) should be 1.2833333333333332, but returned " + str(sum(5)) +# +# print("All tests passed!") + + +def sumNTerm(n): + # remove pass and insert your code here + # for the purpose of this exercise you + # should be calling sumNTerm() with a smaller + # value of n inside this function + if n == 1.0: + return 1.0 + else: + if n % 2 == 0: + return 1 / n + sumNTerm(n - 1) + else: + return -1 / n + sumNTerm(n - 1) + + +n = int(input("Enter the number of terms to sum:\n")) + +print("Sum of first", n, "terms =", sumNTerm(n)) \ No newline at end of file diff --git a/Lab 4/q3.py b/Lab 4/q3.py new file mode 100755 index 0000000..a111515 --- /dev/null +++ b/Lab 4/q3.py @@ -0,0 +1,35 @@ +# def GCD(n, m): +# if m <= n and n % m == 0: # base case +# return m +# elif n < m: # if n < m, swap n and m +# return GCD(m, n) +# else: +# return GCD(m, n % m) # recursive call to find gcd with n % m + + + + +def GCD(n,m): + # remove pass and insert your code here + # for hte purpose of this exercise you should + # call the function GCD() with a smaller value of + # the parameters appropriately. + if m <= n and n % m == 0: + return m + elif n < m: + return GCD(m, n) + else: + return GCD(m, n % m) + +n1 = int(input("Enter the first number:\n")) +n2 = int(input("Enter the second number:\n")) + +print("The GCD of", n1, "and", n2, "is", GCD(n1,n2)) + +# Test cases +assert GCD(12, 8) == 4, "GCD(12, 8) should be 4, but returned " + str(GCD(12, 8)) +assert GCD(8, 12) == 4, "GCD(8, 12) should be 4, but returned " + str(GCD(8, 12)) +assert GCD(12, 9) == 3, "GCD(12, 9) should be 3, but returned " + str(GCD(12, 9)) +assert GCD(9, 12) == 3, "GCD(9, 12) should be 3, but returned " + str(GCD(9, 12)) + +print("All tests passed!") diff --git a/Lab 4/q4.py b/Lab 4/q4.py new file mode 100755 index 0000000..b1b576d --- /dev/null +++ b/Lab 4/q4.py @@ -0,0 +1,30 @@ +def hanoi(n, source, target, spare): + if n == 1: + print("Move disk", n, "from", source, "to", target) + else: + hanoi(n - 1, source, spare, target) + print("Move disk", n, "from", source, "to", target) + hanoi(n - 1, spare, target, source) + + +hanoi(3, "A", "B", "C") + + +def moveTower(height, fromPole, toPole, withPole): + # add code here + # call moveDisk in your function call. + if height == 1: + moveDisk(fromPole, toPole) + + else: + moveTower(height - 1, fromPole, withPole, toPole) + moveDisk(fromPole, toPole) + moveTower(height - 1, withPole, toPole, fromPole) + + +def moveDisk(fp, tp): + print("moving disk from", fp, "to", tp) + + +disks = int(input("Enter the number of disks:\n")) +moveTower(disks, "A", "B", "C") \ No newline at end of file diff --git a/Lab 5/q1.py b/Lab 5/q1.py new file mode 100755 index 0000000..8c4750b --- /dev/null +++ b/Lab 5/q1.py @@ -0,0 +1,49 @@ +#! /bin/python + + +# this function checks if a queen can be placed in location (col,row) +def isValid(col, row, chessBoard): + # check if there is a queen in the same row + for i in range(col): + if chessBoard[row][i] == 1: + return False + + # Check if there is a quen in the same column + for i in range(row): + if chessBoard[i][col] == 1: + return False + + # check if there is a queen in the same diagonal + for i in range(8): + for j in range(8): + if (i + j == col + row) or (i - j == col - row): + if chessBoard[j][i] == 1: + return False + return True + + +# initialize chessboard +N = 8 +chessBoard = [] +for i in range(N): + chessBoard.append([]) + for j in range(N): + chessBoard[i].append(0) + +# place a queen in the upper left corner of the board +chessBoard[1][1] = 1 +chessBoard[0][4] = 1 +chessBoard[2][6] = 1 + +columnIndex = int(input("Enter a column index:\n")) +rowIndex = int(input("Enter a row index:\n")) + + +print( + "Placing a queen at column", + columnIndex, + "row", + rowIndex, + ":", + isValid(columnIndex, rowIndex, chessBoard), +) diff --git a/Lab 5/q2.py b/Lab 5/q2.py new file mode 100755 index 0000000..74444af --- /dev/null +++ b/Lab 5/q2.py @@ -0,0 +1,86 @@ +#! /bin/python + +map = [] +countryColor = [] +colorCode = ["Red", "Green", "Blue", "Yellow"] + + +# This function initailize the 2-dimensional map array +def createMap(): + global map + mapString = ( + "0,1,1,1,0,0,0\n" + "1,0,0,1,1,1,0\n" + "1,0,0,1,0,0,1\n" + "1,1,1,0,1,0,1\n" + "0,1,0,1,0,1,1\n" + "0,1,0,0,1,0,0\n" + "0,0,1,1,1,0,0" + ) + + for r in mapString.split("\n"): + map.append([int(x) for x in r.split(",")]) + + +# This function initialize the color of each country to 0 = no color +def initializeColor(): + global map + N = len(map) + for i in range(N): + countryColor.append(0) + + +# print the solution in the format required +def printSolution(): + global colorCode + + output = "Country\n" + for i in range(len(countryColor)): + output += str(i) + "\t" + output += "\n" + for i in range(len(countryColor)): + output += colorCode[countryColor[i] - 1] + "\t" + output += "\n" + print(output) + + # This function tries to recursively color a country + # Here the parameter country is the index to the list of country from 0...N-1 + # The skeleton of the program has been provided to you + # Remove the passes and fill in the missing codes for this function + global countryColor + + +def color(country): + global map + N = len(map) + + # if country = number of countries to color + # print solution and exit + if country == N: + printSolution() + return + + availableColor = set([1, 2, 3, 4]) + # remove the color of any neighbour of country i from the set availableColor + for i in range(N): + if map[country][i] == 1: + if countryColor[i] in availableColor: + availableColor.remove(countryColor[i]) + + # for each remaining color in the set availableColor + # color country i with the color and then recursively color the next country + for colors in availableColor: + countryColor[country] = colors + color(country + 1) + countryColor[country] = 0 + + # reset the color of this country to none before backtracking + countryColor[country] = 0 + + +# read the map array +createMap() +# set all countries to no color +initializeColor() +# first try to color country 0 +color(0) diff --git a/Lab 6/insertionSort.py b/Lab 6/insertionSort.py new file mode 100755 index 0000000..d4998d0 --- /dev/null +++ b/Lab 6/insertionSort.py @@ -0,0 +1,44 @@ +count={} + +# swap elements at index i and j or array a +def swap(a,i,j): + global count + a[i],a[j]=a[j],a[i] + count[a[i]]=count[a[i]]+1 + count[a[j]]=count[a[j]]+1 + +# remove pass and implement insertion sort +# that sorts an input array a using the swap +# function defined above to swap two elements +# of an array. The swap function will +# automatically keep track of the number of +# swap for each item +def insertionSort(a): + for i in range(1, len(a)): + + currentVal = a[i] + position = i + + while position > 0 and a[position-1] > currentVal: + swap(a,position,position-1) + position = position-1 + + print(a) + a[position] = currentVal + + +# get user input +array = input("Enter a list of string to sort separated by commas:\n") +array = [str(x) for x in array.split(",")] + +# set up the dictionary to track counts +for x in array: + count[x]=0 + +print(array) +insertionSort(array) +print("Number of swap for each item:",count) +total = 0 +for i in count.keys(): + total = total+count[i] +print("Average number of swap for each item:", round((total*1.0)/len(count.keys()),1)) diff --git a/Lab 6/selectionSort.py b/Lab 6/selectionSort.py new file mode 100755 index 0000000..e4ee27a --- /dev/null +++ b/Lab 6/selectionSort.py @@ -0,0 +1,41 @@ +count = {} + + +# swap elements at index i and j or array a +def swap(a, i, j): + global count + a[i], a[j] = a[j], a[i] + + count[a[i]] = count[a[i]] + 1 + count[a[j]] = count[a[j]] + 1 + + +# remove pass and implement selection sort +# use the swap function defined above to +# swap two elements of an array. The swap +# function will automatically keep track of +# the number of swap for each item +def selectionSort(a): + for j in range(len(a)): + imin = j + for i in range(j+1, len(a)): + if a[i] < a[imin]: + imin = i + if imin != j: + swap(a, j, imin) + + +# get user input +array = input("Enter a list of string to sort separated by commas:\n") +array = [str(x) for x in array.split(",")] + +# set up the dictionary to track counts +for x in array: + count[x] = 0 + +selectionSort(array) +print("Number of swap for each item:", count) +total = 0 +for i in count.keys(): + total = total + count[i] +print("Average number of swap for each item:", (total * 1.0) / len(count.keys())) diff --git a/Lab 7/Q2.py b/Lab 7/Q2.py new file mode 100755 index 0000000..9ec51d8 --- /dev/null +++ b/Lab 7/Q2.py @@ -0,0 +1,33 @@ +import random + +random.seed(1) +dataSize = int(input("Enter the size of the list:\n")) +data = [random.randint(1,dataSize) for i in range(dataSize)] +data.sort() + +# iterative version of binary search +def binarySearchIterative(arr,low,high,value): + while low <= high: + mid = (low + high) >> 1 + if arr[mid] == value: + return mid + elif value < arr[mid]: + high = mid - 1 + else: + low = mid + 1 + return -1 + +#recursive version of binary search +def binarySearchRecursive(arr,low,high,value): + if low > high: + return -1 + mid = (low + high) >> 1 + if arr[mid] == value: + return mid + elif value < arr[mid]: + return binarySearchRecursive(arr,low,mid-1,value) + else: + return binarySearchRecursive(arr,mid+1,high,value) + +print("Iterative: 9132 is at index ", binarySearchIterative(data,0,len(data)-1,9132)) +print("Recursive: 9132 is at index ", binarySearchRecursive(data,0,len(data)-1,9132)) \ No newline at end of file diff --git a/Lab 8/BST.py b/Lab 8/BST.py new file mode 100755 index 0000000..bad6542 --- /dev/null +++ b/Lab 8/BST.py @@ -0,0 +1,48 @@ +compare = 0 + + +class Node: + key = None + value = None + left = None + right = None + + def __init__(self, k, v): + self.key = k + self.value = v + + def insert(self, k, v): + global compare + if self.key == k: + compare = compare + 1 + self.v = v + return + elif k < self.key: + compare = compare + 1 + # remove pass and add your code here + # if left child is none, add the node as the left child + # else call the left child to insert the node + if self.left is None: + self.left = Node(k, v) + else: + self.left.insert(k, v) + + else: + compare = compare + 1 + # remove pass and add your code here + # if right child is none, add the node as the right child + # else call the right child to insert the node + if self.right is None: + self.right = Node(k, v) + else: + self.right.insert(k, v) + + +input = input("Enter a list of letters to insert into the binary tree separated by commas:\n") +input = input.split(",") + +root = Node(input[0], 1) +for i in range(1, len(input)): + root.insert(input[i], 2) + +print("Number of compares to create the BST =", compare) \ No newline at end of file diff --git a/Practices/BSTOrder.py b/Practices/BSTOrder.py new file mode 100755 index 0000000..af052e3 --- /dev/null +++ b/Practices/BSTOrder.py @@ -0,0 +1,112 @@ +# Class describing a node of tree +class Node: + def __init__(self, v): + self.left = None + self.right = None + self.data = v + + def insert(self, v): + if self.data: + if v < self.data: + if self.left is None: + self.left = Node(v) + else: + self.left.insert(v) + elif v > self.data: + if self.right is None: + self.right = Node(v) + else: + self.right.insert(v) + else: + self.data = v + + def printTree(self): + if self.left: + self.left.printTree() + print(chr(self.data), end=" ") + if self.right: + self.right.printTree() + +# Inorder Traversal +def printInorder(root): + if root: + # Traverse left subtree + printInorder(root.left) + + # Visit node + print(chr(root.data), end=" ") + + # Traverse right subtree + printInorder(root.right) + + +# Preorder Traversal +def printPostOrder(node): + if node is None: + return + + # Traverse left subtree + printPostOrder(node.left) + + # Traverse right subtree + printPostOrder(node.right) + + # Visit Node + print(chr(node.data), end=" ") + + +# Preorder Traversal +def printPreOrder(node): + if node is None: + return + # Visit Node + print(chr(node.data), end=" ") + + # Traverse left subtree + printPreOrder(node.left) + + # Traverse right subtree + printPreOrder(node.right) + + +# Driver code +if __name__ == "__main__": + # Build the tree + root = Node(ord('E')) + #root.left = Node(ord('A')) + #root.right = Node(ord('S')) + #root.right.right = Node(ord('Y')) + #root.right.right.left = Node(ord('U')) + #root.right.right.left.left = Node(ord('S')) + #root.right.right.left.left.right = Node(ord('T')) + #root.right.left = Node(ord('Q')) + #root.right.left.left = Node(ord('E')) + #root.right.left.left.right = Node(ord('I')) + #root.right.left.left.right.right = Node(ord('O')) + #root.right.left.left.right.right.left = Node(ord('N')) + + # Insert EASYQUESTION + root.insert(ord('A')) + root.insert(ord('S')) + root.insert(ord('Y')) + root.insert(ord('Q')) + root.insert(ord('U')) + root.insert(ord('E')) + root.insert(ord('I')) + root.insert(ord('O')) + root.insert(ord('N')) + + # Print the tree + print("Tree:") + root.printTree() + + + # Function call + print("Inorder Traversal:", end=" ") + printInorder(root) + print("\nPreorder Traversal:", end=" ") + printPreOrder(root) + print("\nPostorder Traversal:", end=" ") + printPostOrder(root) + +# This code is contributed by ajaymakvana. diff --git a/Practices/Searching/BinarySearch.py b/Practices/Searching/BinarySearch.py new file mode 100755 index 0000000..6d75193 --- /dev/null +++ b/Practices/Searching/BinarySearch.py @@ -0,0 +1,45 @@ +def iterativeBinarySearch(array, value): + left = 0 + right = len(array) + + while left <= right: + mid = (left + right) >> 1 + if array[mid] == value: + return mid + elif array[mid] < value: + left = mid + 1 + else: + right = mid - 1 + return -1 + +def binarySearchWithForLoop(array, value): + left = 0 + right = len(array) + + for i in range(len(array)): + mid = (left + right) >> 1 + if array[mid] == value: + return mid + elif array[mid] < value: + left = mid + 1 + else: + right = mid - 1 + return -1 + +def recursiveBinarySearch(array, value, left, right): + if left > right: + return -1 + + mid = (left + right) >> 1 + if array[mid] == value: + return mid + elif array[mid] < value: + return recursiveBinarySearch(array, value, mid + 1, right) + else: + return recursiveBinarySearch(array, value, left, mid - 1) + + +array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +print(iterativeBinarySearch(array, 10)) +print(recursiveBinarySearch(array, 4, 0, len(array) - 1)) +print(binarySearchWithForLoop(array, 5)) diff --git a/Practices/Sorting/InsertionSort.py b/Practices/Sorting/InsertionSort.py new file mode 100755 index 0000000..89dce1e --- /dev/null +++ b/Practices/Sorting/InsertionSort.py @@ -0,0 +1,27 @@ +def insertionSort(a): + for i in range(1, len(a)): + currentValue = a[i] + position = i + + while position > 0 and a[position - 1] > currentValue: + a[position] = a[position - 1] + position -= 1 + a[position] = currentValue + + return a + + +array = [4, 2, 5, 9, 1, 3, 6, 8, 7] +insertionSort(array) +print(array) + +# Output +# [2, 4, 5, 9, 1, 3, 6, 8, 7] +# [2, 4, 5, 9, 1, 3, 6, 8, 7] +# [2, 4, 5, 9, 1, 3, 6, 8, 7] +# [1, 2, 4, 5, 9, 3, 6, 8, 7] +# [1, 2, 3, 4, 5, 9, 6, 8, 7] +# [1, 2, 3, 4, 5, 6, 9, 8, 7] +# [1, 2, 3, 4, 5, 6, 8, 9, 7] +# [1, 2, 3, 4, 5, 6, 7, 8, 9] + diff --git a/Practices/Sorting/MergeSort.py b/Practices/Sorting/MergeSort.py new file mode 100755 index 0000000..9db0e92 --- /dev/null +++ b/Practices/Sorting/MergeSort.py @@ -0,0 +1,41 @@ +def merge(array1, array2): + array3 = [] + size1 = len(array1) + size2 = len(array2) + + index1 = index2 = 0 + + while index1 < size1 and index2 < size2: + if array1[index1] < array2[index2]: + array3.append(array1[index1]) + index1 += 1 + else: + array3.append(array2[index2]) + index2 += 1 + + for i in range(index1, size1): + array3.append(array1[i]) + + for i in range(index2, size2): + array3.append(array2[i]) + + return array3 + + +def mergeSort(array): + size = len(array) + + if size <= 1: + return array + + mid = size // 2 + + left = mergeSort(array[:mid]) + right = mergeSort(array[mid:]) + + #return merge(left, right) + return merge1(left, right) + + +array = [4, 2, 5, 9, 1, 3, 6, 8, 7] +print(mergeSort(array)) diff --git a/Practices/Sorting/__init__.py b/Practices/Sorting/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Practices/Sorting/bubbleSort.py b/Practices/Sorting/bubbleSort.py new file mode 100755 index 0000000..91919df --- /dev/null +++ b/Practices/Sorting/bubbleSort.py @@ -0,0 +1,11 @@ +def bubbleSort(a): + for i in range(len(a)): + # -i because the last i elements are already sorted + # -1 because we compare j and j+1 + for j in range(len(a) - i - 1): + if a[j] > a[j + 1]: + a[j], a[j + 1] = a[j + 1], a[j] + +array = [3,4,2,9,5,1,6] +bubbleSort(array) +print(array) diff --git a/Practices/Sorting/quickSort.py b/Practices/Sorting/quickSort.py new file mode 100755 index 0000000..5c8d482 --- /dev/null +++ b/Practices/Sorting/quickSort.py @@ -0,0 +1,24 @@ +def partition(a): + pivot = a[0] + pivotIndex = 0 + + for i in range(1, len(a)): + if a[i] < pivot: + a[i], a[pivotIndex + 1] = a[pivotIndex + 1], a[i] + pivotIndex += 1 + + a[0], a[pivotIndex] = a[pivotIndex], a[0] + return pivotIndex + + +def quickSort(a): + if len(a) <= 1: + return a + pivotIndex = partition(a) + left = quickSort(a[:pivotIndex]) + right = quickSort(a[pivotIndex + 1:]) + return left + [a[pivotIndex]] + right + + +array = [4, 2, 5, 9, 1, 3, 6, 8, 7] +print(quickSort(array)) diff --git a/Practices/Sorting/quickSortDesc.py b/Practices/Sorting/quickSortDesc.py new file mode 100755 index 0000000..86511f1 --- /dev/null +++ b/Practices/Sorting/quickSortDesc.py @@ -0,0 +1,27 @@ +def partition(a): + pivot = a[0] + index = 0 + + for i in range(1, len(a)): + if a[i] > pivot: + a[i], a[index + 1] = a[index + 1], a[i] + index += 1 + + a[0], a[index] = a[index], a[0] + return index + + +def quickSort(a): + if len(a) <= 1: + return a + + pivot = partition(a) + + left = quickSort(a[:pivot]) + right = quickSort(a[pivot + 1:]) + + return left + [a[pivot]] + right + + +array = [4, 2, 5, 9, 1, 3, 6, 8, 7] +print(quickSort(array)) diff --git a/Practices/Sorting/selectionSort.py b/Practices/Sorting/selectionSort.py new file mode 100755 index 0000000..b22f2bd --- /dev/null +++ b/Practices/Sorting/selectionSort.py @@ -0,0 +1,29 @@ + +def selSort(a): + for i in range(len(a)): + minIndex = i + for j in range(i + 1, len(a)): + if a[j] < a[minIndex]: + minIndex = j + a[i], a[minIndex] = a[minIndex], a[i] + + return a + +def selSortMax(a): + # For each element in the array starting from the end + for i in range(len(a) - 1, 0, -1): + maxIndex = i + # Search for max element in the array from the beginning + for j in range(i): + if a[j] > a[maxIndex]: + maxIndex = j + # Swap the max element with the last element + a[i], a[maxIndex] = a[maxIndex], a[i] + + return a + +array = [4, 2, 5, 9, 1, 3, 6, 8, 7] +selSort(array) +selSortMax(array) +print(array) + diff --git a/Practices/__init__.py b/Practices/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/Practices/checkEven.py b/Practices/checkEven.py new file mode 100755 index 0000000..066ea60 --- /dev/null +++ b/Practices/checkEven.py @@ -0,0 +1,12 @@ + +# Checking if a value is an even number or not + + +def checkEven(n): + return n & 1 == 0 + + +assert checkEven(2) == True, "checkEven(2) should be True, but returned " + str(checkEven(2)) +assert checkEven(3) == False, "checkEven(3) should be False, but returned " + str(checkEven(3)) + +print("All tests passed!") \ No newline at end of file diff --git a/Practices/doublyLinkedList.py b/Practices/doublyLinkedList.py new file mode 100755 index 0000000..60d4729 --- /dev/null +++ b/Practices/doublyLinkedList.py @@ -0,0 +1,77 @@ +class node: + def __init__(self, data): + self.data = data + self.next = None + self.prev = None + +class doublyLinkedList: + def __init__(self): + self.head = None + self.prev = None + + def insert(self, node): + if self.head is None: + self.head = self.prev = node + else: + self.head.prev = node + node.next = self.head + self.head = node + + + def delete(self, value): + temp = self.head + while temp is not None and temp.data is not value: + temp = temp.next + if temp is None: + print("Error, value not found") + else: + if temp is self.head: + self.head = self.head.next + elif temp is self.tail: + self.tail = self.tail.prev + else: + temp.prev.next = temp.next + temp.next.prev = temp.prev + + def peek(self): + return self.head.data + + def search(self, value): + temp = self.head + counter = 0 + while temp is not None and temp.data is not value: + temp = temp.next + counter += 1 + if temp is None: + print("Error: Unable to search") + else: + return counter + + def printList(self): + temp = self.head + while temp is not None: + if temp.next is not None: + print(temp.data, end=" -> ") + else: + print(temp.data) + temp = temp.next + + +def main(): + dll = doublyLinkedList() + dll.insert(node(5)) + dll.insert(node(6)) + dll.insert(node(7)) + + dll.printList() + # Asserts + assert(dll.peek() == 7), f"Top of Doubly Linked List not 7, got:{dll.peek()}" + assert(dll.search(5) == 2), f"Index of 5 not 2, got:{dll.search(5)}" + assert(dll.search(6) == 1), f"Index of 6 not 1, got:{dll.search(6)}" + assert(dll.search(7) == 0), f"Index of 7 not 0, got:{dll.search(7)}" + + print("All tests passed") + dll.printList() + +if __name__ == "__main__": + main() diff --git a/Practices/queue.py b/Practices/queue.py new file mode 100755 index 0000000..5e257fc --- /dev/null +++ b/Practices/queue.py @@ -0,0 +1,46 @@ +class queue: + def __init__(self): + self.data = [] + self.rear = -1 + + def enqueue(self, value): + self.data.append(value) + self.rear += 1 + + def dequeue(self): + value = self.data[0] # Dequeue from the front + del self.data[0] + self.rear -= 1 + return value + + def peek(self): + if self.rear != -1 and self.data is not None: + return self.data[self.rear] + else: + return "Empty Queue" + + def printQueue(self): + return(self.data) + +def main(): + q1 = queue() + + print(q1.printQueue()) + q1.enqueue(10) + assert(q1.peek() == 10), f"Top of queue not 10, got:{q1.peek()}" + q1.enqueue(11) + assert(q1.peek() == 11), f"Top of queue not 11, got:{q1.peek()}" + + print(q1.printQueue()) + + q1.dequeue() + assert(q1.peek() == 11), f"Top of queue not 11, got:{q1.peek()}" + print(q1.printQueue()) + q1.dequeue() + assert(q1.peek() == "Empty Queue"), f"Top of queue not Empty Queue, got:{q1.peek()}" + + print("No errors found") + print(q1.printQueue()) + +if __name__ == "__main__": + main() diff --git a/Practices/reverse.py b/Practices/reverse.py new file mode 100755 index 0000000..6e4b8fe --- /dev/null +++ b/Practices/reverse.py @@ -0,0 +1,13 @@ +def reverse(): + ch = raw_input() + if ch != 'end': + reverse() + print ch, + +reverse() + +# input: +# a b c d end + +# output: +# end d c b a diff --git a/Practices/singly_linked_list.py b/Practices/singly_linked_list.py new file mode 100755 index 0000000..6686c08 --- /dev/null +++ b/Practices/singly_linked_list.py @@ -0,0 +1,131 @@ +class SinglyListNode: + def __init__(self, data): + self.data = data + self.next = None + + +class SinglyLinkedList: + def __init__(self): + self.head = None + + def insertAtHead(self, node): + if self.head is None: + self.head = node + else: + node.next = self.head + self.head = node + + def search(self, index): + temp = self.head + prev = None + counter = 0 + while temp is not None and counter < index: + prev = temp + temp = temp.next + counter += 1 + if temp is None: + print("Error: invalid index") + else: + return temp + + def searchValue(self, value): + temp = self.head + #prev = None + counter = 0 + + while temp is not None and temp.data != value: + #prev = temp + temp = temp.next + counter += 1 + + if temp is None: + print("Not Found") + elif temp.data == value: + return counter + def delete(self, value): + temp = self.head + prev = None + while temp is not None and temp.data is not value: + prev = temp + temp = temp.next + + if temp is None: + print("Error: value not found") + elif temp.next == self.head: + self.deleteAtHead() + else: + prev.next = temp.next + del temp + + def deleteAtHead(self): + temp = self.head + self.head = self.head.next + del temp + + def peek(self): + return self.head.data + + def isEmpty(self): + return self.head is None + + def printList(self): + temp = self.head + while temp is not None: + if temp.next is None: + print(temp.data) + else: + print(temp.data, end=" -> ") + temp = temp.next + + +def main(): + linkL = SinglyLinkedList() + + # Nodes + aNode = SinglyListNode(10) + bNode = SinglyListNode(11) + cNode = SinglyListNode(12) + dNode = SinglyListNode(13) + + linkL.insertAtHead(aNode) + linkL.insertAtHead(bNode) + linkL.insertAtHead(cNode) + linkL.insertAtHead(dNode) + + assert linkL.search(3).data == 10, f"Node containing 10 not found, got:{linkL.search(3).data}" + assert linkL.search(2).data == 11, f"Node containing 11 not found, got:{linkL.search(2).data}" + assert linkL.search(1).data == 12, f"Node containing 12 not found, got:{linkL.search(1).data}" + assert linkL.search(0).data == 13, f"Node containing 13 not found, got:{linkL.search(0).data}" + + print("No Errors: Linked List Contents: ") + linkL.printList() + print() + + linkL.delete(12) + print("After Deletion") + assert linkL.search(1).data == 11, f"Node containing 11 not found, got:{linkL.search(1).data}" + print("No Errors: Linked List Contents: ") + linkL.printList() + print() + + linkL.deleteAtHead() + assert linkL.search(0).data == 11, f"Node containing 11 not found, got:{linkL.search(0).data}" + print("No Errors: Linked List Contents: ") + linkL.printList() + print() + + assert linkL.searchValue(10) == 1, f"Index of node containing 10 not found, got:{linkL.searchValue(10)}" + print("Index of node containing 10 is: ", linkL.searchValue(10)) + + assert linkL.peek() == 11, f"Head of linked list is not 11, got:{linkL.peek()}" + print("Head of linked list is: ", linkL.peek()) + + linkL.deleteAtHead() + linkL.deleteAtHead() + + assert linkL.isEmpty() == True, f"Linked list is not empty, got:{linkL.printList()}" + print("Linked list is empty!") + + +if __name__ == "__main__": + main() diff --git a/Practices/stack.py b/Practices/stack.py new file mode 100755 index 0000000..4ae7327 --- /dev/null +++ b/Practices/stack.py @@ -0,0 +1,66 @@ +class Stack: + # Complete the code here + def __init__(self): + self.top = -1 + self.data = [] + + def push(self, value): + self.data.append(0) + self.top += 1 + self.data[self.top] = value + + def pop(self): + value = self.data[self.top] + del self.data[self.top] + self.top -= 1 + return value + + def peek(self): + if self.top != -1 and self.data is not None: + return self.data[self.top] + else: + return "Empty Stack" + def printStack(self): + print(self.data) + + + +def main(): + tmpStack = Stack() + + print(tmpStack.peek()) + + tmpStack.push(10) + topOfStack = tmpStack.peek() + assert (topOfStack == 10), f"Top of stack not 10, got:{topOfStack}" + + tmpStack.push(11) + topOfStack = tmpStack.peek() + assert (topOfStack == 11), f"Top of stack not 11, got:{topOfStack}" + + tmpStack.push(12) + topOfStack = tmpStack.peek() + assert (topOfStack == 12), f"Top of stack not 12, got:{topOfStack}" + + tmpStack.push(13) + topOfStack = tmpStack.peek() + assert (topOfStack == 13), f"Top of stack not 13, got:{topOfStack}" + + tmpStack.push(14) + topOfStack = tmpStack.peek() + assert (topOfStack == 14), f"Top of stack not 14, got:{topOfStack}" + + tmpStack.pop() + topOfStack = tmpStack.peek() + assert (topOfStack == 13), f"Top of stack not 13, got:{topOfStack}" + + tmpStack.pop() + topOfStack = tmpStack.peek() + assert (topOfStack == 12), f"Top of stack not 12, got:{topOfStack}" + + print("No Errors! Stack contents: ") + tmpStack.printStack() + + +if __name__ == "__main__": + main() diff --git a/Practices/supDigit.py b/Practices/supDigit.py new file mode 100755 index 0000000..f5ad538 --- /dev/null +++ b/Practices/supDigit.py @@ -0,0 +1,40 @@ +#!/bin/python3 + +import math +import os +import random +import re +import sys + +# +# Complete the 'superDigit' function below. +# +# The function is expected to return an INTEGER. +# The function accepts following parameters: +# 1. STRING n +# 2. INTEGER k +# + +def superDigit(n, k): + # Write your code here + if len(n) == 1: + return n + else: + digits = [int(x) for x in n] * k + return superDigit(str(sum(digits)), 1) + +if __name__ == '__main__': + #fptr = open(os.environ['OUTPUT_PATH'], 'w') + + first_multiple_input = input().rstrip().split() + + n = first_multiple_input[0] + + k = int(first_multiple_input[1]) + + result = superDigit(n, k) + print(result) + + #fptr.write(str(result) + '\n') + + #fptr.close() diff --git a/Practices/test1.py b/Practices/test1.py new file mode 100755 index 0000000..d9996fc --- /dev/null +++ b/Practices/test1.py @@ -0,0 +1,57 @@ +def partition(a): + pivot = a[0] + pivotIndex = 0 + + for i in range(1, len(a)): + if a[i] < pivot: + a[i], a[pivotIndex + 1] = a[pivotIndex + 1], a[i] + pivotIndex += 1 + + a[0], a[pivotIndex] = a[pivotIndex], a[0] + return pivotIndex + +# Using partition to find 0 to kth smallest element +# Without using quickSort +# Obfuscate this line +def findKthsmallest(nums, k): print(nums[:partition(nums)][::-1]) + #partition(nums) + #for i in range(k): + # if i == k - 1: + # print(nums[i]) + # else: + # print(nums[i], end=", ") + + # 1 line partition to find 0 to kth smallest element and reverse + +def quickSort(a): + if len(a) <= 1: + return a + pivotIndex = partition(a) + left = quickSort(a[:pivotIndex]) + right = quickSort(a[pivotIndex + 1:]) + return left + [a[pivotIndex]] + right + + +def findKthLargest(nums, k): + sortedArray = quickSort(nums) + for i in range(k): + print(sortedArray[i]) + +def binarySerarchK(nums,k): + left = 0 + right = len(nums) - 1 + + # Return element 1 to k + while left <= right: + mid = (left + right) >> 1 + if mid == k: + return nums[:mid] + elif mid < k: + left = mid + 1 + else: + right = mid - 1 + return -1 + +array = [4, 2, 5, 9, 1, 3, 6, 8, 7] +findKthsmallest(array, 3) +print(quickSort(array)) diff --git a/main.py b/main.py new file mode 100755 index 0000000..bf8b9e5 --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press Shift+F10 to execute it or replace it with your code. +# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/