├── .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 |
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 | 
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 |
--------------------------------------------------------------------------------