├── .github └── img │ └── banner.webp ├── .gitignore ├── LICENSE ├── README.md ├── code-session ├── README.md ├── atoi │ └── main.py └── loan │ └── main.py ├── problems ├── README.md ├── beautiful-nums │ └── main.go ├── bell-numbers │ └── main.py ├── coins │ ├── go.mod │ └── main.go ├── count-subarrays-where-max-element-appears-at-least-k-times │ └── main.go ├── decode-string │ └── main.py ├── diagonal-traverse │ └── main.go ├── excel-sheet-column-title │ └── main.go ├── find-all-duplicates-in-an-array │ └── main.py ├── find-all-groups-of-farmland │ └── main.py ├── first-missing-positive │ └── main.py ├── generate-ipv4 │ └── main.go ├── generate-parentheses │ ├── go.mod │ └── main.py ├── jump-game │ └── main.py ├── k-nearest-neighbour │ └── main.go ├── kadanes-algorithm │ └── main.py ├── knn │ └── main.py ├── length-of-longest-subarray-with-at-most-k-frequency │ └── main.go ├── longest-palindrome │ ├── go.mod │ ├── main.go │ ├── main.py │ └── main_test.go ├── longest-palindromic-substring │ └── main.py ├── longest-valid-parentheses │ ├── go.mod │ └── main.go ├── longest_common_prefix │ └── main.py ├── merge-k-sorted-lists │ ├── go.mod │ └── main.go ├── merge │ ├── go.mod │ └── main.go ├── min-by-column │ └── main.py ├── number-of-islands │ └── main.py ├── package-delivery │ └── main.go ├── permutation-sequence │ └── main.go ├── prefix-and-suffix-search │ └── main.py ├── prefix-search │ ├── test_trie.py │ └── trie.py ├── print-n-bit-binary-numbers-having-more-1s-than-0s │ └── main.py ├── search-a-2d-matrix-ii │ ├── go.mod │ └── main.go ├── search-a-2d-matrix │ ├── go.mod │ └── main.py ├── shuffle │ ├── go.mod │ ├── main.go │ └── main_test.go ├── shuffler │ └── main.go ├── sort-colors │ ├── go.mod │ └── main.go └── sort-integers-by-the-number-of-1-bits │ └── main.py ├── questions ├── README.md ├── array-vs-slice │ ├── go.mod │ └── main.go ├── mutex │ ├── go.mod │ └── main.go └── reader-writer │ ├── go.mod │ └── main.go └── system-design └── README.md /.github/img/banner.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1995parham-teaching/interviews/0ea10e73c1faac6a3093060f6541d8fed686c9e3/.github/img/banner.webp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/latex 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=latex 4 | 5 | ### LaTeX ### 6 | ## Core latex/pdflatex auxiliary files: 7 | *.aux 8 | *.lof 9 | *.log 10 | *.lot 11 | *.fls 12 | *.out 13 | *.toc 14 | *.fmt 15 | *.fot 16 | *.cb 17 | *.cb2 18 | .*.lb 19 | 20 | ## Intermediate documents: 21 | *.dvi 22 | *.xdv 23 | *-converted-to.* 24 | # these rules might exclude image files for figures etc. 25 | *.ps 26 | *.eps 27 | *.pdf 28 | 29 | ## Generated if empty string is given at "Please type another file name for output:" 30 | .pdf 31 | 32 | ## Bibliography auxiliary files (bibtex/biblatex/biber): 33 | *.bbl 34 | *.bcf 35 | *.blg 36 | *-blx.aux 37 | *-blx.bib 38 | *.run.xml 39 | 40 | ## Build tool auxiliary files: 41 | *.fdb_latexmk 42 | *.synctex 43 | *.synctex(busy) 44 | *.synctex.gz 45 | *.synctex.gz(busy) 46 | *.pdfsync 47 | 48 | ## Build tool directories for auxiliary files 49 | # latexrun 50 | latex.out/ 51 | 52 | ## Auxiliary and intermediate files from other packages: 53 | # algorithms 54 | *.alg 55 | *.loa 56 | 57 | # achemso 58 | acs-*.bib 59 | 60 | # amsthm 61 | *.thm 62 | 63 | # beamer 64 | *.nav 65 | *.pre 66 | *.snm 67 | *.vrb 68 | 69 | # changes 70 | *.soc 71 | 72 | # comment 73 | *.cut 74 | 75 | # cprotect 76 | *.cpt 77 | 78 | # elsarticle (documentclass of Elsevier journals) 79 | *.spl 80 | 81 | # endnotes 82 | *.ent 83 | 84 | # fixme 85 | *.lox 86 | 87 | # feynmf/feynmp 88 | *.mf 89 | *.mp 90 | *.t[1-9] 91 | *.t[1-9][0-9] 92 | *.tfm 93 | 94 | #(r)(e)ledmac/(r)(e)ledpar 95 | *.end 96 | *.?end 97 | *.[1-9] 98 | *.[1-9][0-9] 99 | *.[1-9][0-9][0-9] 100 | *.[1-9]R 101 | *.[1-9][0-9]R 102 | *.[1-9][0-9][0-9]R 103 | *.eledsec[1-9] 104 | *.eledsec[1-9]R 105 | *.eledsec[1-9][0-9] 106 | *.eledsec[1-9][0-9]R 107 | *.eledsec[1-9][0-9][0-9] 108 | *.eledsec[1-9][0-9][0-9]R 109 | 110 | # glossaries 111 | *.acn 112 | *.acr 113 | *.glg 114 | *.glo 115 | *.gls 116 | *.glsdefs 117 | *.lzo 118 | *.lzs 119 | 120 | # uncomment this for glossaries-extra (will ignore makeindex's style files!) 121 | # *.ist 122 | 123 | # gnuplottex 124 | *-gnuplottex-* 125 | 126 | # gregoriotex 127 | *.gaux 128 | *.gtex 129 | 130 | # htlatex 131 | *.4ct 132 | *.4tc 133 | *.idv 134 | *.lg 135 | *.trc 136 | *.xref 137 | 138 | # hyperref 139 | *.brf 140 | 141 | # knitr 142 | *-concordance.tex 143 | # TODO Comment the next line if you want to keep your tikz graphics files 144 | *.tikz 145 | *-tikzDictionary 146 | 147 | # listings 148 | *.lol 149 | 150 | # luatexja-ruby 151 | *.ltjruby 152 | 153 | # makeidx 154 | *.idx 155 | *.ilg 156 | *.ind 157 | 158 | # minitoc 159 | *.maf 160 | *.mlf 161 | *.mlt 162 | *.mtc[0-9]* 163 | *.slf[0-9]* 164 | *.slt[0-9]* 165 | *.stc[0-9]* 166 | 167 | # minted 168 | _minted* 169 | *.pyg 170 | 171 | # morewrites 172 | *.mw 173 | 174 | # nomencl 175 | *.nlg 176 | *.nlo 177 | *.nls 178 | 179 | # pax 180 | *.pax 181 | 182 | # pdfpcnotes 183 | *.pdfpc 184 | 185 | # sagetex 186 | *.sagetex.sage 187 | *.sagetex.py 188 | *.sagetex.scmd 189 | 190 | # scrwfile 191 | *.wrt 192 | 193 | # sympy 194 | *.sout 195 | *.sympy 196 | sympy-plots-for-*.tex/ 197 | 198 | # pdfcomment 199 | *.upa 200 | *.upb 201 | 202 | # pythontex 203 | *.pytxcode 204 | pythontex-files-*/ 205 | 206 | # tcolorbox 207 | *.listing 208 | 209 | # thmtools 210 | *.loe 211 | 212 | # TikZ & PGF 213 | *.dpth 214 | *.md5 215 | *.auxlock 216 | 217 | # todonotes 218 | *.tdo 219 | 220 | # vhistory 221 | *.hst 222 | *.ver 223 | 224 | # easy-todo 225 | *.lod 226 | 227 | # xcolor 228 | *.xcp 229 | 230 | # xmpincl 231 | *.xmpi 232 | 233 | # xindy 234 | *.xdy 235 | 236 | # xypic precompiled matrices and outlines 237 | *.xyc 238 | *.xyd 239 | 240 | # endfloat 241 | *.ttt 242 | *.fff 243 | 244 | # Latexian 245 | TSWLatexianTemp* 246 | 247 | ## Editors: 248 | # WinEdt 249 | *.bak 250 | *.sav 251 | 252 | # Texpad 253 | .texpadtmp 254 | 255 | # LyX 256 | *.lyx~ 257 | 258 | # Kile 259 | *.backup 260 | 261 | # gummi 262 | .*.swp 263 | 264 | # KBibTeX 265 | *~[0-9]* 266 | 267 | # TeXnicCenter 268 | *.tps 269 | 270 | # auto folder when using emacs and auctex 271 | ./auto/* 272 | *.el 273 | 274 | # expex forward references with \gathertags 275 | *-tags.tex 276 | 277 | # standalone packages 278 | *.sta 279 | 280 | # Makeindex log files 281 | *.lpz 282 | 283 | # REVTeX puts footnotes in the bibliography by default, unless the nofootinbib 284 | # option is specified. Footnotes are the stored in a file with suffix Notes.bib. 285 | # Uncomment the next line to have this generated file ignored. 286 | #*Notes.bib 287 | 288 | ### LaTeX Patch ### 289 | # LIPIcs / OASIcs 290 | *.vtc 291 | 292 | # glossaries 293 | *.glstex 294 | 295 | # End of https://www.toptal.com/developers/gitignore/api/latex 296 | */*.pdf 297 | 298 | .idea 299 | problems/prefix-search/__pycache__/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Interviews

2 | 3 |

4 | banner 5 |

6 | 7 | ## Introduction 8 | 9 | This repository started as mocked interviews between me and [@elahe-dastan](https://github.com/elahe-dastan) then I decided to gather all together at our teaching organization, so other people can use it too. 10 | Now this repository contains sample problems for all stages in technical interview. 11 | Please fill issue in case of any problem with these questions. 12 | 13 | - [Questions: Ask them orally for reviewing core concepts.](./questions/) 14 | - [Code Sessions: You need to have a specific session for them, so you can see how the candidate is going to implement them and structure his/her project.](./code-session/) 15 | - [Problems: You can ask them during interview session and review the candidate pseudocode.](./problems/) 16 | 17 | ## Before Interview (As an Interviewee) 18 | 19 | 1. Only have these tabs open: 20 | 21 | - Gmail: Maybe they want to share a Google document with you 22 | - [GoByExample](https://gobyexample.com/): Maybe they let you review concepts in their live coding session, 23 | so having this at your hand to find out your challenges. 24 | - [Golang](https://pkg.go.dev/) 25 | 26 | 2. Have your anti-sanction service up and running 27 | 3. It is ok that you talk to yourself but try to do dispose of everything you don't know :) 28 | 4. Don't have any stress, they are as senior as you :D 29 | 30 | ## Before Interview (As an Interviewer) 31 | 32 | 1. Create a Markdown document contains your problems, questions and hands-on coding. (you can store these for future references) 33 | 2. Create another google document to share it with your interviewee and put the hands-on coding there. 34 | 3. Make yourself clean and ready to share video (if this is a video interview) 35 | 4. Review on your company introduction to make sound and clean 36 | 37 | ## What happens during an interview? 38 | 39 | First HR is going to set up a call and ask about the general conditions of interviewee. 40 | This call is not technical and actually about things like current employment status, your timings, etc. 41 | 42 | ### First Focus Interview 43 | 44 | It is better to start with greetings and then introducing you and your company then ask him/her to introduce himself/herself. 45 | Then you can ask typical questions like: 46 | 47 | - Challenges which you are proud of 48 | - University 49 | - Major 50 | - Courses 51 | - Where do you see yourself in the next 5 years? 52 | - Why and when did you get promoted? 53 | - Why do you think /company/ is for you? 54 | 55 | Also, you can ask about your business and tell him/her more about what you are actually doing. 56 | 57 | ### Second Focus Interview 58 | 59 | For the second meeting you can start by coding or system design (even you can ask both of them in a one meeting). 60 | -------------------------------------------------------------------------------- /code-session/README.md: -------------------------------------------------------------------------------- 1 | # Code Session 2 | 3 | These questions are hard to implement, so they require your candidate to have coding environment at hands, 4 | and you need to check edge cases or even ask him/her to write some test cases. 5 | 6 | ## Loan 7 | 8 | Design a loan system which gives people loan, and they can pay it back. 9 | They must pay back them in time, and they can have more than one loan at the time. 10 | 11 | ## Record Appender 12 | 13 | There is a data file as below. We want to read it and then insert it into database. 14 | 15 | data.txt: 16 | 17 | ``` 18 | John, Doe, 0939 123 1234 19 | Jane, Doe, 0399 123 1234 20 | ``` 21 | 22 | - API for retrieving data from database 23 | - Improve performance of Insert phase to support thousands of records 24 | 25 | P.S. [Solution](https://github.com/1995parham-teaching/record-appender) 26 | 27 | ## Hangman 28 | 29 | Implement Hangman! 30 | 31 | ``` 32 | > Computer: _ _ _ _ _ 33 | 34 | < Player: P 35 | 36 | > Computer _ _ _ _ _ (player lose some score) 37 | 38 | < Player: E 39 | 40 | > Computer E _ _ _ E 41 | 42 | < Player: L 43 | 44 | > Computer: E L _ _ E 45 | 46 | < Player: H 47 | 48 | > Computer E L _ H E 49 | 50 | < Player A 51 | 52 | > Computer E L A H E (player win) 53 | ``` 54 | 55 | If the player runs out of the score he or she will die. 56 | 57 | ## String to Integer (`atoi`) 58 | 59 | Implement the `myAtoi(string s)` function, which converts a string 60 | to a 32-bit signed integer (similar to C/C++'s `atoi` function). 61 | 62 | The algorithm for myAtoi(string s) is as follows: 63 | 64 | 1. Read in and ignore any leading whitespace. 65 | 2. Check if the next character (if not already at the end of the string) is `'-'` or `'+'`. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present. 66 | 3. Read in next the characters until the next non-digit character or the end of the input is reached. The rest of the string is ignored. 67 | 4. Convert these digits into an integer (i.e. `"123" -> 123`, `"0032" -> 32`). If no digits were read, then the integer is `0`. Change the sign as necessary (from step 2). 68 | 5. If the integer is out of the 32-bit signed integer range `[-2**31, 2**31 - 1]`, then clamp the integer so that it remains in the range. Specifically, integers less than `-2**31` should be clamped to `-2**31`, and integers greater than `2**31 - 1` should be clamped to `2**31 - 1`. 69 | 6. Return the integer as the final result. 70 | 71 | Note: 72 | 73 | - Only the space character `' '` is considered a whitespace character. 74 | - Do not ignore any characters other than the leading whitespace or the rest of the string after the digits. 75 | 76 | Example 1: 77 | 78 | ``` 79 | Input: s = "42" 80 | Output: 42 81 | Explanation: The underlined characters are what is read in, the caret is the current reader position. 82 | Step 1: "42" (no characters read because there is no leading whitespace) 83 | ^ 84 | Step 2: "42" (no characters read because there is neither a '-' nor '+') 85 | ^ 86 | Step 3: "42" ("42" is read in) 87 | ^ 88 | The parsed integer is 42. 89 | Since 42 is in the range [-231, 231 - 1], the final result is 42. 90 | ``` 91 | 92 | Example 2: 93 | 94 | ``` 95 | Input: s = " -42" 96 | Output: -42 97 | Explanation: 98 | Step 1: " -42" (leading whitespace is read and ignored) 99 | ^ 100 | Step 2: " -42" ('-' is read, so the result should be negative) 101 | ^ 102 | Step 3: " -42" ("42" is read in) 103 | ^ 104 | The parsed integer is -42. 105 | Since -42 is in the range [-231, 231 - 1], the final result is -42. 106 | ``` 107 | 108 | Example 3: 109 | 110 | ``` 111 | Input: s = "4193 with words" 112 | Output: 4193 113 | Explanation: 114 | Step 1: "4193 with words" (no characters read because there is no leading whitespace) 115 | ^ 116 | Step 2: "4193 with words" (no characters read because there is neither a '-' nor '+') 117 | ^ 118 | Step 3: "4193 with words" ("4193" is read in; reading stops because the next character is a non-digit) 119 | ^ 120 | The parsed integer is 4193. 121 | Since 4193 is in the range [-231, 231 - 1], the final result is 4193. 122 | ``` 123 | 124 | Constraints: 125 | 126 | - `0 <= s.length <= 200` 127 | - `s` consists of English letters (lower-case and upper-case), digits (`0-9`), `' '`, `'+'`, `'-'`, and `'.'`. 128 | 129 | [LeetCode](https://leetcode.com/problems/string-to-integer-atoi/) 130 | -------------------------------------------------------------------------------- /code-session/atoi/main.py: -------------------------------------------------------------------------------- 1 | def atoi(input: str) -> int: 2 | index = 0 3 | number = 0 4 | 5 | while index < len(input) and input[index] == " ": 6 | index += 1 7 | 8 | if index == len(input): 9 | return 0 10 | 11 | match input[index]: 12 | case "+": 13 | sign = 1 14 | index += 1 15 | case "-": 16 | sign = -1 17 | index += 1 18 | case _: 19 | sign = 1 20 | 21 | while index < len(input): 22 | match input[index]: 23 | case "0": 24 | number = number * 10 + 0 25 | case "1": 26 | number = number * 10 + 1 27 | case "2": 28 | number = number * 10 + 2 29 | case "3": 30 | number = number * 10 + 3 31 | case "4": 32 | number = number * 10 + 4 33 | case "5": 34 | number = number * 10 + 5 35 | case "6": 36 | number = number * 10 + 6 37 | case "7": 38 | number = number * 10 + 7 39 | case "8": 40 | number = number * 10 + 8 41 | case "9": 42 | number = number * 10 + 9 43 | case _: 44 | return sign * number 45 | if sign == 1 and number >= 2**31 - 1: 46 | return 2**31 - 1 47 | if sign == -1 and -number <= -(2**31): 48 | return -(2**31) 49 | index += 1 50 | 51 | return sign * number 52 | 53 | 54 | if __name__ == "__main__": 55 | assert atoi("") == 0 56 | assert atoi(" ") == 0 57 | assert atoi("-1") == -1 58 | assert atoi(" -12abac") == -12 59 | assert atoi(" -12") == -12 60 | assert atoi(" 12") == 12 61 | assert atoi(" 12 ") == 12 62 | -------------------------------------------------------------------------------- /code-session/loan/main.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | 3 | 4 | class Loan: 5 | def __init__(self, amount: float = 0, deadline: datetime.date | None = None): 6 | # load identification which will be filled by the database. 7 | self.id = 0 8 | self.amount: float = amount 9 | self.deadline: datetime.date | None = deadline 10 | self.paid: bool = False 11 | 12 | 13 | class Customer: 14 | def __init__(self): 15 | self.loans: list[Loan] = [] 16 | self.credit: float = 0 17 | 18 | def loan(self, loan: Loan): 19 | self.loans.append(loan) 20 | 21 | def pay(self, payment: float): 22 | nearest_loan: Loan | None = None 23 | nearest_deathline = datetime.date(year=1, month=1, day=1) 24 | for loan in self.loans: 25 | if ( 26 | loan.deadline is not None 27 | and (loan.deadline > nearest_deathline) 28 | and not loan.paid 29 | ): 30 | nearest_deathline = loan.deadline 31 | nearest_loan = loan 32 | 33 | if nearest_loan is None: 34 | self.credit += payment 35 | return 36 | 37 | if payment < nearest_loan.amount: 38 | nearest_loan.amount -= payment 39 | elif payment >= nearest_loan.amount: 40 | payment -= nearest_loan.amount 41 | nearest_loan.amount = 0 42 | nearest_loan.paid = True 43 | 44 | self.pay(payment) 45 | 46 | 47 | if __name__ == "__main__": 48 | customer = Customer() 49 | customer.loan( 50 | Loan( 51 | amount=100, 52 | deadline=datetime.date.today() + datetime.timedelta(minutes=100), 53 | ) 54 | ) 55 | customer.loan( 56 | Loan( 57 | amount=100, 58 | deadline=datetime.date.today() + datetime.timedelta(minutes=1000), 59 | ) 60 | ) 61 | customer.loan( 62 | Loan( 63 | amount=100, 64 | deadline=datetime.date.today() + datetime.timedelta(minutes=200), 65 | ) 66 | ) 67 | 68 | customer.pay(payment=400) 69 | 70 | print("consumer loans after paying $400:") 71 | for i, loan in enumerate(customer.loans): 72 | print(f"{i}. ${loan.amount} {loan.deadline}") 73 | 74 | print(f"remaining cusmter credit: ${customer.credit}") 75 | -------------------------------------------------------------------------------- /problems/README.md: -------------------------------------------------------------------------------- 1 | # Problems 2 | 3 | These are some hands-on problem, and you can use a shared Google Doc to read and write code together. 4 | They don't require the interviewee to have an IDE or coding environment, and the main part of your discussion 5 | should be Algorithm. 6 | 7 | ## [KNN](./knn) 8 | 9 | Implement KNN Algorithm. 10 | 11 | ## [Decode String](./decode-string) 12 | 13 | Given an encoded string, return its decoded string. 14 | 15 | The encoding rule is: `k[encoded_string]`, where the `encoded_string` inside the square brackets is being 16 | repeated exactly `k` times. Note that `k` is guaranteed to be a positive integer. 17 | 18 | You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, 19 | etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only 20 | for those repeat numbers, k. For example, there will not be input like `3a` or `2[4]`. 21 | 22 | The test cases are generated so that the length of the output will never exceed `10^5`. 23 | 24 | Example 1: 25 | 26 | ``` 27 | Input: s = "3[a]2[bc]" 28 | Output: "aaabcbc" 29 | ``` 30 | 31 | Example 2: 32 | 33 | ``` 34 | Input: s = "3[a2[c]]" 35 | Output: "accaccacc" 36 | ``` 37 | 38 | Example 3: 39 | 40 | ``` 41 | Input: s = "2[abc]3[cd]ef" 42 | Output: "abcabccdcdcdef" 43 | ``` 44 | 45 | Constraints: 46 | 47 | - `1 <= s.length <= 30` 48 | - `s` consists of lowercase English letters, digits, and square brackets `'[]'`. 49 | - `s` is guaranteed to be a valid input. 50 | - All the integers in `s` are in the range `[1, 300]`. 51 | 52 | [LeetCode](https://leetcode.com/problems/decode-string/description/) 53 | 54 | ## [Find All Groups of Farmland](./find-all-groups-of-farmland) 55 | 56 | You are given a **0-indexed** `m x n` binary matrix `land` where a `0` represents a hectare of forested land and 57 | a `1` represents a hectare of farmland. 58 | 59 | To keep the land organized, there are designated rectangular areas of hectares that consist **entirely** of farmland. 60 | These rectangular areas are called **groups**. No two groups are adjacent, meaning farmland in one group 61 | is not four-directionally adjacent to another farmland in a different group. 62 | 63 | `land` can be represented by a coordinate system where the top left corner of `land` is `(0, 0)` and the bottom right 64 | corner of `land` is `(m-1, n-1)`. Find the coordinates of the top left and bottom right corner of each **group** 65 | of farmland. A **group** of farmland with a top left corner at `(r1, c1)` and a bottom right corner at 66 | `(r2, c2)` is represented by the 4-length array `[r1, c1, r2, c2]`. 67 | 68 | Return a 2D array containing the 4-length arrays described above for each **group** of farmland in `land`. 69 | If there are no groups of farmland, return an empty array. You may return the answer in **any order**. 70 | 71 | [LeetCode](https://leetcode.com/problems/find-all-groups-of-farmland/) 72 | 73 | ## [Number of Islands](./number-of-islands) 74 | 75 | Given an m x n 2D binary grid which represents a map of '1's (land) and '0's (water), return the number of islands. 76 | 77 | An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. 78 | 79 | Example 1: 80 | 81 | ``` 82 | Input: grid = [ 83 | ["1","1","1","1","0"], 84 | ["1","1","0","1","0"], 85 | ["1","1","0","0","0"], 86 | ["0","0","0","0","0"] 87 | ] 88 | Output: 1 89 | ``` 90 | 91 | Example 2: 92 | 93 | ``` 94 | Input: grid = [ 95 | ["1","1","0","0","0"], 96 | ["1","1","0","0","0"], 97 | ["0","0","1","0","0"], 98 | ["0","0","0","1","1"] 99 | ] 100 | Output: 3 101 | ``` 102 | 103 | Constraints: 104 | 105 | - `m == grid.length` 106 | - `n == grid[i].length` 107 | - `1 <= m, n <= 300` 108 | - `grid[i][j] is '0' or '1'` 109 | 110 | [LeetCode](https://leetcode.com/problems/number-of-islands/) 111 | 112 | ## [Shuffle](./shuffle) 113 | 114 | You have an array with n-items (A). 115 | We want to partition it into k-subarrays that each of them has n/k items, and each element of A appears precisely once. 116 | The order of these subarrays must not be the same as the A. 117 | 118 | **We know that: n % k == 0** 119 | 120 | - With duplication or without duplication? 121 | 122 | For example: 123 | 124 | ```python 125 | A = [1, 2, 3, 4] 126 | 127 | k = 2 128 | ``` 129 | 130 | we don't accept the following solution: 131 | 132 | ```python 133 | A1 = {1, 2} 134 | A2 = {3, 4} 135 | ``` 136 | 137 | but we accept the following solution: 138 | 139 | ```python 140 | A1 = [1, 3] 141 | A2 = [2, 4] 142 | ``` 143 | 144 | ## [Coins](./coins) 145 | 146 | We have `n` amount of money and our country have the following coins: 147 | 148 | - coin-1 149 | - coin-5 150 | - coin-7 151 | - coin-10 152 | 153 | We want to have this money with minimum number of coins. What is the minimum? For example: 154 | 155 | - 2 = 2 x coin-1 156 | - 5 = 1 x coin-5 157 | - 6 = 1 x coin-5 + 1 x coin-1 158 | 159 | ## Bulb Switcher 160 | 161 | There are n bulbs that are initially off. You first turn on all the bulbs. 162 | Then, you turn off every second bulb. On the third round, 163 | you toggle every third bulb (turning on if it's off or turning off if it's on). 164 | For the i-th round, you toggle every i bulb. 165 | For the n-th round, you only toggle the last bulb. 166 | Find how many bulbs are on after n rounds. 167 | 168 | Example: 169 | 170 | ```text 171 | Input: 3 172 | Output: 1 173 | Explanation: 174 | At first, the three bulbs are [off, off, off]. 175 | After first round, the three bulbs are [on, on, on]. 176 | After second round, the three bulbs are [on, off, on]. 177 | After third round, the three bulbs are [on, off, off]. 178 | ``` 179 | 180 | So you should return 1, because there is only one bulb is on. 181 | 182 | [LeetCode](https://leetcode.com/problems/bulb-switcher/) 183 | 184 | ## Happy Number 185 | 186 | Write an algorithm to determine if a number n is "happy". 187 | 188 | A happy number is a number defined by the following process: Starting with any positive integer, 189 | replace the number by the sum of the squares of its digits, and repeat the process 190 | until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. 191 | Those numbers for which this process ends in 1 are happy numbers. 192 | 193 | Return True if n is a happy number, and False if not. 194 | 195 | Example: 196 | 197 | ```text 198 | Input: 19 199 | Output: true 200 | Explanation: 201 | 1^2 + 9^2 = 82 202 | 8^2 + 2^2 = 68 203 | 6^2 + 8^2 = 100 204 | 1^2 + 0^2 + 0^2 = 1 205 | ``` 206 | 207 | [LeetCode](https://leetcode.com/problems/happy-number/) 208 | 209 | ## Rotate Image 210 | 211 | You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). 212 | 213 | ```text 214 | Given input matrix = 215 | [ 216 | [1,2,3], 217 | [4,5,6], 218 | [7,8,9] 219 | ], 220 | 221 | rotate the input matrix in-place such that it becomes: 222 | [ 223 | [7,4,1], 224 | [8,5,2], 225 | [9,6,3] 226 | ] 227 | ``` 228 | 229 | ```text 230 | Given input matrix = 231 | [ 232 | [ 5, 1, 9,11], 233 | [ 2, 4, 8,10], 234 | [13, 3, 6, 7], 235 | [15,14,12,16] 236 | ], 237 | 238 | rotate the input matrix in-place such that it becomes: 239 | [ 240 | [15,13, 2, 5], 241 | [14, 3, 4, 1], 242 | [12, 6, 8, 9], 243 | [16, 7,10,11] 244 | ] 245 | ``` 246 | 247 | [LeetCode](https://leetcode.com/problems/rotate-image/) 248 | 249 | ## Snappfood 250 | 251 | We have motorcycles and restaurants. Motorcycles deliver foods to peoples from restaurants. 252 | How we can schedule this delivery process? 253 | 254 | ## [Search a 2D Matrix](./search-a-2d-matrix) 255 | 256 | You are given a `m x n` integer matrix `matrix` with the following two properties: 257 | 258 | - Each row is sorted in non-decreasing order. 259 | - The first integer of each row is greater than the last integer of the previous row. 260 | 261 | Given an integer `target`, return `true` if `target` is in `matrix` or `false` otherwise. 262 | 263 | You must write a solution in `O(log(m * n))` time complexity. 264 | 265 | Example 1: 266 | 267 | ```text 268 | Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 269 | Output: true 270 | ``` 271 | 272 | Example 2: 273 | 274 | ```text 275 | Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 276 | Output: false 277 | ``` 278 | 279 | Constraints: 280 | 281 | - `m == matrix.length` 282 | - `n == matrix[i].length` 283 | - `1 <= m, n <= 100` 284 | - `-10^4 <= matrix[i][j], target <= 10^4` 285 | 286 | ## [Search a 2D Matrix II](./search-a-2d-matrix-ii) 287 | 288 | Write an efficient algorithm that searches for a value `target` in an `m x n` integer matrix. 289 | This matrix has the following properties: 290 | 291 | - Integers in each row are sorted in ascending from left to right. 292 | - Integers in each column are sorted in ascending from top to bottom. 293 | 294 | ```text 295 | Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5 296 | Output: true 297 | ``` 298 | 299 | ```text 300 | Input: matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 20 301 | Output: false 302 | ``` 303 | 304 | Constraints: 305 | 306 | - `m == matrix.length` 307 | - `n == matrix[i].length` 308 | - `1 <= n, m <= 300` 309 | - `-109 <= matrix[i][j] <= 109` 310 | - All the integers in each row are sorted in ascending order. 311 | - All the integers in each column are sorted in ascending order. 312 | - `-109 <= target <= 109` 313 | 314 | [LeetCode](https://leetcode.com/problems/search-a-2d-matrix-ii/) 315 | 316 | ## [Longest Palindromic Substring](./longest-palindrome) 317 | 318 | Given a string `s`, return the longest palindromic substring in `s`. 319 | 320 | Example 1: 321 | 322 | ```text 323 | Input: s = "babad" 324 | Output: "bab" 325 | Explanation: "aba" is also a valid answer. 326 | ``` 327 | 328 | Example 2: 329 | 330 | ```text 331 | Input: s = "cbbd" 332 | Output: "bb" 333 | ``` 334 | 335 | [LeetCode](https://leetcode.com/problems/longest-palindromic-substring/) 336 | 337 | ## K-th Smallest Element in a Sorted Matrix 338 | 339 | [LeetCode](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/) 340 | 341 | ## [Merge k Sorted Lists](./merge-k-sorted-lists) 342 | 343 | You are given an array of `k` linked-lists `lists`, each linked-list is sorted in ascending order. 344 | Merge all the linked-lists into one sorted linked-list and return it. 345 | 346 | Example 1: 347 | 348 | ```text 349 | Input: lists = [[1,4,5],[1,3,4],[2,6]] 350 | Output: [1,1,2,3,4,4,5,6] 351 | Explanation: The linked-lists are: 352 | [ 353 | 1->4->5, 354 | 1->3->4, 355 | 2->6 356 | ] 357 | merging them into one sorted list: 358 | 1->1->2->3->4->4->5->6 359 | ``` 360 | 361 | Example 2: 362 | 363 | ```text 364 | Input: lists = [] 365 | Output: [] 366 | ``` 367 | 368 | Example 3: 369 | 370 | ```text 371 | Input: lists = [[]] 372 | Output: [] 373 | ``` 374 | 375 | [LeetCode](https://leetcode.com/problems/merge-k-sorted-lists/) 376 | 377 | ## K Nearest Neighbor 378 | 379 | We have `n` points and one reference point. 380 | Each point has `x` and `y` coordinates. 381 | We want to find `k` the nearest points to the reference point. 382 | 383 | For example: 384 | 385 | ```python 386 | import dataclasses 387 | 388 | @dataclasses.dataclass() 389 | class Point: 390 | x: float 391 | y: float 392 | 393 | points = [ 394 | Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0), 395 | Point(-1, -1), Point(0, -1), Point(-1, 0), 396 | ] 397 | reference = Point(-1, -1) 398 | n = len(points) 399 | k = 2 400 | 401 | k_nearest_points = [Point(-1, -1), Point(-1, 0)] 402 | # or 403 | k_nearest_points = [Point(-1, -1), Point(0, -1)] 404 | ``` 405 | 406 | ## [Sort Colors](./sort-colors) 407 | 408 | Given an array `nums` with `n` objects colored red, white, or blue, 409 | sort them in-place so that objects of the same color are adjacent, 410 | with the colors in the order red, white, and blue. 411 | 412 | We will use the integers `0`, `1`, and `2` to represent the color red, white, and blue, respectively. 413 | 414 | You must solve this problem without using the library's sort function 415 | 416 | Example 1: 417 | 418 | ```text 419 | Input: nums = [2,0,2,1,1,0] 420 | Output: [0,0,1,1,2,2] 421 | ``` 422 | 423 | Example 2: 424 | 425 | ```text 426 | Input: nums = [2,0,1] 427 | Output: [0,1,2] 428 | ``` 429 | 430 | Constraints: 431 | 432 | - `n == nums.length` 433 | - `1 <= n <= 300` 434 | - `nums[i]` is either `0`, `1`, or `2`. 435 | 436 | Follow up: Could you come up with a one-pass algorithm using only constant extra space? 437 | 438 | [LeetCode](https://leetcode.com/problems/sort-colors) 439 | 440 | ## [Generate Parentheses](./generate-parentheses) 441 | 442 | Given `n` pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 443 | 444 | Example 1: 445 | 446 | ```text 447 | Input: n = 3 448 | Output: ["((()))","(()())","(())()","()(())","()()()"] 449 | ``` 450 | 451 | Example 2: 452 | 453 | ```text 454 | Input: n = 1 455 | Output: ["()"] 456 | ``` 457 | 458 | Constraints: 459 | 460 | - `1 <= n <= 8` 461 | 462 | [LeetCode](https://leetcode.com/problems/generate-parentheses) 463 | 464 | ## [Longest Valid Parentheses](./longest-valid-parentheses) 465 | 466 | Given a string containing just the characters '(' and ')', return the length of the longest valid (well-formed) parentheses 467 | substring. 468 | 469 | Example 1: 470 | 471 | ```text 472 | Input: s = "(()" 473 | Output: 2 474 | Explanation: The longest valid parentheses substring is "()". 475 | ``` 476 | 477 | Example 2: 478 | 479 | ```text 480 | Input: s = ")()())" 481 | Output: 4 482 | Explanation: The longest valid parentheses substring is "()()". 483 | ``` 484 | 485 | Example 3: 486 | 487 | ```text 488 | Input: s = "" 489 | Output: 0 490 | ``` 491 | 492 | Constraints: 493 | 494 | - `0 <= s.length <= 3 * 10^4` 495 | - `s[i] is '(', or ')'` 496 | 497 | [LeetCode](https://leetcode.com/problems/longest-valid-parentheses/) 498 | 499 | ## Min By Column 500 | 501 | ### Part 1 of 2 502 | 503 | Imagine that we are working with a simple database. 504 | Each row associates column names (strings) with integer values. 505 | Here's a table with three rows: 506 | 507 | ```text 508 | a b c d 509 | 1 0 0 0 510 | 0 2 3 0 511 | 0 0 0 4 512 | ``` 513 | 514 | We might choose to represent a database table in JSON, as an array of objects. 515 | For example, the previous table could be written as: 516 | 517 | ```json 518 | [ 519 | { "a": 1, "b": 0, "c": 0, "d": 0 }, 520 | { "a": 0, "b": 2, "c": 3, "d": 0 }, 521 | { "a": 0, "b": 0, "c": 0, "d": 4 } 522 | ] 523 | ``` 524 | 525 | Write a function, `min_by_column`, that takes a database table (as above), 526 | along with a column name, and returns the row that contains the minimum value for the given column. 527 | If a row doesn't have any value for the column, your function should behave as though the value for that column was zero. 528 | 529 | #### Examples 530 | 531 | ```python 532 | table_1 = [ 533 | {"a": 1}, 534 | {"a": 2}, 535 | {"a": 3} 536 | ] 537 | assert min_by_column(table_1, "a") == {"a": 1} 538 | ``` 539 | 540 | ```python 541 | table_2 = [ 542 | {"a": 1, "b": 2}, 543 | {"a": 3, "b": 0} 544 | ] 545 | assert min_by_column(table_2, "b") == {"a": 3, "b": 0} 546 | ``` 547 | 548 | ```python 549 | table_3 = [ 550 | {"a": 1, "b": -2}, 551 | {"a": 3} 552 | ] 553 | assert min_by_column(table_3, "b") == {"a": 1, "b": -2} 554 | ``` 555 | 556 | ### Part 2 of 2 557 | 558 | In Part 1 you may have noticed that it's possible for two rows to be "tied", 559 | meaning that either would be an acceptable return value from `min_by_column`. 560 | 561 | Consider: 562 | 563 | ```python 564 | table_4 = [ 565 | {"a": 1, "b": 2}, 566 | {"a": 1, "b": 3}, 567 | {"a": 1, "b": 4} 568 | ] 569 | assert min_by_column(table_4, "a") == '???' 570 | ``` 571 | 572 | Since all three rows have the same value for column "a", 573 | all three rows are acceptable candidates to be returned by `min_by_column(table, "a")`. 574 | 575 | In these cases, it would be nice if users could specify additional columns (e.g. "b") to use as tie-breakers. 576 | A tie-breaker would only apply in cases where multiple rows share the same minimum value. 577 | In `table_4` above, the row `{"a": 1, "b": 2}` is tied for the smallest "a" value (1) and of all the tied candidates, 578 | it has the smallest "b" value (2). If two records had equal values for "a" and also for "b" then another 579 | tie-breaker (e.g. "c") could be used. 580 | When records are tied with respect to all columns, any of the tied records may be considered the minimum. 581 | 582 | Write a function `min_by_columns` that takes a database table and an ordered list of column names, 583 | and returns the row with the minimum column values using the tie-breaking logic above. 584 | Refactor `min_by_column` to use `min_by_columns` to produce its result. 585 | 586 | #### Examples 587 | 588 | ```python 589 | table_5 = [ 590 | {"x": 1, "y": 3}, 591 | {"x": 1, "y": 0} 592 | ] 593 | assert min_by_columns(table_5, ["x", "y"]) == {"x": 1, "y": 0} 594 | ``` 595 | 596 | ```python 597 | table_6 = [ 598 | {"x": 2, "y": 3}, 599 | {"x": 2, "y": 1}, 600 | {"x": 1, "y": 10} 601 | ] 602 | assert min_by_columns(table_6, ["x", "y"]) == {"x": 1, "y": 10} 603 | ``` 604 | 605 | ```python 606 | table_7 = [ 607 | {"x": 3, "y": -1, "z": 0}, 608 | {"x": 1, "y": 10, "z": 1}, 609 | {"x": 1, "y": 10, "z": 0} 610 | ] 611 | assert min_by_columns(table_7, ["x", "y", "z"]) == {"x": 1, "y": 10, "z": 0} 612 | ``` 613 | 614 | ```python 615 | table_8 = [ 616 | {"x": 1, "y": 2, "z": 3}, 617 | {"x": 2, "y": 2, "z": 2} 618 | ] 619 | assert min_by_columns(table_8, ["x", "y", "z"]) == {"x": 1, "y": 2, "z": 3} 620 | ``` 621 | 622 | ## Prefix Search 623 | 624 | We have a database, and we'd like it to support these operations: 625 | 626 | - `insert(word)`: Inset a word to database 627 | - `look up(prefix)`: Return all the words starting with the given prefix 628 | - `delete(prefix)`: Delete all the words starting with the given prefix 629 | - `count(prefix)`Count the number of words starting with the given prefix 630 | 631 | ## Package Delivery 632 | 633 | ### Part 1 634 | 635 | Write a Delivery class (or object) that represents a delivery with a destination 636 | and distance. 637 | Deliveries require different sensors, depending on their distance. 638 | 639 | Add a method, `getNeededSensors`, that returns a mapping of sensor name to the 640 | count of that sensor needed to complete the delivery according to these rules: 641 | 642 | - If distance < 10 miles, require 1 gps and 1 temp sensor. 643 | - If 10 <= distance < 100 miles require 1 gps, 2 temp, and 1 weight sensor. 644 | - If distance >= 100 miles require 2 gps, 4 temp, and 2 weight sensors. 645 | 646 | ### Part 2 647 | 648 | Write a Scheduler class (or object) that represents a daily delivery scheduler with a set of available sensors. 649 | Add a method, `scheduleDeliveries`, that given a list of deliveries as an argument, 650 | returns a list of deliveries that can be made that day. 651 | Assume all deliveries will be leaving at the same time every day, so sensors can only 652 | be used once. 653 | 654 | Test Cases to consider: 655 | 656 | ```python 657 | deliveryA = Delivery("A", 9) 658 | deliveryB = Delivery("B", 15) 659 | deliveryC = Delivery("C", 100) 660 | scheduler = Scheduler({"gps": 2, "temp": 4, "weight": 2}) 661 | scheduler.scheduleDeliveries([deliveryA, deliveryB, deliveryC]) == [deliveryA, deliveryB] 662 | scheduler.scheduleDeliveries([deliveryA, deliveryC, deliveryB]) == [deliveryA, deliveryB] 663 | scheduler.scheduleDeliveries([deliveryC, deliveryA, deliveryB]) == [deliveryC] 664 | ``` 665 | 666 | ### Part 3 667 | 668 | We get paid a flat fee for all deliveries. Modify the `scheduleDeliveries` 669 | function to maximize the number of deliveries that will be made in a day. 670 | 671 | Our previous test: 672 | 673 | ```python 674 | scheduler.scheduleDeliveries([deliveryC, deliveryA, deliveryB]) ==[deliveryC] 675 | ``` 676 | 677 | Should now return: 678 | 679 | ```python 680 | scheduler.scheduleDeliveries([deliveryC, deliveryA, deliveryB]) ==[deliveryA, deliveryB] 681 | ``` 682 | 683 | ### Part 4 684 | 685 | We recently purchased a new type of sensor, `doorSensor`. 686 | A `doorSensor` can be used in place of 1 weight sensor or in place of 2 temperature 687 | sensors at any time. 688 | Modify our existing functions to maximize the day's deliveries with the new sensor. 689 | 690 | ## K-th biggest number 691 | 692 | time complexity of retrieving the biggest number in a list: O(n) 693 | time complexity of retrieving the second-biggest number in a list: 2\*O(n) = O(n) 694 | time complexity of retrieving the k-th biggest number in a list: 695 | if k is smaller than lg(n) we can retrieve the element in `O(kn)` and if k is bigger than `lg(n)` we can retrieve the 696 | element in `O(nlg(n))` by sorting the list and returning the k-th element 697 | 698 | ## [Prefix and Suffix Search](./prefix-and-suffix-search/) 699 | 700 | [LeetCode](https://leetcode.com/problems/prefix-and-suffix-search/) 701 | 702 | ## [Print N-bit binary numbers having more 1s than 0s](./print-n-bit-binary-numbers-having-more-1s-than-0s/) 703 | 704 | Given a positive integer `n`. 705 | Your task is to generate a string list of all n-bit binary numbers where, for any prefix of the number, 706 | there are more or an equal number of 1's than 0's. The numbers should be sorted in decreasing order of magnitude. 707 | 708 | Example 1: 709 | 710 | ```text 711 | Input: 712 | n = 2 713 | Output: 714 | "11, 10" 715 | Explanation: Valid numbers are those where each prefix has more 1s than 0s: 716 | 11: all its prefixes (1 and 11) have more 1s than 0s. 717 | 10: all its prefixes (1 and 10) have more 1s than 0s. 718 | So, the output is "11, 10". 719 | ``` 720 | 721 | Example 2: 722 | 723 | ```text 724 | Input: 725 | n = 3 726 | Output: 727 | "111, 110, 101" 728 | Explanation: Valid numbers are those where each prefix has more 1s than 0s. 729 | 111: all its prefixes (1, 11, and 111) have more 1s than 0s. 730 | 110: all its prefixes (1, 11, and 110) have more 1s than 0s. 731 | 101: all its prefixes (1, 10, and 101) have more 1s than 0s. 732 | So, the output is "111, 110, 101". 733 | ``` 734 | 735 | User Task: 736 | Your task is to complete the function `NBitBinary()` which takes a single number as input `n` and 737 | returns the list of strings in **decreasing** order. You need not take any input or print anything. 738 | 739 | ```python 740 | class Solution: 741 | def NBitBinary(self, n): 742 | pass 743 | ``` 744 | 745 | Expected Time Complexity: `O(|2n|)` 746 | Expected Auxiliary Space: `O(2n)` 747 | 748 | Constraints: 749 | 750 | ``` 751 | 1 <= n <= 15 752 | ``` 753 | 754 | [GeeksForGeeks](https://www.geeksforgeeks.org/problems/print-n-bit-binary-numbers-having-more-1s-than-0s0252) 755 | 756 | ## [Kadane's Algorithm](./kadanes-algorithm/) 757 | 758 | Given an array `Arr[]` of `N` integers. 759 | Find the contiguous sub-array (containing at least one number) which has the maximum sum and return its sum. 760 | 761 | Example 1: 762 | 763 | ```text 764 | Input: 765 | N = 5 766 | Arr[] = {1,2,3,-2,5} 767 | Output: 768 | 9 769 | Explanation: 770 | Max subarray sum is 9 771 | of elements (1, 2, 3, -2, 5) which 772 | is a contiguous subarray. 773 | ``` 774 | 775 | Example 2: 776 | 777 | ```text 778 | Input: 779 | N = 4 780 | Arr[] = {-1,-2,-3,-4} 781 | Output: 782 | -1 783 | Explanation: 784 | Max subarray sum is -1 785 | of element (-1) 786 | ``` 787 | 788 | Your Task: 789 | You don't need to read input or print anything. 790 | The task is to complete the function `maxSubarraySum()` which takes `Arr[]` and `N` as input parameters 791 | and returns the sum of subarray with maximum sum. 792 | 793 | Expected Time Complexity: `O(N)` 794 | Expected Auxiliary Space: `O(1)` 795 | 796 | Constraints: 797 | 798 | ``` 799 | 1 ≤ N ≤ 10^6 800 | -10^7 ≤ A[i] ≤ 10^7 801 | ``` 802 | 803 | [GeeksForGeeks](https://www.geeksforgeeks.org/problems/kadanes-algorithm-1587115620/) 804 | 805 | ## [Find All Duplicates in an Array](./find-all-duplicates-in-an-array) 806 | 807 | Given an integer array `nums` of length `n` where all the integers of `nums` are in the range `[1, n]` 808 | and each integer appears once or twice, return an array of all the integers that appears twice. 809 | 810 | You must write an algorithm that runs in `O(n)` time and uses only constant extra space. 811 | 812 | Example 1: 813 | 814 | ``` 815 | Input: nums = [4,3,2,7,8,2,3,1] 816 | Output: [2,3] 817 | ``` 818 | 819 | Example 2: 820 | 821 | ``` 822 | Input: nums = [1,1,2] 823 | Output: [1] 824 | ``` 825 | 826 | Example 3: 827 | 828 | ``` 829 | Input: nums = [1] 830 | Output: [] 831 | ``` 832 | 833 | Constraints: 834 | 835 | - `n == nums.length` 836 | - `1 <= n <= 105` 837 | - `1 <= nums[i] <= n` 838 | 839 | Each element in `nums` appears once or twice. 840 | 841 | [LeetCode](https://leetcode.com/problems/find-all-duplicates-in-an-array/) 842 | 843 | ## [First Missing Positive](./first-missing-positive) 844 | 845 | Given an unsorted integer array `nums`. 846 | Return the smallest positive integer that is not present in `nums`. 847 | 848 | You must implement an algorithm that runs in `O(n)` time and uses `O(1)` auxiliary space. 849 | 850 | Example 1: 851 | 852 | ``` 853 | Input: nums = [1,2,0] 854 | Output: 3 855 | Explanation: The numbers in the range [1,2] are all in the array. 856 | ``` 857 | 858 | Example 2: 859 | 860 | ``` 861 | Input: nums = [3,4,-1,1] 862 | Output: 2 863 | Explanation: 1 is in the array but 2 is missing. 864 | ``` 865 | 866 | Example 3: 867 | 868 | ``` 869 | Input: nums = [7,8,9,11,12] 870 | Output: 1 871 | Explanation: The smallest positive integer 1 is missing. 872 | ``` 873 | 874 | Constraints: 875 | 876 | - `1 <= nums.length <= 105` 877 | - `231 <= nums[i] <= 231 - 1` 878 | 879 | [LeetCode](https://leetcode.com/problems/first-missing-positive) 880 | 881 | ## [Excel Sheet Column Title](./excel-sheet-column-title) 882 | 883 | Given an integer `columnNumber`, return its corresponding column title as it appears in an Excel sheet. 884 | 885 | For example: 886 | 887 | ``` 888 | A -> 1 889 | B -> 2 890 | C -> 3 891 | ... 892 | Z -> 26 893 | AA -> 27 894 | AB -> 28 895 | ... 896 | ``` 897 | 898 | Example 1: 899 | 900 | ``` 901 | Input: columnNumber = 1 902 | Output: "A" 903 | ``` 904 | 905 | Example 2: 906 | 907 | ``` 908 | Input: columnNumber = 28 909 | Output: "AB" 910 | ``` 911 | 912 | Example 3: 913 | 914 | ``` 915 | Input: columnNumber = 701 916 | Output: "ZY" 917 | ``` 918 | 919 | Constraints: 920 | 921 | - `1 <= columnNumber <= 231 - 1` 922 | 923 | [LeetCode](https://leetcode.com/problems/excel-sheet-column-title/) 924 | 925 | ## [Permutation Sequence](./permutation-sequence) 926 | 927 | The set `[1, 2, 3, ..., n]` contains a total of `n!` unique permutations. 928 | 929 | By listing and labeling all the permutations in order, we get the following sequence for n = 3: 930 | 931 | ``` 932 | "123" 933 | "132" 934 | "213" 935 | "231" 936 | "312" 937 | "321" 938 | ``` 939 | 940 | Given `n` and `k`, return the `k`th permutation sequence. 941 | 942 | Example 1: 943 | 944 | ``` 945 | Input: n = 3, k = 3 946 | Output: "213" 947 | ``` 948 | 949 | Example 2: 950 | 951 | ``` 952 | Input: n = 4, k = 9 953 | Output: "2314" 954 | ``` 955 | 956 | Example 3: 957 | 958 | ``` 959 | Input: n = 3, k = 1 960 | Output: "123" 961 | ``` 962 | 963 | Constraints: 964 | 965 | - `1 <= n <= 9` 966 | - `1 <= k <= n!` 967 | 968 | ## [Length of Longest Subarray With at Most K Frequency](./length-of-longest-subarray-with-at-most-k-frequency) 969 | 970 | You are given an integer array `nums` and an integer `k`. 971 | The frequency of an element `x` is the number of times it occurs in an array. 972 | An array is called good if the frequency of each element in this array is less than or equal to `k`. 973 | Return the length of the longest good subarray of `nums`. 974 | A subarray is a contiguous non-empty sequence of elements within an array. 975 | 976 | Example 1: 977 | 978 | ``` 979 | Input: nums = [1,2,3,1,2,3,1,2], k = 2 980 | Output: 6 981 | Explanation: The longest possible good subarray is [1,2,3,1,2,3] since the values 1, 2, and 3 occur at most twice in this subarray. Note that the subarrays [2,3,1,2,3,1] and [3,1,2,3,1,2] are also good. 982 | It can be shown that there are no good subarrays with length more than 6. 983 | ``` 984 | 985 | Example 2: 986 | 987 | ``` 988 | Input: nums = [1,2,1,2,1,2,1,2], k = 1 989 | Output: 2 990 | Explanation: The longest possible good subarray is [1,2] since the values 1 and 2 occur at most once in this subarray. Note that the subarray [2,1] is also good. 991 | It can be shown that there are no good subarrays with length more than 2. 992 | ``` 993 | 994 | Example 3: 995 | 996 | ``` 997 | Input: nums = [5,5,5,5,5,5,5], k = 4 998 | Output: 4 999 | Explanation: The longest possible good subarray is [5,5,5,5] since the value 5 occurs 4 times in this subarray. 1000 | It can be shown that there are no good subarrays with length more than 4. 1001 | ``` 1002 | 1003 | Constraints: 1004 | 1005 | - `1 <= nums.length <= 10^5` 1006 | - `1 <= nums[i] <= 10^9` 1007 | - `1 <= k <= nums.length` 1008 | 1009 | ## [Count Subarrays Where Max Element Appears at Least K Times](./count-subarrays-where-max-element-appears-at-least-k-times) 1010 | 1011 | You are given an integer array `nums` and a positive integer `k`. 1012 | Return the number of subarrays where the maximum element of `nums` appears at least `k` times in that subarray. 1013 | A subarray is a contiguous sequence of elements within an array. 1014 | 1015 | Example 1: 1016 | 1017 | ``` 1018 | Input: nums = [1,3,2,3,3], k = 2 1019 | Output: 6 1020 | Explanation: The subarrays that contain the element 3 at least 2 times are: [1,3,2,3], [1,3,2,3,3], [3,2,3], [3,2,3,3], [2,3,3] and [3,3]. 1021 | ``` 1022 | 1023 | Example 2: 1024 | 1025 | ``` 1026 | Input: nums = [1,4,2,1], k = 3 1027 | Output: 0 1028 | Explanation: No subarray contains the element 4 at least 3 times. 1029 | ``` 1030 | 1031 | Constraints: 1032 | 1033 | - `1 <= nums.length <= 10^5` 1034 | - `1 <= nums[i] <= 10^6` 1035 | - `1 <= k <= 105` 1036 | -------------------------------------------------------------------------------- /problems/beautiful-nums/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | You are given a 0-indexed integer array nums having length n, and an integer k. 3 | 4 | You can perform the following increment operation any number of times (including zero): 5 | 6 | Choose an index i in the range [0, n - 1], and increase nums[i] by 1. 7 | An array is considered beautiful if, for any subarray with a size of 3 or more, 8 | its maximum element is greater than or equal to k. 9 | 10 | Return an integer denoting the minimum number of increment operations needed to make nums beautiful. 11 | 12 | A subarray is a contiguous non-empty sequence of elements within an array. 13 | 14 | 15 | 16 | Example 1: 17 | 18 | Input: nums = [2,3,0,0,2], k = 4 19 | [i = 1, i = 1, = 4] -> [1, 4] -> [3, 2] -> 3 20 | 21012 k = 5 21 | [2, 1, 0] -> 2 -> 3 22 | [1, 0, 1] -> 1 -> 4 23 | [0, 1, 2] -> 2 -> 3 24 | Output: 3 25 | f(n-1) 26 | f(n-2) 27 | f(n-3) 28 | A = [ .... ] -> X 29 | [ A , k ] -> X 10, 4, 0,0, 10 30 | 31 | min(k - max(y, z, k), 0) 32 | [ ..... ] 33 | [a,b,c,X] 34 | x f1 35 | xx f2 f3 36 | xxxx 37 | */ 38 | 39 | package main 40 | 41 | func main() { 42 | } 43 | 44 | func f(n int, nums []int, k int) int { 45 | if n == 0 || n == 1 || n == 2 { 46 | return 0 47 | } 48 | 49 | p1 := max(k-nums[0], 0) + f(n-1, nums, k) 50 | p2 := max(k-nums[1], 0) + f(n-2, nums, k) 51 | p3 := max(k-nums[2], 0) + f(n-3, nums, k) 52 | 53 | return min(min(p1, p2), p3) 54 | } 55 | -------------------------------------------------------------------------------- /problems/bell-numbers/main.py: -------------------------------------------------------------------------------- 1 | import functools 2 | 3 | 4 | @functools.cache 5 | def C(n: int, k: int) -> int: 6 | """ 7 | the number of combinations of k objects from a set with n objects. 8 | """ 9 | if k == 0: 10 | return 1 11 | if k == 1: 12 | return n 13 | if k == n: 14 | return 1 15 | if n - k < k: 16 | return C(n, n - k) 17 | return C(n - 1, k - 1) + C(n - 1, k) 18 | 19 | 20 | @functools.cache 21 | def bell(n: int) -> int: 22 | """ 23 | recursive formulation for the bell number, 24 | which discusses the set containing the nth element. 25 | 26 | https://en.wikipedia.org/wiki/Bell_number 27 | """ 28 | if n == 0: 29 | return 1 30 | count = 0 31 | for k in range(n): 32 | count += C(n - 1, k) * bell(k) 33 | return count 34 | 35 | 36 | if __name__ == "__main__": 37 | assert C(10, 0) == 1 38 | assert C(5, 2) == 10 39 | assert C(3, 1) == 3 40 | assert C(3, 2) == 3 41 | assert C(4, 2) == 6 42 | 43 | assert bell(2) == 2 44 | assert bell(3) == 5 45 | -------------------------------------------------------------------------------- /problems/coins/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/coins 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/coins/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | "time" 7 | ) 8 | 9 | // Coins returns all available types of coins. 10 | func Coins() []int { 11 | return []int{1, 5, 7, 10} 12 | } 13 | 14 | const one = 1 15 | 16 | // MinimumCoinsProblem solution with memorization. 17 | type MinimumCoinsProblem struct { 18 | Table map[int]int 19 | Calls int 20 | } 21 | 22 | func main() { 23 | amount := 23 24 | 25 | problem := MinimumCoinsProblem{ 26 | Table: make(map[int]int), 27 | } 28 | 29 | start := time.Now() 30 | 31 | fmt.Printf("%d needs %d coins\n", amount, problem.Minimum(amount, 0)) 32 | 33 | fmt.Printf("Execution Time: %v\n", time.Since(start)) 34 | 35 | fmt.Printf("Number of Calls: %d\n", problem.Calls) 36 | } 37 | 38 | // Minimum number of coins for n amount of money. 39 | func (p *MinimumCoinsProblem) Minimum(n, number int) int { 40 | p.Calls++ 41 | 42 | if n == 0 { 43 | return number 44 | } 45 | 46 | if val, ok := p.Table[n]; ok { 47 | return number + val 48 | } 49 | 50 | min := math.MaxInt32 51 | 52 | for _, v := range Coins() { 53 | if n < v { 54 | break 55 | } 56 | 57 | r := p.Minimum(n-v, number+one) 58 | if r < min { 59 | min = r 60 | } 61 | } 62 | 63 | p.Table[n] = min - number 64 | 65 | return min 66 | } 67 | -------------------------------------------------------------------------------- /problems/count-subarrays-where-max-element-appears-at-least-k-times/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func countSubarraysWithMax(nums []int, k int, max int) int64 { 6 | if len(nums) < k { 7 | return 0 8 | } 9 | 10 | firstMaxIndex := -1 11 | i := 0 12 | for firstMaxIndex == -1 { 13 | if i == len(nums) { 14 | return 0 15 | } 16 | if nums[i] == max { 17 | firstMaxIndex = i 18 | } 19 | i++ 20 | } 21 | 22 | c := countSubarraysWithMax(nums[firstMaxIndex+1:], k, max) 23 | 24 | n := 0 25 | lastMaxIndex := -1 26 | for i := firstMaxIndex; i < len(nums); i++ { 27 | if nums[i] == max { 28 | n++ 29 | } 30 | if n == k { 31 | lastMaxIndex = i 32 | break 33 | } 34 | } 35 | 36 | if lastMaxIndex == -1 { 37 | return c 38 | } 39 | 40 | return c + int64(firstMaxIndex+1)*int64(len(nums)-lastMaxIndex) 41 | } 42 | 43 | func countSubarrays(nums []int, k int) int64 { 44 | max := -1 45 | for _, n := range nums { 46 | if n > max { 47 | max = n 48 | } 49 | } 50 | 51 | return countSubarraysWithMax(nums, k, max) 52 | } 53 | 54 | func main() { 55 | tests := []struct { 56 | nums []int 57 | k int 58 | answer int64 59 | }{ 60 | { 61 | nums: []int{1, 3, 2, 3, 3}, 62 | k: 2, 63 | answer: 6, 64 | }, 65 | { 66 | nums: []int{1, 4, 2, 1}, 67 | k: 3, 68 | answer: 0, 69 | }, 70 | } 71 | 72 | for _, t := range tests { 73 | if t.answer != countSubarrays(t.nums, t.k) { 74 | fmt.Printf("The number of subarrays should be %d but it is %d for %v %d\n", 75 | t.answer, 76 | countSubarrays(t.nums, t.k), 77 | t.nums, 78 | t.k, 79 | ) 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /problems/decode-string/main.py: -------------------------------------------------------------------------------- 1 | def evaluate(expr: str) -> str: 2 | current_expr = "" 3 | string = "" 4 | i = 0 5 | numbers_stack = [] 6 | strings_stack = [] 7 | 8 | while i < len(expr): 9 | # print(f"expr: {expr}, string: {string}, at i {i}: {expr[i]}") 10 | 11 | if (current_expr + expr[i]).isnumeric(): 12 | current_expr += expr[i] 13 | elif current_expr != "": 14 | number = int(current_expr) 15 | numbers_stack.insert(0, number) 16 | current_expr = expr[i] 17 | else: 18 | current_expr = expr[i] 19 | 20 | if current_expr == "[": 21 | strings_stack.insert(0, string) 22 | string = "" 23 | current_expr = "" 24 | elif current_expr == "]": 25 | number = numbers_stack.pop(0) 26 | string *= number 27 | string = strings_stack.pop(0) + string 28 | current_expr = "" 29 | elif current_expr.isalpha(): 30 | string += current_expr 31 | current_expr = "" 32 | 33 | i += 1 34 | 35 | return string 36 | 37 | 38 | if __name__ == "__main__": 39 | cases = [ 40 | ("ab3[a]2[bc]", "abaaabcbc"), 41 | ("3[3[a]]", "aaaaaaaaa"), 42 | ("3[a2[c]]", "accaccacc"), 43 | ] 44 | 45 | for case in cases: 46 | assert evaluate(case[0]) == case[1] 47 | -------------------------------------------------------------------------------- /problems/diagonal-traverse/main.go: -------------------------------------------------------------------------------- 1 | // Given an MxN matrix, write code which prints out the diagonals (from upper right to lower left) 2 | // of the matrix. In this example where M = 4, N = 3: 3 | // {{9, 3, 2}, 4 | // {8, 6, 1}, 5 | // {5, 5, 6}, 6 | // {1, 2, 8}} 7 | 8 | // Your code should print out: 9 | // 9 10 | // 3 8 11 | // 2 6 5 12 | // 1 5 1 13 | // 6 2 14 | // 8 15 | 16 | package main 17 | 18 | import "fmt" 19 | 20 | type tuple struct { 21 | x int 22 | y int 23 | } 24 | 25 | func main() { 26 | arr := [][]int{ 27 | {9, 3, 2}, 28 | {8, 6, 1}, 29 | {5, 5, 6}, 30 | {1, 2, 8}, 31 | } 32 | M := len(arr) 33 | N := len(arr[0]) 34 | 35 | diags := make([]tuple, 0) 36 | 37 | for i := 0; i < N; i++ { 38 | diags = append(diags, tuple{0, i}) 39 | } 40 | for i := 1; i < M; i++ { 41 | diags = append(diags, tuple{i, N - 1}) 42 | } 43 | 44 | for _, t := range diags { 45 | i, j := t.x, t.y 46 | for i < M && j >= 0 { 47 | fmt.Printf("%d ", arr[i][j]) 48 | j-- 49 | i++ 50 | } 51 | fmt.Println() 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /problems/excel-sheet-column-title/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func convertToTitle(columnNumber int) string { 6 | if columnNumber == 0 { 7 | return "" 8 | } 9 | r := columnNumber % 26 10 | r = (r + 25) % 26 11 | return convertToTitle((columnNumber-1)/26) + string(byte('A'+r)) 12 | } 13 | 14 | func main() { 15 | tests := []struct { 16 | columnNumber int 17 | columnName string 18 | }{ 19 | { 20 | columnNumber: 701, 21 | columnName: "ZY", 22 | }, 23 | { 24 | columnNumber: 1, 25 | columnName: "A", 26 | }, 27 | { 28 | columnNumber: 26, 29 | columnName: "Z", 30 | }, 31 | { 32 | columnNumber: 27, 33 | columnName: "AA", 34 | }, 35 | } 36 | 37 | for _, t := range tests { 38 | if t.columnName != convertToTitle(t.columnNumber) { 39 | fmt.Printf("Column number %d should be converted to %s but it converted to %s", 40 | t.columnNumber, 41 | t.columnName, 42 | convertToTitle(t.columnNumber), 43 | ) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /problems/find-all-duplicates-in-an-array/main.py: -------------------------------------------------------------------------------- 1 | def find_duplicates(nums: list[int]) -> list[int]: 2 | result = [] 3 | for i in range(len(nums)): 4 | index = abs(nums[i]) - 1 5 | if nums[index] > 0: 6 | nums[index] = -nums[index] 7 | else: 8 | result.append(abs(nums[i])) 9 | return result 10 | 11 | 12 | if __name__ == "__main__": 13 | assert find_duplicates([1, 1, 2, 2]) == [1, 2] 14 | assert find_duplicates([1, 2, 3, 4]) == [] 15 | assert find_duplicates([1, 2, 2, 4]) == [2] 16 | -------------------------------------------------------------------------------- /problems/find-all-groups-of-farmland/main.py: -------------------------------------------------------------------------------- 1 | def find_farmland(land: list[list[int]]) -> list[list[int]]: 2 | n = len(land) 3 | m = len(land[0]) 4 | 5 | farms = [] 6 | 7 | for r in range(n): 8 | for c in range(m): 9 | if land[r][c] == 1: 10 | length = 1 11 | org = (r, c) 12 | dst = (r, c) 13 | 14 | land[r][c] = 0 15 | 16 | while True: 17 | i, j = org 18 | if ( 19 | i + length < n 20 | and j + length < m 21 | and {land[i + k][j + length] for k in range(length + 1)} == {1} 22 | and {land[i + length][j + k] for k in range(length + 1)} == {1} 23 | ): 24 | dst = (i + length, j + length) 25 | 26 | for k in range(length + 1): 27 | land[i + k][j + length] = 0 28 | 29 | for k in range(length + 1): 30 | land[i + length][j + k] = 0 31 | 32 | length += 1 33 | else: 34 | break 35 | 36 | while True: 37 | i, _ = org 38 | _, j = dst 39 | 40 | if j + 1 < m and {land[i + k][j + 1] for k in range(length)} == {1}: 41 | for k in range(length): 42 | land[i + k][j + 1] = 0 43 | 44 | dst = (dst[0], dst[1] + 1) 45 | else: 46 | break 47 | 48 | while True: 49 | _, j = org 50 | i, _ = dst 51 | 52 | if i + 1 < n and {land[i + 1][j + k] for k in range(length)} == {1}: 53 | for k in range(length): 54 | land[i + 1][j + k] = 0 55 | 56 | dst = (dst[0] + 1, dst[1]) 57 | else: 58 | break 59 | 60 | farms.append( 61 | [ 62 | *org, 63 | *dst, 64 | ] 65 | ) 66 | 67 | return farms 68 | 69 | 70 | if __name__ == "__main__": 71 | assert find_farmland([[1, 0, 0], [0, 1, 1], [0, 1, 1]]) == [ 72 | [0, 0, 0, 0], 73 | [1, 1, 2, 2], 74 | ], find_farmland([[1, 0, 0], [0, 1, 1], [0, 1, 1]]) 75 | 76 | assert find_farmland([[1, 1], [1, 1]]) == [[0, 0, 1, 1]], find_farmland( 77 | [[1, 1], [1, 1]] 78 | ) 79 | 80 | assert find_farmland([[1, 1, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0]]) == [ 81 | [0, 0, 1, 1], 82 | [0, 5, 0, 5], 83 | ], find_farmland([[1, 1, 0, 0, 0, 1], [1, 1, 0, 0, 0, 0]]) 84 | -------------------------------------------------------------------------------- /problems/first-missing-positive/main.py: -------------------------------------------------------------------------------- 1 | def first_missing_positive(nums: list[int]) -> int: 2 | """ 3 | Use the same array to mark numbers that we seen. 4 | By marking, I mean converting them into the negative number, 5 | for example when I see 4, I convert nums[3] to negative and 6 | this will indicates we have 4 in our array. 7 | """ 8 | 9 | # by converting negative and zero numbers 10 | # to big enough positive numbers we remove 11 | # them from our algorithm. 12 | for i in range(len(nums)): 13 | if nums[i] == 0: 14 | nums[i] = len(nums) + 1 15 | elif nums[i] < 0: 16 | nums[i] = len(nums) + 1 17 | 18 | sp = 1 19 | 20 | for i in range(len(nums)): 21 | if sp == abs(nums[i]): 22 | sp += 1 23 | while sp <= len(nums) and nums[sp - 1] < 0: 24 | sp += 1 25 | index = abs(nums[i]) - 1 26 | if index < len(nums) and nums[index] > 0: 27 | nums[index] *= -1 28 | return sp 29 | 30 | 31 | if __name__ == "__main__": 32 | assert first_missing_positive([1, 2, 0]) == 3 33 | assert first_missing_positive([3, 4, -1, 1]) == 2 34 | assert first_missing_positive([7, 8, 9, 11, 12]) == 1 35 | assert first_missing_positive([2, 1, 3, 4, 4, 3, 1, 1]) == 5 36 | -------------------------------------------------------------------------------- /problems/generate-ipv4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | GenerateIPv4([]int{0, 1, 0, 0, 0, 0}) // 0.100.0.0 7 | } 8 | 9 | // nums = [1,2,3,4] 10 | // GenerateIPv4 -> Return all IPV4 that can be generated. 11 | // 0-255 x 4 12 | // [1,2,3,4] -> 1.2.3.4 This is the only example that can be generated. 13 | // [1,2,1,2,2,3,1,2,3] -> 121.223.12.3, 121.223.1.23, 12.122.31.23, etc... 14 | // 0 <= n <= 9 15 | // - All number must used. 16 | // 0,0,0,0,0 -> 0.0.0.0 17 | // 0,1,0,0,0,0 -> 0.100.0.0 18 | // 01.00.0.0 19 | // 0.1.0.0, 0.10.0.0 20 | 21 | func sliceToNum(num []int) (int, bool) { 22 | n := len(num) 23 | s := 0 24 | 25 | leadingZero := false 26 | if num[0] == 0 && n > 1 { 27 | leadingZero = true 28 | } 29 | 30 | for i := 0; i < n; i++ { 31 | s = s*10 + num[i] 32 | } 33 | 34 | return s, leadingZero 35 | } 36 | 37 | func GenerateIPv4(nums []int) { 38 | n := len(nums) 39 | 40 | // O(n ^ 3) 41 | // if we consider 10^6 is the most instructions that we can run in 1 seconds 42 | // we only can handle 100 elements in our input during 1 second. 43 | for i := 1; i < n; i++ { 44 | for j := i + 1; j < n; j++ { 45 | for k := j + 1; k < n; k++ { 46 | p1, l1 := sliceToNum(nums[:i]) 47 | p2, l2 := sliceToNum(nums[i:j]) 48 | p3, l3 := sliceToNum(nums[j:k]) 49 | p4, l4 := sliceToNum(nums[k:]) 50 | 51 | if l1 || l2 || l3 || l4 { 52 | continue 53 | } 54 | 55 | if p1 >= 0 && p1 <= 255 && p2 >= 0 && p2 <= 255 && p3 >= 0 && p3 <= 255 && p4 >= 0 && p4 <= 255 { 56 | fmt.Printf("%d.%d.%d.%d\n", p1, p2, p3, p4) 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /problems/generate-parentheses/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/generate-parentheses 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/generate-parentheses/main.py: -------------------------------------------------------------------------------- 1 | def generate(n) -> list[str]: 2 | if n == 0: 3 | return [] 4 | if n == 1: 5 | return ["()"] 6 | 7 | res = [] 8 | for i in range(n): 9 | inner = generate(n - 1 - i) 10 | outer = generate(i) 11 | 12 | if len(outer) > 0 and len(inner) > 0: 13 | for iparn in inner: 14 | for oparn in outer: 15 | res.append(f"({iparn}){oparn}") 16 | elif len(outer) > 0: 17 | for oparn in outer: 18 | res.append(f"(){oparn}") 19 | elif len(inner) > 0: 20 | for iparn in inner: 21 | res.append(f"({iparn})") 22 | return res 23 | 24 | 25 | if __name__ == "__main__": 26 | assert generate(1) == ["()"] 27 | assert generate(3) == ["((()))", "(()())", "(())()", "()(())", "()()()"] 28 | -------------------------------------------------------------------------------- /problems/jump-game/main.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def jumpOver(self, nums: List[int]) -> bool: 6 | for i in range(len(nums)): 7 | if nums[i] > len(nums) - i: 8 | return True 9 | return False 10 | 11 | def canJump(self, nums: List[int]) -> bool: 12 | if len(nums) == 1: 13 | return True 14 | for i in range(len(nums) - 1): 15 | if nums[i] == 0: 16 | if not self.jumpOver(nums[:i]): 17 | return False 18 | 19 | return True 20 | 21 | 22 | print(Solution().canJump([2,0,0])) 23 | -------------------------------------------------------------------------------- /problems/k-nearest-neighbour/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | type Point struct { 9 | X float64 10 | Y float64 11 | } 12 | 13 | type PointsByDist struct { 14 | Points []Point 15 | ReferencePoint Point 16 | } 17 | 18 | func (p PointsByDist) Len() int { 19 | return len(p.Points) 20 | } 21 | 22 | func (p PointsByDist) Less(i, j int) bool { 23 | d1 := (p.Points[i].X-p.ReferencePoint.X)*(p.Points[i].X-p.ReferencePoint.X) + (p.Points[i].Y-p.ReferencePoint.Y)*(p.Points[i].Y-p.ReferencePoint.Y) 24 | d2 := (p.Points[j].X-p.ReferencePoint.X)*(p.Points[j].X-p.ReferencePoint.X) + (p.Points[j].Y-p.ReferencePoint.Y)*(p.Points[j].Y-p.ReferencePoint.Y) 25 | 26 | return d1 < d2 27 | } 28 | 29 | func (p PointsByDist) Swap(i, j int) { 30 | p.Points[i], p.Points[j] = p.Points[j], p.Points[i] 31 | } 32 | 33 | func main() { 34 | startingPoint := Point{3.0, 4.0} 35 | 36 | candidatePoints := []Point{ 37 | {12.0, 18.0}, 38 | {2.0, 5.0}, 39 | {6.0, 9.0}, 40 | {21.0, 14.0}, 41 | {15.0, 19.0}, 42 | } 43 | 44 | k := 3 45 | 46 | pd := PointsByDist{Points: candidatePoints, ReferencePoint: startingPoint} 47 | 48 | sort.Sort(pd) 49 | 50 | for _, p := range pd.Points[:k] { 51 | fmt.Println(p) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /problems/kadanes-algorithm/main.py: -------------------------------------------------------------------------------- 1 | def maximum_sequence(arr: list[int]) -> int: 2 | n = len(arr) 3 | if n == 0: 4 | return 0 5 | 6 | # d[i] contains the largest continues sequence that ends 7 | # with arr[i] 8 | d = [0 for _ in range(n)] 9 | d[0] = arr[0] 10 | for i in range(1, n): 11 | d[i] = max(d[i - 1] + arr[i], arr[i]) 12 | 13 | max_sum = d[0] 14 | for i in range(n): 15 | max_sum = max(max_sum, d[i]) 16 | return max_sum 17 | 18 | 19 | if __name__ == "__main__": 20 | assert maximum_sequence([1, 2, 3, -2, 5]) == 9 21 | assert maximum_sequence([-1, -2, -3, -4]) == -1 22 | -------------------------------------------------------------------------------- /problems/knn/main.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | import numpy as np 4 | import pandas as pd 5 | 6 | 7 | def dist(X: pd.Series, Y: pd.Series): 8 | return math.dist(X, Y) 9 | 10 | 11 | class KNN: 12 | def __init__(self, database: pd.DataFrame, k: int): 13 | self.database = database 14 | self.k = k 15 | 16 | def predict(self, req: pd.Series) -> pd.DataFrame: 17 | self.database["distance"] = self.database.apply(lambda x: dist(x, req), axis=1) 18 | k_nearest_neighbours = self.database.iloc[ 19 | np.argpartition(self.database["distance"], self.k - 1)[: self.k] 20 | ] 21 | 22 | return k_nearest_neighbours 23 | 24 | 25 | if __name__ == "__main__": 26 | data = pd.DataFrame([[1, 2], [3, 2], [5, 4], [3, 1], [6, 3], [8, 4]]) 27 | 28 | knn = KNN(data, 3) 29 | 30 | req = pd.Series([5, 5]) 31 | print(knn.predict(req)) 32 | -------------------------------------------------------------------------------- /problems/length-of-longest-subarray-with-at-most-k-frequency/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func maxSubarrayLength(nums []int, k int) int { 6 | length := 0 7 | 8 | start := 0 9 | end := 0 10 | 11 | frequency := map[int]int{} 12 | 13 | for start != len(nums) { 14 | for { 15 | frequency[nums[end]] += 1 16 | if frequency[nums[end]] <= k { 17 | if end-start+1 > length { 18 | length = end - start + 1 19 | } 20 | } else { 21 | break 22 | } 23 | if end < len(nums)-1 { 24 | end += 1 25 | } 26 | } 27 | 28 | start += 1 29 | if start == len(nums) { 30 | break 31 | } 32 | frequency[nums[start-1]] -= 1 33 | frequency[nums[end]] -= 1 34 | } 35 | 36 | return length 37 | } 38 | 39 | func main() { 40 | tests := []struct { 41 | nums []int 42 | k int 43 | answer int 44 | }{ 45 | { 46 | nums: []int{1, 2, 3, 1, 2, 3, 1, 2}, 47 | k: 2, 48 | answer: 6, 49 | }, { 50 | nums: []int{1, 4, 4, 3}, 51 | k: 1, 52 | answer: 2, 53 | }, 54 | } 55 | 56 | for _, t := range tests { 57 | if maxSubarrayLength(t.nums, t.k) != t.answer { 58 | fmt.Printf("maximum length should be %d for %v and %d but it is %d\n", 59 | t.answer, 60 | t.nums, 61 | t.k, 62 | maxSubarrayLength(t.nums, t.k), 63 | ) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /problems/longest-palindrome/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/longest-palindrome 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /problems/longest-palindrome/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(longestpalindrome("babad")) 7 | } 8 | 9 | func longestpalindrome(s string) string { 10 | lognest := 0 11 | sub := "" 12 | 13 | for i := 0; i < len(s); i++ { 14 | for j := i; j <= len(s); j++ { 15 | if j-i > lognest && isPalindrome(s[i:j]) { 16 | lognest = j - i 17 | sub = s[i:j] 18 | } 19 | } 20 | } 21 | 22 | return sub 23 | } 24 | 25 | func isPalindrome(s string) bool { 26 | if len(s) == 0 { 27 | return false 28 | } 29 | 30 | for i := 0; i <= len(s)/2; i++ { 31 | if s[i] != s[len(s)-1-i] { 32 | return false 33 | } 34 | } 35 | return true 36 | } 37 | -------------------------------------------------------------------------------- /problems/longest-palindrome/main.py: -------------------------------------------------------------------------------- 1 | def longest_palindromic_substring(s): 2 | """ 3 | Return lognest plandromic substring. 4 | """ 5 | if len(s) == 0: 6 | return "" 7 | 8 | lg = len(s) 9 | res = s[0] 10 | for j in range(2): 11 | offset = 0 12 | candidate = "" 13 | i = 0 14 | while i + j < lg: 15 | # When j is 0, the following condition is obvious and in case 16 | # of 1 it causes moving on when two neighbor cells are equal. 17 | if s[i] != s[i + j]: 18 | i += 1 19 | continue 20 | 21 | if ( 22 | i - offset >= 0 23 | and i + j + offset < lg 24 | and s[i - offset] == s[i + j + offset] 25 | ): 26 | candidate = s[i - offset : i + j + offset + 1] 27 | offset += 1 28 | else: 29 | i += 1 30 | if len(candidate) > len(res): 31 | res = candidate 32 | offset = 0 33 | candidate = "" 34 | 35 | return res 36 | 37 | 38 | if __name__ == "__main__": 39 | assert longest_palindromic_substring("babad") == "bab" 40 | assert longest_palindromic_substring("cbbd") == "bb" 41 | assert longest_palindromic_substring("bb") == "bb" 42 | -------------------------------------------------------------------------------- /problems/longest-palindrome/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func Test(t *testing.T) { 6 | cases := []struct { 7 | input string 8 | output string 9 | }{ 10 | { 11 | input: "babad", 12 | output: "bab", 13 | }, 14 | { 15 | input: "cbbd", 16 | output: "bb", 17 | }, 18 | } 19 | 20 | for _, c := range cases { 21 | o := longestpalindrome(c.input) 22 | if o != c.output { 23 | t.Fail() 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /problems/longest-palindromic-substring/main.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestOddPalindrome(self, s): 3 | res = "" 4 | for i in range(len(s)): 5 | r = s[i] 6 | for d in range(min(len(s) - i, i + 1)): 7 | if s[i - d] != s[i + d]: 8 | break 9 | 10 | r = s[i - d:i + d + 1] 11 | 12 | if len(r) > len(res): 13 | res = r 14 | 15 | return res 16 | 17 | def longestEvenPalindrome(self, s): 18 | res = "" 19 | r = "" 20 | for i in range(len(s) - 1): 21 | if s[i] == s[i + 1]: 22 | r = s[i: i + 2] 23 | for d in range(min(len(s) - i - 2, i) + 1): 24 | if s[i - d] != s[i + d + 1]: 25 | break 26 | 27 | r = s[i - d:i + d + 2] 28 | 29 | if len(r) > len(res): 30 | res = r 31 | 32 | return res 33 | 34 | def longestPalindrome(self, s: str) -> str: 35 | ro = self.longestOddPalindrome(s) 36 | re = self.longestEvenPalindrome(s) 37 | 38 | return ro if len(ro) > len(re) else re 39 | 40 | 41 | r = Solution().longestPalindrome("babad") 42 | print(r) 43 | -------------------------------------------------------------------------------- /problems/longest-valid-parentheses/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/longest-valid-parentheses 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/longest-valid-parentheses/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | cases := []struct { 7 | input string 8 | output int 9 | }{ 10 | { 11 | input: "(()", 12 | output: 2, 13 | }, 14 | { 15 | input: ")()())", 16 | output: 4, 17 | }, 18 | } 19 | 20 | for _, c := range cases { 21 | if longestValidParentheses(c.input) != c.output { 22 | fmt.Printf("there output should be %d for %q\n", c.output, c.input) 23 | } else { 24 | fmt.Printf("%q passed successfully\n", c.input) 25 | } 26 | } 27 | } 28 | 29 | func longestValidParentheses(s string) int { 30 | longest_seq := 0 31 | 32 | for j := 0; j < len(s); j++ { 33 | current_seq := 0 34 | current_state := 0 35 | 36 | for i := j; i < len(s); i++ { 37 | current_seq += 1 38 | if s[i] == '(' { 39 | current_state += 1 40 | } else { 41 | current_state -= 1 42 | } 43 | if current_state == 0 { 44 | if longest_seq < current_seq { 45 | longest_seq = current_seq 46 | } 47 | } 48 | if current_state < 0 { 49 | current_state = 0 50 | current_seq = 0 51 | } 52 | } 53 | } 54 | 55 | return longest_seq 56 | } 57 | -------------------------------------------------------------------------------- /problems/longest_common_prefix/main.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | 3 | def myLongestCommonPrefix(self, strs) -> str: 4 | m = {} 5 | for s in strs: 6 | if m.get(s[0]) is None: 7 | m[s[0]] = 1 8 | else: 9 | m[s[0]] = m[s[0]] + 1 10 | 11 | maxValue = 0 12 | max_key = "" 13 | 14 | for k, v in m.items(): 15 | if v > maxValue: 16 | maxValue = v 17 | max_key = k 18 | 19 | if maxValue == 1: 20 | return "" 21 | 22 | new_strs = [] 23 | for s in strs: 24 | if s[0] == max_key: 25 | new_strs.append(s[1:]) 26 | 27 | if len(new_strs) < len(strs): 28 | return "" 29 | 30 | return max_key + self.myLongestCommonPrefix(new_strs) 31 | 32 | def longestCommonPrefix(self, strs) -> str: 33 | m = {} 34 | for s in strs: 35 | if m.get(s[0]) is None: 36 | m[s[0]] = 1 37 | else: 38 | m[s[0]] = m[s[0]] + 1 39 | 40 | maxValue = 0 41 | max_key = "" 42 | 43 | for k, v in m.items(): 44 | if v > maxValue: 45 | maxValue = v 46 | max_key = k 47 | 48 | if maxValue == 1: 49 | return "" 50 | 51 | new_strs = [] 52 | for s in strs: 53 | if s[0] == max_key: 54 | new_strs.append(s[1:]) 55 | 56 | if len(new_strs) < len(strs): 57 | return "" 58 | 59 | return max_key + self.myLongestCommonPrefix(new_strs) 60 | 61 | 62 | s = Solution() 63 | print(s.longestCommonPrefix(["flower", "flow", "flight"])) 64 | 65 | # a = {"A": 0, "B": 1} 66 | # for k, v in a.items(): 67 | # print(k) 68 | # print(v) 69 | # if a.get("A") == None: 70 | # print("hi") 71 | -------------------------------------------------------------------------------- /problems/merge-k-sorted-lists/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/merge-k-sorted-lists 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/merge-k-sorted-lists/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "math" 4 | 5 | type ListNode struct { 6 | Val int 7 | Next *ListNode 8 | } 9 | 10 | func mergeKLists(lists []*ListNode) *ListNode { 11 | var head *ListNode 12 | var it *ListNode 13 | 14 | for { 15 | 16 | minIndex := -1 17 | min := math.MaxInt 18 | 19 | for index, list := range lists { 20 | if list != nil && list.Val < min { 21 | min = list.Val 22 | minIndex = index 23 | } 24 | } 25 | 26 | if minIndex == -1 { 27 | break 28 | } 29 | 30 | lists[minIndex] = lists[minIndex].Next 31 | 32 | node := &ListNode{ 33 | Val: min, 34 | Next: nil, 35 | } 36 | 37 | if head == nil { 38 | head = node 39 | it = node 40 | } else { 41 | it.Next = node 42 | it = node 43 | } 44 | } 45 | 46 | return head 47 | } 48 | -------------------------------------------------------------------------------- /problems/merge/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/merge 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/merge/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | f := []int{-1} 7 | s := []int{-2, -2} 8 | 9 | fmt.Println(sort(f, s)) 10 | } 11 | 12 | func sort(first []int, second []int) []int { 13 | result := make([]int, 0) 14 | fIndex, sIndex := 0, 0 15 | 16 | for { 17 | if fIndex == len(first) { 18 | result = append(result, second[sIndex:]...) 19 | 20 | break 21 | } else if sIndex == len(second) { 22 | result = append(result, first[fIndex:]...) 23 | 24 | break 25 | } 26 | 27 | if first[fIndex] <= second[sIndex] { 28 | result = append(result, first[fIndex]) 29 | fIndex++ 30 | } else { 31 | result = append(result, second[sIndex]) 32 | sIndex++ 33 | } 34 | } 35 | 36 | return result 37 | } 38 | -------------------------------------------------------------------------------- /problems/min-by-column/main.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | 4 | def min_by_column(database, col_names): 5 | # Fill the null values with zero 6 | df = database.fillna(0) 7 | 8 | # Iterate over the list of column names by order 9 | for col_name in col_names: 10 | # Shrink the DF by the min value for col_name 11 | df = df[df[col_name] == df[col_name].min()] 12 | 13 | # I just one row has remained we can return it 14 | if len(df) == 1: 15 | return df.iloc[0].to_dict() 16 | 17 | # It iteration over all column names has been finished we can just return the first row 18 | return df.iloc[0].to_dict() 19 | 20 | 21 | table_1 = pd.DataFrame([1, 2, 3], columns=["a"]) 22 | # print(min_by_column(table_1, ["a"])) 23 | assert min_by_column(table_1, ["a"]) == {"a": 1} 24 | 25 | table_2 = pd.DataFrame([[1, 2], [3, 0]], columns=["a", "b"]) 26 | # print(min_by_column(table_2, "b")) 27 | assert min_by_column(table_2, "b") == {"a": 3, "b": 0} 28 | 29 | table_3 = pd.DataFrame([[1, -2], [3]], columns=["a", "b"]) 30 | # print(min_by_column(table_3, "b")) 31 | assert min_by_column(table_3, "b") == {"a": 1, "b": -2} 32 | 33 | 34 | table_5 = pd.DataFrame([[1, 3], [1, 0]], columns=["x", "y"]) 35 | # print(min_by_column(table_5, ["x", "y"])) 36 | assert min_by_column(table_5, ["x", "y"]) == {"x": 1, "y": 0} 37 | 38 | table_6 = pd.DataFrame([[2, 3], [2, 1], [1, 10]], columns=["x", "y"]) 39 | # print(min_by_column(table_6, ["x", "y"])) 40 | assert min_by_column(table_6, ["x", "y"]) == {"x": 1, "y": 10} 41 | 42 | 43 | table_7 = pd.DataFrame([[3, -1, 0], [1, 10, 1], [1, 10, 0]], columns=["x", "y", "z"]) 44 | # print(min_by_column(table_7, ["x", "y", "z"])) 45 | assert min_by_column(table_7, ["x", "y", "z"]) == {"x": 1, "y": 10, "z": 0} 46 | 47 | 48 | table_8 = pd.DataFrame([[1, 2, 3], [2, 2, 2]], columns=["x", "y", "z"]) 49 | # print(min_by_column(table_8, ["x", "y", "z"])) 50 | assert min_by_column(table_8, ["x", "y", "z"]) == {"x": 1, "y": 2, "z": 3} 51 | 52 | -------------------------------------------------------------------------------- /problems/number-of-islands/main.py: -------------------------------------------------------------------------------- 1 | def num_of_islands(grid: list[list[str]]) -> int: 2 | n = len(grid) 3 | m = len(grid[0]) 4 | 5 | islands = 0 6 | 7 | for i in range(n): 8 | for j in range(m): 9 | if grid[i][j] == "1": 10 | islands += 1 11 | queue: list[tuple[int, int]] = [(i, j)] 12 | grid[i][j] = "0" 13 | 14 | while len(queue) != 0: 15 | r, c = queue.pop() 16 | if r + 1 < n: 17 | if grid[r + 1][c] == "1": 18 | queue.append((r + 1, c)) 19 | grid[r + 1][c] = "0" 20 | if r - 1 >= 0: 21 | if grid[r - 1][c] == "1": 22 | queue.append((r - 1, c)) 23 | grid[r - 1][c] = "0" 24 | if c + 1 < m: 25 | if grid[r][c + 1] == "1": 26 | queue.append((r, c + 1)) 27 | grid[r][c + 1] = "0" 28 | if c - 1 >= 0: 29 | if grid[r][c - 1] == "1": 30 | queue.append((r, c - 1)) 31 | grid[r][c - 1] = "0" 32 | 33 | return islands 34 | 35 | 36 | if __name__ == "__main__": 37 | assert ( 38 | num_of_islands( 39 | [ 40 | ["1", "1", "1", "1", "0"], 41 | ["1", "1", "0", "1", "0"], 42 | ["1", "1", "0", "0", "0"], 43 | ["0", "0", "0", "0", "0"], 44 | ] 45 | ) 46 | == 1 47 | ) 48 | 49 | assert ( 50 | num_of_islands( 51 | [ 52 | ["1", "1", "0", "0", "0"], 53 | ["1", "1", "0", "0", "0"], 54 | ["0", "0", "1", "0", "0"], 55 | ["0", "0", "0", "1", "1"], 56 | ], 57 | ) 58 | == 3 59 | ) 60 | -------------------------------------------------------------------------------- /problems/package-delivery/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "sort" 7 | ) 8 | 9 | type SortBySensors []Delivery 10 | 11 | func (a SortBySensors) Len() int { return len(a) } 12 | func (a SortBySensors) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 13 | func (a SortBySensors) Less(i, j int) bool { 14 | needed1 := a[i].GetNeededSensors() 15 | needed2 := a[j].GetNeededSensors() 16 | 17 | sum1 := 0 18 | sum2 := 0 19 | 20 | for _, sn := range SensorNames { 21 | sum1 += needed1[sn] 22 | sum2 += needed2[sn] 23 | } 24 | 25 | return sum1 < sum2 26 | } 27 | 28 | type SensorName string 29 | 30 | const ( 31 | GPS SensorName = "gps" 32 | Temp SensorName = "temp" 33 | Weight SensorName = "weight" 34 | Door SensorName = "door" 35 | ) 36 | 37 | var SensorNames = []SensorName{GPS, Temp, Weight, Door} 38 | 39 | type Delivery struct { 40 | destination string 41 | distance int 42 | } 43 | 44 | func NewDelivery(destination string, distance int) Delivery { 45 | return Delivery{ 46 | destination: destination, 47 | distance: distance, 48 | } 49 | } 50 | 51 | func (d Delivery) GetNeededSensors() map[SensorName]int { 52 | sensors := make(map[SensorName]int) 53 | 54 | if d.distance < 10 { 55 | sensors[GPS] = 1 56 | sensors[Temp] = 1 57 | } else if d.distance >= 10 && d.distance < 100 { 58 | sensors[GPS] = 1 59 | sensors[Temp] = 2 60 | sensors[Weight] = 1 61 | } else { 62 | sensors[GPS] = 2 63 | sensors[Temp] = 4 64 | sensors[Weight] = 2 65 | } 66 | 67 | return sensors 68 | } 69 | 70 | type Scheduler struct { 71 | resources map[SensorName]int 72 | } 73 | 74 | func NewScheduler(resources map[SensorName]int) Scheduler { 75 | return Scheduler{ 76 | resources: resources, 77 | } 78 | } 79 | 80 | func (s Scheduler) ScheduleDeliveries(deliveries []Delivery) []Delivery { 81 | sort.Sort(SortBySensors(deliveries)) 82 | 83 | success := make([]Delivery, 0) 84 | resources := make(map[SensorName]int) 85 | 86 | for _, sn := range SensorNames { 87 | resources[sn] = s.resources[sn] 88 | } 89 | 90 | for _, delivery := range deliveries { 91 | failed := false 92 | 93 | needed := delivery.GetNeededSensors() 94 | for _, sn := range SensorNames { 95 | if needed[sn] > resources[sn] { 96 | if sn == Weight { 97 | if (needed[sn] - resources[sn]) <= resources[Door] { 98 | resources[Door] -= (needed[sn] - resources[sn]) 99 | resources[Weight] += (needed[sn] - resources[sn]) 100 | continue 101 | } 102 | } else if sn == Temp { 103 | if (needed[sn] - resources[sn]) <= 2*resources[Door] { 104 | resources[Door] -= (needed[sn] - resources[sn]) / 2 105 | resources[Temp] += (needed[sn] - resources[sn]) / 2 106 | continue 107 | } 108 | } 109 | failed = true 110 | break 111 | } 112 | } 113 | 114 | if !failed { 115 | for _, sn := range SensorNames { 116 | resources[sn] -= needed[sn] 117 | } 118 | success = append(success, delivery) 119 | } 120 | } 121 | 122 | return success 123 | } 124 | 125 | func main() { 126 | { 127 | d1 := NewDelivery("NY", 7) 128 | d2 := NewDelivery("FL", 10) 129 | d3 := NewDelivery("CA", 158) 130 | 131 | m1 := d1.GetNeededSensors() 132 | 133 | if m1[GPS] != 1 { 134 | log.Fatal("GetNeededSensors is not working as expected") 135 | } 136 | if m1[Temp] != 1 { 137 | log.Fatal("GetNeededSensors is not working as expected") 138 | } 139 | 140 | fmt.Println(d2.GetNeededSensors()) 141 | fmt.Println(d3.GetNeededSensors()) 142 | } 143 | 144 | fmt.Println() 145 | 146 | { 147 | deliveryA := NewDelivery("A", 9) 148 | deliveryB := NewDelivery("B", 15) 149 | deliveryC := NewDelivery("C", 100) 150 | scheduler := NewScheduler(map[SensorName]int{GPS: 2, Temp: 4, Weight: 2}) 151 | 152 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryA, deliveryB, deliveryC})) 153 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryA, deliveryC, deliveryB})) 154 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryC, deliveryA, deliveryB})) 155 | } 156 | 157 | fmt.Println() 158 | 159 | { 160 | deliveryA := NewDelivery("A", 9) 161 | deliveryB := NewDelivery("B", 15) 162 | deliveryC := NewDelivery("C", 100) 163 | scheduler := NewScheduler(map[SensorName]int{GPS: 0, Temp: 0, Weight: 0}) 164 | 165 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryA, deliveryB, deliveryC})) 166 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryA, deliveryC, deliveryB})) 167 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryC, deliveryA, deliveryB})) 168 | } 169 | 170 | fmt.Println() 171 | 172 | { 173 | deliveryA := NewDelivery("A", 9) 174 | deliveryB := NewDelivery("B", 15) 175 | deliveryC := NewDelivery("C", 100) 176 | scheduler := NewScheduler(map[SensorName]int{GPS: 4, Temp: 4, Weight: 2, Door: 2}) 177 | 178 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryA, deliveryB, deliveryC})) 179 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryA, deliveryC, deliveryB})) 180 | fmt.Println(scheduler.ScheduleDeliveries([]Delivery{deliveryC, deliveryA, deliveryB})) 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /problems/permutation-sequence/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func factorial(n int) int { 6 | if n == 0 || n == 1 { 7 | return 1 8 | } 9 | 10 | return factorial(n-1) * n 11 | } 12 | 13 | func getPermutationWithList(nums []int, k int) string { 14 | n := len(nums) 15 | 16 | if n == 1 { 17 | return fmt.Sprintf("%d", nums[0]) 18 | } 19 | 20 | i := 0 21 | 22 | for i*factorial(n-1) < k { 23 | i++ 24 | } 25 | 26 | i-- 27 | 28 | v := nums[i] 29 | nums = append(nums[:i], nums[i+1:]...) 30 | 31 | return fmt.Sprintf("%d%s", v, getPermutationWithList(nums, k-i*factorial(n-1))) 32 | } 33 | 34 | func getPermutation(n int, k int) string { 35 | nums := make([]int, n) 36 | 37 | for i := 1; i <= n; i++ { 38 | nums[i-1] = i 39 | } 40 | 41 | return getPermutationWithList(nums, k) 42 | } 43 | 44 | func main() { 45 | fmt.Println(getPermutation(3, 3)) 46 | } 47 | -------------------------------------------------------------------------------- /problems/prefix-and-suffix-search/main.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self): 3 | self.children: dict[str, Node] = {} 4 | self.word: str | None = None 5 | self.index: int | None = None 6 | 7 | def child(self, ch: str): 8 | if len(ch) != 1: 9 | raise ValueError("ch should have only one character length") 10 | 11 | node = self.children.get(ch, None) 12 | if node is None: 13 | node = Node() 14 | self.children[ch] = node 15 | return node 16 | 17 | 18 | class Trie: 19 | def __init__(self): 20 | self.root = Node() 21 | 22 | @classmethod 23 | def __insert(cls, root: Node, word: str, actual_word: str, actual_index): 24 | if len(word) == 0: 25 | root.word = actual_word 26 | root.index = actual_index 27 | return 28 | node = root.child(word[0]) 29 | cls.__insert(node, word[1:], actual_word, actual_index) 30 | 31 | def insert(self, word: str, index: int): 32 | self.__insert(self.root, word, word, index) 33 | 34 | def traverse(self, prefix: str) -> list[Node]: 35 | return self.__traverse(self.root, prefix, []) 36 | 37 | @classmethod 38 | def __traverse(cls, root: Node, prefix: str, words: list[Node]) -> list[Node]: 39 | if len(prefix) == 0 and root.word is not None: 40 | words.append(root) 41 | if len(prefix) > 0: 42 | return cls.__traverse(root.child(prefix[0]), prefix[1:], words) 43 | for _, node in root.children.items(): 44 | cls.__traverse(node, "", words) 45 | return words 46 | 47 | def delete(self, prefix: str): 48 | nodes = self.__traverse(self.root, prefix, []) 49 | for node in nodes: 50 | if node.word is not None: 51 | node.word = None 52 | 53 | 54 | class WordFilter: 55 | def __init__(self, words: list[str]): 56 | self.pref_trie = Trie() 57 | self.suff_trie = Trie() 58 | 59 | for i, word in enumerate(words): 60 | self.pref_trie.insert(word, i) 61 | self.suff_trie.insert(word[::-1], i) 62 | 63 | def f(self, pref: str, suff: str) -> int: 64 | index = -1 65 | pref_nodes = self.pref_trie.traverse(pref) 66 | suff_nodes = self.suff_trie.traverse(suff[::-1]) 67 | 68 | pref_indecies: set[int] = set() 69 | 70 | for node in pref_nodes: 71 | if node.index is not None: 72 | pref_indecies.add(node.index) 73 | 74 | for node in suff_nodes: 75 | if node.index in pref_indecies and node.index > index: 76 | index = node.index 77 | 78 | return index 79 | 80 | 81 | if __name__ == "__main__": 82 | wf = WordFilter(["apple", "Parham"]) 83 | assert wf.f("a", "e") == 0 84 | assert wf.f("Par", "ham") == 1 85 | assert wf.f("Par", "pam") == -1 86 | -------------------------------------------------------------------------------- /problems/prefix-search/test_trie.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from trie import Trie 4 | 5 | 6 | class TestTrie(unittest.TestCase): 7 | def test_insert(self): 8 | t = Trie() 9 | t.insert("Parham") 10 | t.insert("Elahe") 11 | t.insert("Parya") 12 | t.insert("Elie") 13 | 14 | self.assertListEqual(t.traverse(""), ["Parham", "Parya", "Elahe", "Elie"]) 15 | self.assertListEqual(t.traverse("Par"), ["Parham", "Parya"]) 16 | self.assertListEqual(t.traverse("El"), ["Elahe", "Elie"]) 17 | self.assertListEqual(t.traverse("Ela"), ["Elahe"]) 18 | self.assertListEqual(t.traverse("Eli"), ["Elie"]) 19 | self.assertListEqual(t.traverse("Ele"), []) 20 | 21 | def test_delete(self): 22 | t = Trie() 23 | t.insert("Parham") 24 | t.insert("Elahe") 25 | t.insert("Parya") 26 | t.insert("Elie") 27 | 28 | self.assertListEqual(t.traverse(""), ["Parham", "Parya", "Elahe", "Elie"]) 29 | t.delete("Par") 30 | self.assertListEqual(t.traverse(""), ["Elahe", "Elie"]) 31 | 32 | 33 | if __name__ == "__main__": 34 | unittest.main() 35 | -------------------------------------------------------------------------------- /problems/prefix-search/trie.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | 3 | 4 | class Node: 5 | def __init__(self): 6 | self.children: dict[str, Node] = {} 7 | self.word: str | None = None 8 | 9 | def child(self, ch: str) -> Node: 10 | if len(ch) != 1: 11 | raise ValueError("ch should have only one character length") 12 | 13 | node = self.children.get(ch, None) 14 | if node is None: 15 | node = Node() 16 | self.children[ch] = node 17 | return node 18 | 19 | 20 | class Trie: 21 | def __init__(self): 22 | self.root = Node() 23 | 24 | @classmethod 25 | def __insert(cls, root: Node, word: str, actual_word: str): 26 | if len(word) == 0: 27 | root.word = actual_word 28 | return 29 | node = root.child(word[0]) 30 | cls.__insert(node, word[1:], actual_word) 31 | 32 | def insert(self, word: str): 33 | self.__insert(self.root, word, word) 34 | 35 | def traverse(self, prefix: str) -> list[str]: 36 | nodes = self.__traverse(self.root, prefix, []) 37 | return [node.word for node in nodes if node.word is not None] 38 | 39 | @classmethod 40 | def __traverse(cls, root: Node, prefix: str, words: list[Node]) -> list[Node]: 41 | if len(prefix) == 0 and root.word is not None: 42 | words.append(root) 43 | if len(prefix) > 0: 44 | return cls.__traverse(root.child(prefix[0]), prefix[1:], words) 45 | for _, node in root.children.items(): 46 | cls.__traverse(node, "", words) 47 | return words 48 | 49 | def delete(self, prefix: str): 50 | nodes = self.__traverse(self.root, prefix, []) 51 | for node in nodes: 52 | if node.word is not None: 53 | node.word = None 54 | -------------------------------------------------------------------------------- /problems/print-n-bit-binary-numbers-having-more-1s-than-0s/main.py: -------------------------------------------------------------------------------- 1 | def n_bit_binaries(n: int) -> list[str]: 2 | if n == 1: 3 | return ["1"] 4 | 5 | result: list[str] = [] 6 | binaries = n_bit_binaries(n - 1) 7 | for binary in binaries: 8 | nunber_of_1s = binary.count("1") 9 | nunber_of_0s = binary.count("0") 10 | 11 | if nunber_of_1s - nunber_of_0s > 0: 12 | result.append(binary + "0") 13 | result.append(binary + "1") 14 | 15 | return sorted(result, reverse=True) 16 | 17 | 18 | if __name__ == "__main__": 19 | assert n_bit_binaries(1) == ["1"] 20 | assert n_bit_binaries(2) == ["11", "10"] 21 | assert n_bit_binaries(3) == ["111", "110", "101"] 22 | -------------------------------------------------------------------------------- /problems/search-a-2d-matrix-ii/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/search-a-2d-matrix-ii 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/search-a-2d-matrix-ii/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func searchMatrix(matrix [][]int, target int) bool { 6 | for i := 0; i < len(matrix); i++ { 7 | row := matrix[i] 8 | if j := search(row, target, 0); j != -1 { 9 | return true 10 | } 11 | } 12 | 13 | return false 14 | } 15 | 16 | func search(row []int, wanted, offset int) int { 17 | n := len(row) 18 | 19 | if n == 1 && row[0] != wanted { 20 | return -1 21 | } 22 | 23 | if row[n/2] == wanted { 24 | return offset + n/2 25 | } 26 | 27 | if row[n/2] < wanted { 28 | return search(row[n/2:], wanted, offset+n/2) 29 | } 30 | 31 | return search(row[:n/2], wanted, offset) 32 | } 33 | 34 | func main() { 35 | matrix := [][]int{{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}} 36 | wanted := 20 37 | 38 | fmt.Println(searchMatrix(matrix, wanted)) 39 | } 40 | -------------------------------------------------------------------------------- /problems/search-a-2d-matrix/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/search-a-2d-matrix 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/search-a-2d-matrix/main.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def search_matrix(self, matrix: list[list[int]], target: int) -> bool: 3 | row = self.find_row(0, len(matrix), matrix, target) 4 | if row == -1: 5 | return False 6 | return self.find_in_row(0, len(matrix[row]), matrix[row], target) 7 | 8 | @staticmethod 9 | def find_row( 10 | first_row: int, last_row: int, matrix: list[list[int]], target: int 11 | ) -> int: 12 | """ 13 | use binary search between first elements of rows to find 14 | a row that may contains the given target. 15 | """ 16 | index = (first_row + last_row) // 2 17 | 18 | if last_row < first_row or index >= len(matrix): 19 | return -1 20 | 21 | if matrix[index][0] > target: 22 | return Solution.find_row(first_row, index - 1, matrix, target) 23 | if matrix[index][-1] < target: 24 | return Solution.find_row(index + 1, last_row, matrix, target) 25 | else: 26 | return index 27 | 28 | @staticmethod 29 | def find_in_row(start: int, end: int, row: list[int], target: int) -> bool: 30 | """ 31 | use binary search in a given row to find a target. 32 | """ 33 | index = (start + end) // 2 34 | 35 | if index >= len(row) or end < start: 36 | return False 37 | 38 | if row[index] > target: 39 | return Solution.find_in_row(start, index - 1, row, target) 40 | elif row[index] == target: 41 | return True 42 | else: 43 | return Solution.find_in_row(index + 1, end, row, target) 44 | 45 | 46 | if __name__ == "__main__": 47 | matrix = [[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 60]] 48 | target = 13 49 | 50 | assert Solution().search_matrix(matrix, target) is False 51 | 52 | matrix = [[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 60]] 53 | target = 3 54 | 55 | assert Solution().search_matrix(matrix, target) is True 56 | 57 | matrix = [[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 60]] 58 | target = 11 59 | 60 | assert Solution().search_matrix(matrix, target) is True 61 | 62 | matrix = [[1]] 63 | target = 1 64 | 65 | assert Solution().search_matrix(matrix, target) is True 66 | 67 | matrix = [[1]] 68 | target = 2 69 | 70 | assert Solution().search_matrix(matrix, target) is False 71 | 72 | matrix = [[1], [3]] 73 | target = 3 74 | 75 | assert Solution().search_matrix(matrix, target) is True 76 | -------------------------------------------------------------------------------- /problems/shuffle/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/shuffle 2 | 3 | go 1.20 4 | -------------------------------------------------------------------------------- /problems/shuffle/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | ) 7 | 8 | func main() { 9 | // in the following example my code will answer wrongly whether using shuffle or not 10 | a := []int{1, 1, 2, 2, 3, 3, 4, 4} 11 | k := 4 12 | 13 | sa := Shuffle(a) 14 | r := Partition(sa, k) 15 | fmt.Println(r) 16 | } 17 | 18 | // Shuffle shuffles a copy of given array in-place. 19 | func Shuffle(arr []int) []int { 20 | result := make([]int, len(arr)) 21 | 22 | copy(result, arr) 23 | 24 | for i := 0; i < len(result); i++ { 25 | // nolint: gosec 26 | j := rand.Intn(len(result)-i) + i 27 | result[i], result[j] = result[j], result[i] 28 | } 29 | 30 | return result 31 | } 32 | 33 | // Partition partions a copy of given array into k equal size sub arrays. 34 | func Partition(arr []int, k int) [][]int { 35 | result := make([][]int, k) 36 | 37 | n := len(arr) 38 | l := n / k 39 | 40 | for i := 0; i < k; i++ { 41 | result[i] = make([]int, l) 42 | copy(result[i], arr[i*l:(i+1)*l]) 43 | } 44 | 45 | return result 46 | } 47 | -------------------------------------------------------------------------------- /problems/shuffle/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestShuffle(t *testing.T) { 6 | cases := []struct { 7 | input []int 8 | }{ 9 | { 10 | input: []int{1, 2, 3}, 11 | }, 12 | { 13 | input: []int{1, 1, 1}, 14 | }, 15 | { 16 | input: []int{1, 1, 2, 2}, 17 | }, 18 | } 19 | 20 | for _, c := range cases { 21 | o := Shuffle(c.input) 22 | m := make(map[int]int) 23 | 24 | for _, v := range c.input { 25 | m[v]++ 26 | } 27 | 28 | for _, v := range o { 29 | m[v]-- 30 | } 31 | 32 | for _, v := range m { 33 | if v != 0 { 34 | t.Fail() 35 | } 36 | } 37 | } 38 | } 39 | 40 | func TestPartition(t *testing.T) { 41 | cases := []struct { 42 | input []int 43 | k int 44 | expected [][]int 45 | }{ 46 | { 47 | input: []int{1, 2, 3}, 48 | k: 1, 49 | expected: [][]int{{1, 2, 3}}, 50 | }, 51 | { 52 | input: []int{1, 1, 1}, 53 | k: 3, 54 | expected: [][]int{{1}, {1}, {1}}, 55 | }, 56 | { 57 | input: []int{1, 1, 2, 2}, 58 | k: 2, 59 | expected: [][]int{{1, 1}, {2, 2}}, 60 | }, 61 | } 62 | 63 | for _, c := range cases { 64 | o := Partition(c.input, c.k) 65 | 66 | if len(o) != len(c.expected) { 67 | t.Fail() 68 | } 69 | 70 | for i := range o { 71 | for j := range o[i] { 72 | if o[i][j] != c.expected[i][j] { 73 | t.Fail() 74 | } 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /problems/shuffler/main.go: -------------------------------------------------------------------------------- 1 | /** 2 | """ 3 | Implement a music shuffling data structure with a Shuffle() method 4 | 5 | Inputs: 6 | 1. List of N integers representing songs 7 | 2. Integer K < N, representing the cooldown for a song after each shuffle 8 | 9 | The Shuffle method should randomly pick a song from the songs list. 10 | After a song is picked, it should not be picked again for the next K shuffles. 11 | 12 | 13 | Example: 14 | [1, 2, 3, 4, 5] 15 | 2 16 | 17 | > s = Shuffler([1,2,3,4,5], 2) 18 | > s.shuffle() -> 1 19 | > s.shuffle() -> 3 20 | > s.shuffle() -> 2 21 | > s.shuffle() -> 1 22 | """ 23 | 24 | 25 | **/ 26 | 27 | package main 28 | 29 | import ( 30 | "fmt" 31 | "math/rand" 32 | "time" 33 | ) 34 | 35 | func main() { 36 | s := NewShuffler([]int{1, 2, 3, 4, 5}, 2) 37 | fmt.Println(s.Shuffle()) 38 | fmt.Println(s.Shuffle()) 39 | fmt.Println(s.Shuffle()) 40 | fmt.Println(s.Shuffle()) 41 | fmt.Println(s.Shuffle()) 42 | fmt.Println(s.Shuffle()) 43 | } 44 | 45 | type Shuffler struct { 46 | songs []int 47 | picked []int 48 | k int 49 | rnd *rand.Rand 50 | } 51 | 52 | func NewShuffler(songs []int, k int) *Shuffler { 53 | return &Shuffler{ 54 | songs: songs, 55 | picked: make([]int, len(songs)), 56 | k: k, 57 | rnd: rand.New(rand.NewSource(time.Now().Unix())), 58 | } 59 | } 60 | 61 | func (s *Shuffler) Shuffle() int { 62 | c := s.rnd.Intn(len(s.songs)) 63 | 64 | for s.picked[c] > 0 { 65 | c = (c + 1) % len(s.songs) 66 | } 67 | 68 | for i := 0; i < len(s.songs); i++ { 69 | if s.picked[i] > 0 { 70 | s.picked[i]-- 71 | } 72 | } 73 | 74 | s.picked[c] = s.k 75 | 76 | return s.songs[c] 77 | } 78 | -------------------------------------------------------------------------------- /problems/sort-colors/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/1995parham-teaching/interviews/problems/sort-colors 2 | 3 | go 1.21.1 4 | -------------------------------------------------------------------------------- /problems/sort-colors/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func sortColors(nums []int) { 4 | var colors [3]int 5 | 6 | for _, c := range nums { 7 | colors[c] += 1 8 | } 9 | 10 | for i := 0; i < colors[0]; i++ { 11 | nums[i] = 0 12 | } 13 | 14 | for i := colors[0]; i < colors[0]+colors[1]; i++ { 15 | nums[i] = 1 16 | } 17 | 18 | for i := colors[0] + colors[1]; i < colors[0]+colors[1]+colors[2]; i++ { 19 | nums[i] = 2 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /problems/sort-integers-by-the-number-of-1-bits/main.py: -------------------------------------------------------------------------------- 1 | def number_of_1_bits(n: int) -> tuple[int, int]: 2 | input = n 3 | ones = 0 4 | while n >= 2: 5 | ones += n % 2 6 | n //= 2 7 | ones += n 8 | return (ones, input) 9 | 10 | 11 | if __name__ == "__main__": 12 | assert number_of_1_bits(4) == (1, 4) 13 | assert number_of_1_bits(7) == (3, 7) 14 | 15 | assert sorted([0, 1, 2, 3, 4, 5, 6, 7, 8], key=number_of_1_bits) == [ 16 | 0, 17 | 1, 18 | 2, 19 | 4, 20 | 8, 21 | 3, 22 | 5, 23 | 6, 24 | 7, 25 | ] 26 | assert sorted( 27 | [1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1], key=number_of_1_bits 28 | ) == [ 29 | 1, 30 | 2, 31 | 4, 32 | 8, 33 | 16, 34 | 32, 35 | 64, 36 | 128, 37 | 256, 38 | 512, 39 | 1024, 40 | ] 41 | -------------------------------------------------------------------------------- /questions/README.md: -------------------------------------------------------------------------------- 1 | # Questions 2 | 3 | These are questions that you can ask before starting the hands-on interview to make sure 4 | you are on the same page as the interviewee. 5 | 6 | ## Git 7 | 8 | These questions are here to review the candidate's knowledge of `git`. 9 | Believe it or not, there are many developers who don't know how to use `git` or Git Flow. 10 | It is better to ask these questions in a storytelling manner. Describe the situation 11 | and then ask how the candidate would solve it. 12 | 13 | - Where have you used git? 14 | - Do you understand the differences between Merge and Rebase? 15 | - Are you familiar with Git flow? 16 | - Have you used `git stash`? 17 | - Have you used `git cherry-pick`? 18 | - Have you used `git add -p ...`? 19 | - Have you used `git bisect`? 20 | - What are the differences between Git and GitHub? 21 | - What process is an alternative to merging? 22 | - How would you revert a commit that has already been pushed and made public? 23 | - Can you remember some of your most used `git` commands? 24 | 25 | ## Algorithm 26 | 27 | ### Time Complexity 28 | 29 | - Definition of Time Complexity 30 | 31 | ### Linked List 32 | 33 | - Differences between linked lists and arrays 34 | - Time complexity for accessing an element 35 | - An `ArrayList`, or dynamically resizing array, allows you to have the benefits of an array while offering flexibility in size. 36 | How do they achieve this? Consider adding `n` numbers into a `ArrayList`, what is the time complexity? 37 | 38 | ### Sort Algorithms 39 | 40 | - Do you know any sorting algorithm that has O(n)? 41 | - Which sort has the best order among the comparison sorts? 42 | - What is the difference between Merge Sort and Quick Sort? 43 | 44 | ### Greedy Algorithms 45 | 46 | ## Sessions 47 | 48 | - How does session management work in a web application, and what are the different approaches to maintaining session state? 49 | 50 | ## Operating Systems 51 | 52 | - Process vs Threads 53 | - Experience with multithreaded application programming 54 | - How can you get the list of processes on Linux (`ps`)? 55 | - Are you familiar with `grep`? 56 | - What are the process states on Linux? (If the candidate does not know the process states' names, the questioner can describe at least 3) 57 | - Ready 58 | - Running 59 | - Blocked or wait 60 | - Terminated or Completed 61 | - Zombie 62 | - What are the process states on Linux based on `htop`? 63 | - `S` for sleeping 64 | - `I` for idle (longer inactivity than sleeping on platforms that distinguish) 65 | - `R` for running 66 | - `D` for disk sleep (uninterruptible) 67 | - `Z` for zombie (waiting for parent to read its exit status) 68 | - `T` for traced or suspended (e.g by SIGTSTP) 69 | - `W` for paging 70 | - Which command would you use to check how much memory is being used by Linux? 71 | - `free -m` 72 | - `vmstat` 73 | - `top` 74 | - `htop` 75 | - `cat /proc/meminfo`. (+) 76 | - What is the difference between `. ~/file` and `~/file` 77 | - `./test.sh` runs `test.sh` as a separate program. It may happen to be a bash script, 78 | if the file `test.sh` starts with `#!/bin/bash`. But it could be something else altogether. 79 | - `. ./test.sh` executes the code of the file `test.sh` inside the running instance of bash. 80 | It works as if the content of file `test.sh` had been included textually instead of the `. ./test.sh` line. 81 | (Almost: there are a few details that differ, such as the value of `$BASH_LINENO`, and the behavior of the return built-in.) 82 | - What is the difference between `. ~/file` and `source ~/file` 83 | - Are you familiar with `systemd`? 84 | - Why you cannot write on a disk that has the required spaces? 85 | - Because of the `inode` runs out 86 | 87 | ## Networking 88 | 89 | - When I type a URL on my laptop, can you tell me what my computer does? 90 | - The browser looks up the IP address of the server hosting the website. Your browser checks its own cache, 91 | the operating system cache, a local network cache at your router, and a DNS server cache on your corporate network 92 | or at your internet service provider (ISP). 93 | If the browser cannot find the IP address in any of those cache layers, 94 | the DNS server on your corporate network or at your ISP does a recursive DNS lookup. 95 | A recursive DNS lookup asks multiple DNS servers around the Internet, 96 | which in turn ask more DNS servers for the DNS record until it is found. 97 | - Browser initiates TCP connection with the server: Packets from a client browser request get routed through the 98 | router to find the server with the IP address to connect to. Instead, many sites use a content delivery network, 99 | or CDN, to cache static and dynamic content closer to the browser. Once the browser finds the server on the Internet, 100 | it establishes a TCP connection with the server and if HTTPS is being used, 101 | a TLS handshake takes place to secure the communication. 102 | - Browser sends the HTTP request to the server. 103 | - The server processes request and sends back a response. 104 | - Browser renders the content: As the browser is parsing and rendering the HTML, 105 | it is making additional requests to 106 | get JavaScript, CSS, images, and data. It can do much of this in parallel. 107 | - How you can find the IP address of the server using its name? 108 | - What are the differences between TCP and UDP? 109 | - Flow Control vs Congestion Control 110 | - How does a PHP request flow work (How does Common Gateway Interface (CGI) works)? 111 | - Is there any restriction on the number of TCP connections for a system? 112 | - Can you explain the process of TCP three-way handshake and the significance of each step? 113 | - SYN (Synchronize) 114 | - SYN-ACK (Synchronize-Acknowledge) 115 | - ACK (Acknowledgment) 116 | 117 | ## Python/Django 118 | 119 | - Have you had any experience with optimizing Django/Python projects? 120 | - 121 | - Indexing 122 | - Pagination 123 | - Are you familiar with Django Signals? 124 | - Django includes a **signal dispatcher** which helps decoupled applications get notified when actions 125 | occur elsewhere in the framework. 126 | In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. 127 | They're especially useful when many pieces of code may be interested in the same events. 128 | - Does following code have any issue? 129 | 130 | ```python 131 | async function_name(response): 132 | data = await response.json() 133 | # insert in db 134 | ``` 135 | 136 | - What is async programming? 137 | - What is the difference between async programming and multithreaded programming? 138 | - What is the difference between FastAPI and Flask? 139 | - When can't you use async programming? When the implementation of the code is pure python (GIL) 140 | - What is the difference between the two following codes? 141 | 142 | ```python 143 | import asyncio 144 | 145 | await asyncio.sleep(10) 146 | ``` 147 | 148 | ```python 149 | import time 150 | 151 | time.sleep(10) 152 | ``` 153 | 154 | ## Golang 155 | 156 | - What are the differences between value types and reference types in Golang? 157 | - Value types 158 | - Store their data directly in the memory where the variable is allocated. 159 | - Primitive types like `int`, `float32`, `float64`, `bool`, `struct`, and `array` are **value** types in Golang. 160 | - Reference Types 161 | - Store a reference (i.e., memory address) to the actual data, which is stored on the heap. 162 | - What is the purpose of `defer` statements in Golang? 163 | - Execution Order: Multiple defer statements within a function are executed in a last-in, first-out (LIFO) order. The deferred function calls are placed on a stack, and as the surrounding function exits, the calls are executed in reverse order. 164 | 165 | ### Design and Project structure 166 | 167 | - Is there anything wrong with having more hierarchy for the Go package? 168 | - Can you discuss the ways you have for creating a URL shortener service? 169 | - Talk about [gossip](https://github.com/elahe-dastan/gossip) project and try to tell the following points: 170 | - Challenges 171 | - Mistakes/Failure 172 | - Enjoyed 173 | - What you'd do differently 174 | 175 | ### Arrays vs Slices 176 | 177 | - A `ArrayList`, or dynamically resizing array, allows you to have the benefits of an array while offering flexibility in size. 178 | How do they do this? Consider we want to add n number into `ArrayList` what is the time complexity? 179 | 180 | - Can you explain the following cases in Golang: 181 | 182 | ```go 183 | var ch1 chan int 184 | ch1 <- 1 // write on a nil channel 185 | <-ch1 // read from a nil channel 186 | 187 | ch2 := make(chan int) 188 | close(ch2) 189 | ch2 <- 1 // write on a closed channel 190 | <-ch2 // read from a closed channel 191 | ``` 192 | 193 | [Answer](https://stackoverflow.com/questions/39015602/how-does-a-non-initialized-channel-behave) 194 | 195 | - Explain the result of the following code. Is there any issue? 196 | 197 | ```go 198 | package main 199 | 200 | import "fmt" 201 | 202 | func main() { 203 | s := []int{1, 2, 3, 4} 204 | 205 | change(s) 206 | 207 | fmt.Println(s) 208 | } 209 | 210 | func change(s []int) { 211 | t := make([]int, len(s)) 212 | 213 | copy(t, s) 214 | 215 | for i := range t { 216 | t[i]++ 217 | } 218 | 219 | s = t 220 | } 221 | ``` 222 | 223 | - Is there any difference between `array` and `slice` in Golang? 224 | 225 | ### Context 226 | 227 | - What is the context? How we can use it to cancel the long-run processing? 228 | 229 | ### Goroutine 230 | 231 | - How does Goroutine differ from a regular thread? 232 | 233 | ### Channels and Synchronization 234 | 235 | - Did you use channels? Where did you use them? 236 | - Buffered/Un-buffered Channels 237 | - `select` 238 | - Sync Package (Mutex and Semaphore, WaitGroup) 239 | - Solve Reader-Writer problem with channels 240 | - Explain mutex implementation with channels 241 | 242 | ### Embedding 243 | 244 | ```go 245 | type Student struct { 246 | Person 247 | } 248 | 249 | type Person struct { 250 | Name string 251 | Age int 252 | } 253 | ``` 254 | 255 | ### Interfaces 256 | 257 | - How they are different from Java interfaces? 258 | 259 | ### Testing 260 | 261 | - Have you ever written tests for you Go projects? 262 | - Have you ever used _mock_ in your projects? 263 | 264 | ### Empty Structure and Why? 265 | 266 | ```go 267 | type Empty struct {} 268 | ``` 269 | 270 | ### Errors 271 | 272 | - Describe the error handling procedure in Go and error wrapping. 273 | - Explain `panic` in Golang. Can you mention some of these cases? 274 | - Out of Bounds Panics 275 | - Nil Receivers 276 | 277 | ## Database 278 | 279 | - Foreign Key 280 | - Primary Key 281 | - NoSQL vs SQL 282 | 283 | ## Kubernetes 284 | 285 | - You have incidents in which your pod crashes randomly some minutes after its startup. What do you do about it? How you find out the problem? 286 | - Did you write a Kubernetes manifest? 287 | - Why we need _service_ for accessing to Kubernetes pods? 288 | - Can we use pod's IP address for getting access to it? 289 | - What are the differences between readiness and liveness probes? 290 | - Do you know `helm`, `kustomize`, etc.? 291 | - Can you explain the distinctions between statefulset and deployment? 292 | 293 | ## Docker 294 | 295 | - Container vs Virtual Machine 296 | - How we can improve the following Dockerfile? 297 | 298 | ```dockerfile 299 | # by adding the following file, you can use docker cache better 300 | # COPY Pipfile Pipfile.lock ./ 301 | 302 | RUN pipenv install --dev --system --deploy 303 | 304 | COPY . . 305 | ``` 306 | 307 | ## SOLID 308 | 309 | - **S**: Single Responsibility Principle (known as SRP) 310 | - **O**: Open/Closed Principle 311 | - **L**: Liskov's Substitution Principle 312 | - **I**: Interface Segregation Principle 313 | - **D**: Dependency Inversion Principle 314 | 315 | ## Cloud Native Design 316 | 317 | - How do you handle a crashed loop application on Kubernetes? 318 | - How do you monitor an application? 319 | - Metrics (Telemetry) 320 | - Logs 321 | - Tracing 322 | 323 | ## System Design 324 | 325 | - What do you know about deployment? 326 | - Let's discuss one of these scenarios in detail 327 | - Event Delivery based on `MQTT`, `HTTP`, etc. 328 | - URL Shortener which contains 329 | - _Redis_ 330 | - _Database Replication/Sharding_ 331 | - _HAProxy_ 332 | - ... 333 | - Voting System that introduces the **CAP** theorem 334 | - What is Dependency Injection? 335 | 336 | ### Deployment Strategy 337 | 338 | - What is Blue Green Deployment? 339 | - What is A/B testing? 340 | - How is A/B testing any different from Blue Green Deployment? 341 | 1. Chat Service 342 | 2. Routing Engine 343 | - Have you used A/B testing before? What did you do? 344 | 1. White List 345 | 2. ID 346 | 3. Rule Engine 347 | 348 | ## CI/CD 349 | 350 | If he/she used CI/CD: 351 | 352 | - What are the benefits of CI/CD to deploy your code? 353 | - Which one of tools (GitLab/Jenkins/Bitbucket) did you use? 354 | 355 | If he/she did not use CI/CD: 356 | 357 | - How did you deploy if? (Using Ansible or Puppet don't have negative point) 358 | - Way did not use CI/CD? 359 | 360 | ## ML 361 | 362 | Our GPU doesn't have sufficient memory to load our model into it, what is your solution? 363 | 364 | - Reduce Model Size or Use a Different Model Architecture: 365 | - Can you use a smaller pre-trained model? 366 | - Can you choose a more lightweight model architecture that is specifically designed for your task? For example, if you are working with 367 | deep learning, can you use MobileNet or SqueezeNet, which are designed to be more memory-efficient for tasks like image classification? 368 | - Quantization: It can significantly reduce the memory footprint of a model by converting model weights to lower precision (e.g., from 32-bit floating point to 16-bit fixed point). Tools like TensorFlow's "tf.lite" or PyTorch's quantization modules can help with this. 369 | - Use Mixed Precision Training 370 | - Distributed Training and Model Parallelism 371 | - Gradient Accumulation: This can allow you to use a larger batch size without increasing memory requirements. 372 | - Prune or Sparsify the Model 373 | - Optimize Your Code (Works for training): Free up GPU memory as soon as it's no longer needed. 374 | 375 | - [Find S Algorithm](https://www.geeksforgeeks.org/ml-find-s-algorithm/) 376 | - Dimensionality reduction reduces collinearity 377 | - [Probably approximately correct (PAC) learning](https://www.baeldung.com/cs/probably-aproximately-correct) 378 | 379 | Approximate Nearest Neighbor 380 | 381 | There are so many ANN approaches, one of them is ANNOY 382 | 383 | - ANNOY (Approximate Nearest Neighbor Oh Yeah): 384 | ![ANN](https://github.com/1995parham-teaching/interviews/assets/36500888/ac2a334d-5769-4fc0-a7a2-8fa87c2875d3) 385 | 386 | ## Soft skills, Teamwork and Managerial 387 | 388 | How do you prevent unwanted deployment of a new joiner? 389 | 390 | 1. I restrict production access for new joiners. 391 | 2. I disable all forms of automatic deployments for production, such as automatic synchronization in Argo CD. 392 | 3. I verify the image tag on GitLab to enable easy reversion if necessary. 393 | 4. I'll make main branch protected, so it will need approval to merge other branches with it. 394 | 5. I ensure monitoring alerts are set up to receive notifications in case of any code malfunctions. 395 | 6. I will implement a system integrated across all projects to send notifications to a deployment group whenever a 396 | project is deployed. 397 | 398 | How do you make sure the on-calls can handle the incidents of your project? 399 | 400 | 1. Maintain an Incident Response Handbook. 401 | 2. Post-Incident Reviews 402 | 3. Mentorship and Shadowing 403 | 4. Simulation and Drills 404 | 5. All projects should implement effective monitoring systems. 405 | 6. Automation: for example having back up for the services we can like EMQ or having circuit breaker in projects. 406 | 7. Increase bus factor of projects. 407 | -------------------------------------------------------------------------------- /questions/array-vs-slice/go.mod: -------------------------------------------------------------------------------- 1 | module array-vs-slice 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /questions/array-vs-slice/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | report() 7 | } 8 | 9 | func report() { 10 | var arr [5]int 11 | 12 | arr[1] = 1378 13 | fmt.Printf("arr[1]: %d\n", arr[1]) 14 | 15 | slice := arr[1:3] 16 | slice[0] = 1373 17 | 18 | fmt.Printf("arr[1]: %d\n", arr[1]) 19 | 20 | // arr[5] = 3 21 | // slice[2] = 3 22 | 23 | fmt.Printf("len: %d\n", len(slice)) 24 | fmt.Printf("cap: %d\n", cap(slice)) 25 | slice = append(slice, 3) 26 | fmt.Printf("len: %d\n", len(slice)) 27 | fmt.Printf("cap: %d\n", cap(slice)) 28 | 29 | slice = arr[:] // Works fine 30 | // arr = slice[0 : 5] Compile time error 31 | 32 | fmt.Printf("slice[0]: %d\n", slice[0]) 33 | } 34 | -------------------------------------------------------------------------------- /questions/mutex/go.mod: -------------------------------------------------------------------------------- 1 | module mutex 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /questions/mutex/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | const N = 10000 6 | 7 | func main() { 8 | sum := 0 9 | 10 | m := New() 11 | d := make(chan string) 12 | 13 | for i := 0; i < N; i++ { 14 | go func(mutex Mutex, done chan string) { 15 | mutex.Lock() 16 | defer mutex.Unlock() 17 | 18 | sum++ 19 | if sum == N { 20 | done <- "done" 21 | } 22 | }(m, d) 23 | } 24 | 25 | <-d 26 | 27 | fmt.Println(sum) 28 | } 29 | 30 | type Mutex struct { 31 | l chan string 32 | } 33 | 34 | func New() Mutex { 35 | return Mutex{l: make(chan string, 1)} 36 | } 37 | 38 | func (m Mutex) Lock() { 39 | m.l <- "lock" 40 | } 41 | 42 | func (m Mutex) Unlock() { 43 | <-m.l 44 | } 45 | -------------------------------------------------------------------------------- /questions/reader-writer/go.mod: -------------------------------------------------------------------------------- 1 | module reader-writer 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /questions/reader-writer/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | const waitDuration = 2 * time.Second 9 | 10 | func main() { 11 | sharedMemory := newShared() 12 | 13 | for i := 0; i < 100; i++ { 14 | for j := 0; j < 10; j++ { 15 | go sharedMemory.write() 16 | } 17 | 18 | go sharedMemory.read() 19 | } 20 | 21 | time.Sleep(waitDuration) 22 | fmt.Println(sharedMemory.SharedMemory) 23 | } 24 | 25 | type shared struct { 26 | SharedMemory int 27 | 28 | readLock chan int 29 | writeLock chan int 30 | readerNumber int 31 | } 32 | 33 | func newShared() shared { 34 | return shared{ 35 | SharedMemory: 0, 36 | readLock: make(chan int, 1), 37 | writeLock: make(chan int, 1), 38 | readerNumber: 0, 39 | } 40 | } 41 | 42 | func (s *shared) write() { 43 | s.writeLock <- 0 44 | s.SharedMemory++ 45 | <-s.writeLock 46 | } 47 | 48 | func (s *shared) read() { 49 | s.readLock <- 0 50 | s.readerNumber++ 51 | 52 | if s.readerNumber == 1 { 53 | s.writeLock <- 0 54 | } 55 | 56 | <-s.readLock 57 | 58 | fmt.Println(s.SharedMemory) 59 | 60 | s.readLock <- 0 61 | s.readerNumber-- 62 | 63 | if s.readerNumber == 0 { 64 | <-s.writeLock 65 | } 66 | 67 | <-s.readLock 68 | } 69 | -------------------------------------------------------------------------------- /system-design/README.md: -------------------------------------------------------------------------------- 1 | # System Design 2 | 3 | ## Beshooest Person Ever (A Distributed Voting System) 4 | 5 | You are the CTO of a Fashion Startup. 6 | This fashion startup has the voting system to select the `Beshooest Person Ever`. This voting system has the following structure: 7 | 8 | ``` 9 | 10 | +--------+ 11 | | HQ | 12 | +--------+ 13 | 14 | 15 | +----+ +----+ +----+ +----+ 16 | | C1 | | C2 | | C3 | | C4 | .... 17 | +----+ +----+ +----+ +----+ 18 | 19 | ``` 20 | 21 | As a CTO can you propose a high-level design for this voting system? 22 | If only we want the results at the end of the voting period? 23 | What happens if we want the real-time result? 24 | 25 | 1. There is no issue in the network 26 | 2. There are issues in the network that happens randomly and may disturb your system. 27 | 3. People may use fraud in election results by voting many times. 28 | 29 | The objective is talking about CAP theorem and make sure he/she understands it correctly. 30 | 31 | ## Number Masking 32 | 33 | Snapp! wants to have a service for hiding the driver and passenger numbers to each other. How do you implement it? 34 | 35 | The objective is talking about how do you handle the masking process life cycle, how do you store the user preferences, etc. 36 | 37 | ## Event Engine 38 | 39 | Snapp! wants to deliver events into drivers and passengers. 40 | Which network protocol(s) suites for this problem? 41 | Event Delivery based on MQTT, HTTP, etc. 42 | 43 | ## URL Shortener 44 | 45 | We want to design a system that reads a URL and returns a short version of it (this version should be more memorable than the original one). 46 | It is better to use following technologies: 47 | 48 | - Redis 49 | - Database Replication/Sharding 50 | - HAProxy 51 | 52 | ## How do you react about an incident? 53 | 54 | How do you find the malfunctioning service in case that you have so many microservices, 55 | and your response time is going up? 56 | 57 | The objective is talking about Prometheus, Grafana and Jeager. 58 | --------------------------------------------------------------------------------